Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
أدوات/GitHubGitHub/gmh5225/ghidra_svr_bridge
التحليل الثابتتحليل الكودالهندسة العكسيةالبرمجة النصية والأتمتةالأدوات والمكوناتتحليل الملفات الثنائية
GitHubgmh5225/ghidra_svr_bridge

ghidra_svr_bridge

إضافة Binary Ninja تقوم بمزامنة التحليل ثنائي الاتجاه مع مستودع Ghidra Server، عبر عملية فرعية لجسر Java.

عرض المستودع
2منذ شهر واحدلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

binja-ghidra

إضافة Binary Ninja تتصل بمستودع Ghidra Server وتستورد تحليله — الرموز، وأسماء الدوال، والتعليقات — مباشرةً إلى عرض ثنائي مفتوح في Binary Ninja.

ما الذي تفعله

لكل من Ghidra وBinary Ninja نقاط قوة. تتيح لك هذه الإضافة استخدام كليهما على نفس الملف الثنائي دون نسخ الأسماء أو التعليقات يدويًا بينهما. اتصل بـ Ghidra Server قيد التشغيل، وتصفح مستودعاته، وانقر نقرًا مزدوجًا على أي ملف مشروع لسحب تحليله إلى عرض BN المفتوح حاليًا.

المزامنة تسير في الاتجاهين.

BN ← Ghidra (استيراد)BN → Ghidra (إيداع)
الرموز (التسميات، أسماء الدوال)✓✓
التعليقات (EOL/PRE/POST/PLATE/REP)✓✓
توقيعات الدوال (نوع الإرجاع، اصطلاح الاستدعاء)✓✓
معاملات الدوال (إعادة التسمية، إعادة تحديد النوع، الإضافة)✓✓
أنواع البيانات (struct/union/enum/typedef + pointer/array)✓✓
المعادلات (أسماء الثوابت + المراجع)✓✓
الإشارات المرجعية✓✓
عناصر البيانات المُنمّطة✓✓
أعلام الدوال (thunk، no-return، inline)✓ كوسوم BN—
المتغيرات المحلية (مدركة للتخزين)✓جزئي — تعيين تخزين السجلات غير مُنفَّذ

البنية المعمارية

root@kitploit:~
Binary Ninja (C++ plugin)
    │  TCP / newline-delimited JSON
    ▼
ghidra-bridge-*.jar  (Java, runs as a subprocess)
    │  Java RMI / SSL
    ▼
Ghidra Server  (ghidraSvr, running on the network)

تُشغّل الإضافة عملية Java فرعية (الجسر "bridge") عند التحميل. يحتفظ الجسر باتصال RMI بـ Ghidra Server ويتحدث بروتوكول JSON بسيط مع الإضافة عبر مقبس TCP محلي. يُبقي هذا كل شيفرة Java/RMI خارج عملية C++ ويتيح لـ JVM البدء في الخلفية بينما يُكمل BN التحميل.

كما تهيّئ JVM الخاصة بالجسر إطار عمل Application الخاص بـ Ghidra عند بدء التشغيل حتى يتمكن مسار الكتابة من استخدام واجهات برمجة نموذج البرنامج عالية المستوى في Ghidra (ProgramDB، DataTypeManager، SymbolTable، FunctionManager) بدلًا من كتابات db.Table.putRecord() الخام — انظر مسار كتابة الإيداع أدناه.

المكوّنات

المساراللغةالدور
plugin/C++ / Qt6إضافة الشريط الجانبي في Binary Ninja
bridge/Java 17عميل Ghidra RMI + خادم جسر JSON

الإضافة (C++):

  • plugin.cpp — تسجّل الإعدادات وأداة الشريط الجانبي؛ تبدأ JVM الخاصة بالجسر بحماس عند التحميل
  • GhidraConnection.cpp — singleton؛ تدير دورة حياة الجسر وجميع العمليات المدعومة بـ RMI
  • BridgeProcess.cpp — تُطلق JAR الخاص بالجسر كعملية فرعية مع أنابيب stdout/stderr؛ تقرأ سطر المصافحة READY port=N
  • BridgeClient.cpp — عميل TCP؛ يرسل طلبات JSON، ويستقبل الردود، ويوزّع الأحداث غير المتزامنة
  • SyncEngine.cpp — تطبّق GhidraDbExport على BinaryView (الرموز، التعليقات، الأعلام)
  • ui/ProjectPanel.cpp — أداة الشريط الجانبي: شجرة المستودع، حوار الاتصال، سجل النشاط
  • ui/ConnectDialog.cpp — حوار المضيف/المنفذ/المستخدم/كلمة المرور

الجسر (Java):

  • BridgeMain.java — تحليل الوسائط؛ تهيّئ UniversalIdGenerator وإطار عمل Application الخاص بـ Ghidra؛ تبدأ خادم TCP؛ تطبع READY port=N إلى stdout
  • BridgeServer.java — تقبل اتصال عميل TCP واحد وتُسلّمه BridgeConnection
  • BridgeConnection.java — موزّع طلبات JSON؛ تُسلسل ردود Ghidra API إلى JSON؛ تتعامل مع opCheckin (تنشئ نسخة برنامج جديدة على الخادم)
  • GhidraSession.java — جلسة RMI مُصادَق عليها؛ تغلّف RemoteRepositoryServerHandle
  • EventStreamer.java — خيط خلفي لكل مستودع مفتوح؛ تدفع RepositoryChangeEvents إلى الإضافة كأحداث JSON غير متزامنة
  • DatabaseExporter.java — مسار القراءة: تستخرج جداول الرموز/التعليقات/أعلام الدوال/أنواع البيانات/المعادلات/الإشارات المرجعية من ManagedBufferFileHandle (مخزن قاعدة بيانات Ghidra البعيد) عبر وصول db.jar الخام
  • ProgramApplier.java — مسار الكتابة: تفتح ملف المخزن كـ ProgramDB حقيقي وتطبّق جميع تغييرات جانب BN عبر واجهات Ghidra عالية المستوى (انظر مسار كتابة الإيداع أدناه)
  • DatabaseImporter.java — مساعدات الكتابة الخام القديمة محفوظة فقط كمنفذ اختبار؛ apply(...) الإنتاجي يفوّض إلى ProgramApplier

مسار كتابة الإيداع

يفتح opCheckin ملف المخزن المُدار الخاص بالبرنامج في وضع الكتابة، ويُنشئ ProgramDB فوقه، ويطبّق تغييرات جانب BN عبر واجهات نموذج البرنامج في Ghidra. يُتجنّب الكتابة الخام db.Table.putRecord() — فقد كانت مصدر كل خطأ إفساد في الإيداع واجهناه على الإطلاق:

كتابة على الطبقة الخاطئةنمط الفشل
setIntValue(col, longTypeId) على جدول Function DataIntField.setLongValue يقتطع l2i بصمت → تلف StackPurge عند كل تحديث توقيع
setByteValue(col, isUnion) على V5V6 Composite Data Typesالعمود هو BooleanField في Ghidra 12.x → IllegalFieldAccessException ("Illegal field access")
setIntValue(col, 0) على عمود V2 Typedef Flagsالعمود هو ShortField → نفس الانهيار، مخطط مختلف
كتابة ترويسة مركّبة بدون صفوف إعدادات المكوّناتCompositeEditorModel.cloneAllComponentSettings يرمي ArrayIndexOutOfBoundsException عند فتح البنية في Ghidra
كتابة رمز PARAMETER مع SYM_ADDR_COL = عنوان RAMAddress is not a VariableAddress يرميه FunctionDB.loadSymbolBasedVariables عند أي وصول للدالة
تمرير DBChangeSet بقيمة null إلى DBHandle.save()يكتب الخادم ملف بيانات تغيير بحجم 0 بايت → يفشل الاستخراج التالي بـ EOFException في ProgramContentHandler.loadProgramChangeSet

لا يعاني ProgramApplier من هذه المزالق لأنه يمرّ عبر DataTypeManager.addDataType، SymbolTable.createLabel، Listing.setComment، Function.setReturnType، إلخ — واجهات تحافظ تلقائيًا على ثوابت الجداول المتشابكة في Ghidra. كما يشغّل تمريرة cleanupBadVariableSymbols في بداية كل إيداع لتنقية الإفساد الذي تركته إصدارات الجسر الأقدم في قاعدة البيانات.

server-package/CleanupBadVariableSymbols.java هو GhidraScript مستقل يشغّل نفس التنظيف عبر analyzeHeadless — مفيد عندما يكون الملف مُفسَدًا لدرجة تعذّر فتحه في واجهة Ghidra الرسومية.

الاختبار

root@kitploit:~
./test.sh          # macOS / Linux: tiers 0-3 (C++ unit + BN-headless + Java)
test.bat           # Windows equivalent
test.bat --parity  # cross-DB parity tier only (C++ BN tests + gradlew parityTest)
test.bat --e2e     # live Ghidra-server E2E (starts a local ghidraSvr)

المجموعة منظّمة في خمس طبقات. الطبقات 2–4 موجودة لإثبات خاصية واحدة: نفس البيانات المتوافقة تنتهي مخزّنة في كلٍّ من .bndb وقاعدة بيانات برنامج Ghidra (مصفوفة التوافق في أعلى هذا README).

الطبقةماذاأينالبوابة
0اختبارات وحدة خالصةplugin/test/*.cpp (binja-ghidra-tests)، الجسر *Test.javaدائمًا
1ذهاب وإياب Ghidra-DBالجسر *RoundTripTest.java (ProgramApplier مقابل ProgramDB حقيقي)يحتاج ghidra.home / GHIDRA_HOME
2ذهاب وإياب BN BinaryView/.bndbplugin/test/bn/ (binja-ghidra-bn-tests؛ binaryninjacore بلا واجهة)يتخطّى بنظافة بدون ترخيص BN قادر على العمل بلا واجهة (يُحترم متغير البيئة BN_LICENSE)
3تكافؤ عبر قواعد البياناتCanonicalParityTest (C++ و Java) مقابل القيم الذهبية المشتركة في testdata/parity/fixtures/مع الطبقتين 1+2
4E2E على خادم حيالجسر LiveServerE2ETest — يُقلع ghidraSvr حقيقيًا في مجلد مؤقت، ويزرع عبر analyzeHeadless، ويقود checkout → export → checkin → re-export عبر RMItest.bat --e2e (يضبط GHIDRA_E2E=1)

مرجع التكافؤ (الطبقة 3). يتحقق الجانبان بشكل مستقل مقابل نفس JSON القانوني المُودَع (شكل DatabaseExporter في الجسر). اتجاه الاستيراد: تُحمَّل القيمة الذهبية في ProgramDB (Java) وفي BinaryView عبر SyncEngine (C++)، ويجب أن يساوي كل إعادة تصدير القيمة الذهبية. اتجاه الإيداع: يجب أن تُنتج تعديلات BN النصية بالضبط fixtures/checkin/*/expected-preview.json (C++)، ويجب أن يُعيد تطبيق تلك المعاينة عبر ProgramApplier التصدير كـ expected-after.json (Java). إذا طابق الجانبان القيم الذهبية المشتركة، فإن قاعدتي البيانات تتفقان بالتعدّي. توجد أوضاع مقارنة الحقول وجدول تطبيع أسماء الأنواع في testdata/parity/RULES.md؛ والملف التنفيذي للاختبار هو testdata/bin/parity_x64.bin (التخطيط في parity_x64.md).

مثبّتات الانحدار طويلة الأمد على جانب Java:

  • DataTypesRoundTripTest.struct_cloneSettings_doesNotThrow — يجب أن تبقى إعدادات المركّب متسقة مع الترويسة (انهيار cloneAllComponentSettings)
  • FunctionSignaturesRoundTripTest.returnType_doesNotCorruptStackPurge — اقتطاع IntField
  • ParametersRoundTripTest.noParameterSymbol_endsUpAtRamAddress — ثابت VariableAddress

تتطلب اختبارات الذهاب والإياب والتكافؤ تثبيت Ghidra (يُستخدم وقت التشغيل لخدمات اللغة). يُقرأ المسار من خاصية نظام Gradle ‏ghidra.home أو متغير البيئة GHIDRA_HOME؛ ويمرّر build.gradle قيمة ghidraHome افتراضيًا. تحتاج اختبارات C++ للطبقتين 2/3 إضافةً إلى ذلك أن يكون binaryninjacore قابلًا للتحميل (تضع السكربتات مجلد تثبيت BN على PATH).

المتطلبات الأساسية

التبعيةملاحظات
Binary Ninja (تجاري)مُختبَر مقابل الإصدار المطابق لـ api_REVISION.txt في تثبيت BN
Ghidra Serverمُختبَر مع Ghidra 12.0.4. يجب أن يكون قيد التشغيل وقابلًا للوصول عبر RMI/SSL
Java 17+ JDKيُوصى بـ Eclipse Adoptium JDK 21
CMake 3.24+
Ninja
مترجم C++MSVC 2022+ على Windows؛ clang على macOS؛ gcc/clang على Linux
Qt 6.7+انظر إعداد Qt أدناه؛ يجب أن يكون qmake على PATH وقت البناء
Gradle (عبر wrapper)يستخدم الجسر Gradle wrapper — لا حاجة لتثبيت منفصل
Poetry (لبناء Qt فقط)مطلوب فقط عند بناء Qt من الوحدة الفرعية qt-build. ثبّته بـ pip install poetry أو pipx install poetry.
libclang 19 (لبناء Qt فقط)مطلوب من نظام بناء Qt. انظر qt-build/README.md لتعليمات التنزيل.

إعداد Qt

ترتبط الإضافة بنفس بناء Qt 6 الذي يستخدمه Binary Ninja. لديك خياران:

الخيار A — استخدام تثبيت Qt موجود (الأسرع إذا كان لديك Qt بالفعل)

مرّر Qt6_DIR مشيرًا إلى دليل CMake الخاص بـ Qt لديك:

root@kitploit:~
Qt6_DIR=/path/to/Qt/6.x.y/clang_64/lib/cmake/Qt6 ./build.sh

على macOS يكتشف سكربت البناء Qt تلقائيًا إذا ثُبّت بواسطة مثبّت Qt عبر الإنترنت تحت /usr/local/Qt*.

الخيار B — بناء Qt من الوحدة الفرعية qt-build (~1-2 ساعة، مرة واحدة لكل جهاز)

الوحدة الفرعية qt-build (سكربتات بناء Qt من Vector35) تُصرّف Qt 6 مع تصحيحات Binary Ninja. تتطلب Poetry وlibclang 19 (انظر المتطلبات الأساسية أعلاه وqt-build/README.md).

يُثبَّت Qt في qt/<version>/<compiler>/ داخل المستودع:

المنصةمسار التثبيت
macOSqt/6.10.1/clang_64/
Linux x86-64qt/6.10.1/gcc_64/
Windowsqt/6.10.1/msvc2022_64/
root@kitploit:~
# First time on a new machine:
./build.sh qt          # compiles Qt — takes 1-2 hours

# All subsequent builds (Qt cached in qt/, reused automatically):
./build.sh

خطوة qt مطلوبة مرة واحدة فقط. يكتشف CMake وسكربتات البناء Qt المبني في qt/ في كل تشغيل لاحق ويتخطى الوحدة الفرعية بالكامل. دليل qt/ مُتجاهَل في git.

البناء

استنساخ جديد

root@kitploit:~
git clone https://github.com/mutinylaboratories/ghidra_svr_bridge.git
cd ghidra_svr_bridge
git submodule update --init   # populates binaryninja-api and qt-build (~seconds)

ثم اتبع إعداد Qt أعلاه (الخيار A أو B)، وشغّل:

root@kitploit:~
./build.sh install

macOS / Linux

root@kitploit:~
# Incremental build of both components
./build.sh

# Full clean rebuild + install into BN plugins folder
./build.sh clean install

# Build only the C++ plugin
./build.sh plugin

# Build only the Java bridge
./build.sh bridge

# Build Qt once on a machine without Qt installed
./build.sh qt

متغيرات البيئة (كلها اختيارية — يضبط السكربت قيمًا افتراضية معقولة):

root@kitploit:~
BN_INSTALL=/Applications/Binary\ Ninja.app/Contents/MacOS
Qt6_DIR=/usr/local/Qt-6.7.2/lib/cmake/Qt6

Windows

حرّر المسارات في أعلى build.bat لتطابق بيئتك قبل الاستخدام الأول:

root@kitploit:~
set "JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-21.0.11.10-hotspot"
set "VSDEVCMD=C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\Tools\VsDevCmd.bat"
set "Qt6_DIR=C:\qt\v6.7.2\lib\cmake\Qt6"
set "BN_INSTALL=C:\Program Files\Vector35\BinaryNinja"
root@kitploit:~
rem Incremental build of both components
build.bat

rem Full clean rebuild + install into BN plugins folder
build.bat clean install

rem Build only the C++ plugin
build.bat plugin

rem Build only the Java bridge
build.bat bridge

rem Build Qt once on a machine without Qt installed
build.bat qt

يستخدم بناء C++ خاصية CMake FetchContent لاستنساخ binaryninja-api عند الالتزام الدقيق المسجّل في api_REVISION.txt، بحيث تتطابق ABI الإضافة دائمًا مع إصدار BN المثبّت. يُنزَّل Ghidra تلقائيًا بواسطة CMake عند أول تهيئة إذا لم يُضبط GHIDRA_HOME.

الإعداد

بعد التثبيت، اضبط ما يلي في إعدادات Binary Ninja (Edit → Preferences → Settings، ابحث عن "Ghidra"):

الإعدادالوصف
ghidra.javaExeالمسار الكامل إلى java.exe
ghidra.ghidraHomeجذر تثبيت Ghidra لديك (يحتوي على Ghidra/Framework/…)
ghidra.trustAllCertsاضبطه على true إذا كان Ghidra Server لديك يستخدم شهادة موقّعة ذاتيًا
ghidra.defaultHostيملأ حوار الاتصال مسبقًا
ghidra.defaultPortالافتراضي: 13100
ghidra.defaultUserيملأ حوار الاتصال مسبقًا

الاستخدام

  1. افتح ملفًا ثنائيًا في Binary Ninja.
  2. افتح الشريط الجانبي Ghidra (أيقونة "G" الحمراء).
  3. انقر Connect… وأدخل بيانات اعتماد الخادم.
  4. تُملأ شجرة المستودع. انقر سهم التوسيع (▶) على مستودع لكشف مجلداته وملفات مشروعه.
  5. تظهر ملفات المشروع بالخط العريض والأزرق. انقر نقرًا مزدوجًا على أحدها لاستيراد تحليله إلى عرض الملف الثنائي المفتوح حاليًا.
  6. يُظهر سجل النشاط تقدّم الاستيراد ونطاق العناوين للرموز المطبّقة.

شرط مسبق للخطوة 5: يجب أن يكون ملف البرنامج مُودَعًا في مستودع Ghidra Server (وليس مجرد مفتوح محليًا في Ghidra). في Ghidra: انقر بزر الفأرة الأيمن على الملف في نافذة Project → Version Control → Add to Version Control….

بروتوكول الجسر

تتواصل الإضافة والجسر عبر مقبس TCP محلي باستخدام JSON محدّد بأسطر جديدة. يحمل كل طلب عددًا صحيحًا id وسلسلة op؛ وكل رد يعيد صدى id. تحمل الأحداث غير المتزامنة (تغييرات المستودع من جانب الخادم) مفتاح "event" بدلًا من ذلك.

العمليةالاتجاهالغرض
ping, status, connect, disconnectطلب/رددورة حياة الجلسة
list_repos, open_repo, close_repoطلب/ردتعداد المستودعات
list_items, get_subfoldersطلب/ردتصفح المستودع
get_versions, get_checkoutsطلب/ردحالة التحكم بالإصدارات
checkout, terminate_checkoutطلب/ردقفل كتابة حصري
open_dbطلب/ردقراءة قاعدة بيانات Ghidra كاملة → JSON (ثقيل)
checkinطلب/ردتطبيق تغييرات جانب BN → نسخة مستودع جديدة (ثقيل، عبر ProgramApplier)
download_binary, upload_binaryطلب/ردنقل الملف الثنائي الأصلي للداخل/للخارج
delete_itemطلب/ردإزالة ملف من المستودع
repo_changedحدث (غير متزامن)دفع RepositoryChangeEvent من جانب الخادم

المتابعة على جهاز آخر

يحتوي المستودع على كل ما يلزم لإعادة البناء من الصفر. إعداد كل مطوّر غير الموجود في git:

  1. الاستنساخ + الوحدات الفرعية:
    root@kitploit:~
    git clone https://github.com/mutinylaboratories/ghidra_svr_bridge.git
    cd ghidra_svr_bridge
    git submodule update --init --recursive
    
  2. مسار Ghidra المحلي: أنشئ bridge/gradle.properties:
    root@kitploit:~
    ghidraHome=C:/Users/<you>/ghidra/ghidra_12.0.4_PUBLIC
    
    (الشرطات المائلة الأمامية تعمل على Windows أيضًا — يفضّلها Gradle.)
  3. تثبيتا Ghidra وBinary Ninja: نفس الإعداد كما في أجهزتك الأخرى.
  4. Qt: إما وجّه Qt6_DIR إلى تثبيت موجود أو شغّل ./build.sh qt (Windows: build.bat qt) مرة واحدة.
  5. قناة إصدار Binary Ninja: يجب أن تطابق ABI الإضافة إصدار BN الذي تشغّله. اختر القناة عند البناء؛ يجلب السكربت التزام binaryninja-api المطابق من GitHub:
    root@kitploit:~
    ./build.sh --channel stable    # default — latest stable release (from GitHub)
    ./build.sh --channel dev        # latest dev (dev branch head, from GitHub)
    ./build.sh --bn-api <commit>   # explicit commit, no GitHub lookup (escape hatch)
    
    --channel و--bn-api متعارضان؛ وبدونهما تُستخدم قناة stable. يستعلم --channel من GitHub الخاص بـ Vector35/binaryninja-api (أحدث إصدار stable/*، أو رأس فرع dev) لذا يحتاج إلى وصول للشبكة. إذا كان BN المثبّت لديك متأخرًا عن أحدث إصدار، مرّر --bn-api مع SHA الدقيق من api_REVISION.txt لذلك التثبيت.

عند فتح جلسة Claude Code جديدة، أفضل مؤشرات التأهيل هي هذا README بالإضافة إلى الحالة الحالية على dev:

  • البنية المعمارية وثوابت مسار الكتابة: هذا الملف
  • مسار الكتابة الإنتاجي: bridge/src/main/java/com/ghidra_svr/bridge/ProgramApplier.java
  • منصة الاختبار: bridge/src/test/java/com/ghidra_svr/bridge/ProgramTestBase.java
  • مجموعات الذهاب والإياب: bridge/src/test/java/com/ghidra_svr/bridge/*RoundTripTest.java
  • الالتزامات الأخيرة: git log --oneline — يوضّح كل سطر موضوع ما تغيّر ولماذا

القيود المعروفة / العمل المعلّق

  • تخزين المتغيرات المحلية: يتخطى ProgramApplier مدخلات المعاملات is_local لأن تعيين فهارس سجلات BN إلى تخزين Ghidra يتطلب ترجمة جدول سجلات لكل معمارية. المعاملات تعمل؛ أما المتغيرات المحلية فلا تتزامن بعد.
  • المصادقة: اسم المستخدم + كلمة المرور فقط. لم تُعالَج بعد عمليات استدعاء PKI ومفاتيح SSH.
  • فضاء عناوين واحد: يفترض DatabaseExporter فضاء عناوين RAM واحدًا. قد تنتج فضاءات التراكب أو معماريات هارفارد عناوين غير صحيحة.
  • دمج مجموعة التغييرات: يكتب الجسر DBChangeSet فارغًا لإبقاء عمليات الاستخراج تعمل. لذلك لا تستطيع آليات الدمج عند الاستخراج في Ghidra حل التعديلات المتزامنة تلقائيًا بين مستخدمي BN وGhidra — الكاتب الأخير يفوز.
تنزيل الأداة