
الهندسة العكسية بمساعدة الذكاء الاصطناعي مع Ghidra
ريف·ديك هي محطة عمل تحليل ثابت محلية لمستخدم واحد. تجمع بين واجهة مستخدم على الويب تعتمد على الأدلة أولاً ومساعد LLM على ثنائي يتم تحليله بواسطة خدمة Ghidra بدون واجهة رسومية: تصفح الأدلة الحتمية (الدوال، السلاسل النصية، الواردات، المراجع المتقاطعة، رسم بياني محدود للاستدعاءات) مباشرة، أو اطرح أسئلة محدودة على المساعد يجب أن تستند ادعاءاتها الواقعية إلى أدلة يمكن فحصها.
لا يتم تنفيذ الثنائيات المحللة أبدًا. يتواصل المتصفح فقط مع تطبيق Flask هذا؛ يقوم التطبيق بتوكيل الطلبات المُتحقق منها والمكتوبة إلى خدمة Ghidra.
https://github.com/user-attachments/assets/fba14dc5-7ad5-4137-9349-ed824da64fbe
cp .env.example .env # ضبط API_BASE و MODEL_NAME؛ اضبط API_KEY إذا لزم الأمر
docker compose up --build
يقرأ Docker Compose ملف .env تلقائيًا للاستيفاء. يفشل قبل البدء إذا كان API_BASE أو MODEL_NAME مفقودًا؛ يظل API_KEY=not-used صالحًا للمزودين المحليين/بدون مفتاح. يبدأ الـ stack كلتا الخدمتين. افتح http://127.0.0.1:5000.
لتشغيل خدمة Ghidra فقط:
docker pull biniamfd/ghidra-headless-rest:latest # تأكد من أحدث صورة
docker run --rm \
-p 127.0.0.1:9090:9090 \
-v "$(pwd)/data:/data/ghidra_projects" \
--security-opt no-new-privileges:true \
biniamfd/ghidra-headless-rest:latest
للحصول على pin قابل للتكرار، استخدم digest الإصدار المختبر بدلاً من latest:
docker run --rm \
-p 127.0.0.1:9090:9090 \
-v "$(pwd)/data:/data/ghidra_projects" \
--security-opt no-new-privileges:true \
biniamfd/ghidra-headless-rest:1.2.1@sha256:971591a3a8448d8ed969079b452306e806f36079c3ddd298f4a618d6e2f1442d
biniamfd/ghidra-headless-rest:latest.انسخ .env.example إلى .env واملأ هذه المتغيرات؛ راجع ذلك الملف للحصول على القائمة الكاملة والافتراضيات.
| المتغير | الافتراضي | المعنى |
|---|---|---|
API_BASE | مطلوب | عنوان URL الأساسي المتوافق مع OpenAI (http/https). يتعطل Compose مبكرًا عند غيابه. |
API_KEY | not-used | مفتاح المزود. لا يتم تسجيله أو إرساله إلى المتصفح أبدًا؛ not-used صالح للمزودين المحليين بدون مفتاح. |
MODEL_NAME | مطلوب | معرف النموذج المتوقع بواسطة نقطة النهاية المكونة. يتعطل Compose مبكرًا عند غيابه. |
LLM_STREAM | auto | نقل التدفق: auto (تدفق، الرجوع إلى الاستدعاء المحظور مرة واحدة عند حدوث خطأ توافق قبل الإخراج)، true (تدفق دائمًا)، false (محظور دائمًا). |
GHIDRA_API_BASE | http://127.0.0.1:9090 | عنوان URL الأساسي لخدمة Ghidra. |
GHIDRA_IMAGE | biniamfd/ghidra-headless-rest:1.2.1@sha256:971591a3... | إصدار مُختبر مثبت بواسطة digest ثابت. :latest يحل أيضًا إلى هذا digest؛ تجاوز لتثبيت إصدار مختلف. |
HOST / PORT | 127.0.0.1 / 5000 | ربط خادم التطوير. |
MAX_UPLOAD_BYTES | 104857600 | حد حجم الرفع. |
CHATS_DIR | webui/chats | دليل سجل المحادثات. |
يتحدث ريف·ديك مع أي نقطة نهاية Chat Completions متوافقة مع OpenAI عبر OpenAI SDK، ويتم تكوينه بالكامل بواسطة API_BASE / API_KEY / MODEL_NAME. لا يوجد رأس أو معلمة أو منطق نموذج خاص بمزود معين: خادم Ollama محلي (API_BASE=http://127.0.0.1:11434/v1)، أو نقطة نهاية vLLM/llama.cpp/LM Studio مستضافة ذاتيًا، أو OpenAI نفسها، أو بوابة مثل OpenRouter تعمل جميعها بنفس الطريقة.
مثال إعدادات .env للمزود (استخدم العناصر النائبة، لا تلتزم بالمفاتيح الحقيقية أبدًا):
# Ollama
API_BASE=http://127.0.0.1:11434/v1
API_KEY=not-used
MODEL_NAME=qwen3:8b
# OpenRouter
API_BASE=https://openrouter.ai/api/v1
API_KEY=replace-with-your-key
MODEL_NAME=anthropic/claude-opus-4.8
# OpenAI
API_BASE=https://api.openai.com/v1
API_KEY=replace-with-your-key
MODEL_NAME=replace-with-a-supported-model-id
# LM Studio أو vLLM أو llama.cpp (اضبط المنفذ/النموذج حسب الخادم)
API_BASE=http://127.0.0.1:1234/v1
API_KEY=not-used
MODEL_NAME=replace-with-the-served-model-id
بشكل افتراضي (LLM_STREAM=auto)، يطلب المساعد استجابة متدفقة ويقوم بنقل الرموز إلى المتصفح فور وصولها. يمنح التدفق أيضًا ضمانًا أقوى للإلغاء: عندما توقف استجابة (أو تغلق التبويب)، يغلق ريف·ديك بسرعة دفق المزود الأساسي ولا يقوم بجولات أدوات أو نموذج إضافية، لذلك يتم إنهاء التوليد المنبع بدلاً من تركه يعمل حتى الاكتمال في الخلفية.
ملاحظات:
auto، إذا رفض المزود الطلب المتدفق بسبب خطأ توافق (HTTP 400/404/405/422) قبل أي محتوى أو إخراج استدعاء أداة، يتراجع ريف·ديك إلى استدعاء محظور واحد ويتذكر ذلك لبقية العملية. لا يتم التعامل مع أخطاء المصادقة (401/403)، أو تحديد المعدل (429)، أو الخادم (5xx) كمشكلات توافق ويتم عرضها كأخطاء بدلاً من إعادة المحاولة بصمت. اضبط LLM_STREAM=false لتخطي التدفق تمامًا، أو LLM_STREAM=true لفرضه (بدون تراجع).افتح التطبيق وقم برفع ثنائي لبدء مهمة تحليل. يطلب المحتوى النصي الواضح التأكيد قبل إرساله إلى Ghidra؛ استخدم تجاوز الثنائي الخام الصريح فقط عندما يكون المحتوى عمدًا برنامجًا ثابتًا/بيانات بدلاً من تنسيق قابل للتنفيذ. بمجرد اكتمال التحليل، قم بالتبديل بين علامتي تبويب مساحة العمل:
يأخذ كلا الوضعين ميزانية خطوة لكل مهمة، وخيار بدون حد للخطوات يعمل حتى تنتهي المهمة (لا يزال مقيدًا بـ MAX_STEP_BUDGET حتى لا يمكن لنموذج متكرر الهروب). إذا وصلت عملية إلى ميزانيتها، فإنها تبلغ عن نتائج جزئية وتقدم متابعة — والتي تستأنف نفس المحادثة باستخدام الأدلة المسترجعة بالفعل، دون إعادة استدعاءات الأدوات المكتملة. تنمو التكلفة مع عدد استدعاءات الأدوات/النموذج، لذا فإن الميزانيات الأعلى تكلف أكثر.
سير العمل المتاحة:
| سير العمل | الغرض | يتطلب عنوان دالة هدف |
|---|---|---|
program_triage | تلخيص الغرض المحتمل للبرنامج من البيانات الوصفية والواردات والسلاسل النصية والدوال. | لا |
suspicious_behavior | عرض المؤشرات الحتمية أولاً، ثم فرضيات محدودة ومُصنفة بوضوح. | لا |
selected_function | فك ترجمة دالة وشرحها مع المتصلين/المستدعين بها. | نعم |
call_chain | استكشاف حي واحد محدود من الرسم البياني للاستدعاءات الأصلي/المركب من دالة بداية. | نعم |
attack_surface_triage | قراءة تغطية/أفضل-K للنقاط الحتمية، ثم فحص ثلاثة مرشحين على الأكثر بعمق؛ النقاط هي أولويات وليست أحكامًا. | لا |
vulnerability_hypothesis | اختيار مرشح واحد محدود وعرض الأدلة والأدلة المضادة والأسئلة المفتوحة؛ لا يقوم بالتأكيد التلقائي أبدًا. | لا |
لكل مهمة تحليل محادثة رئيسية بالإضافة إلى سلاسل فرعية مركزة اختيارية. اختر تحقيق فرعي جديد، أدخل ملخصًا من سطر واحد، واعمل بسياق محادثة جديد على نفس الثنائي ونفس الأدوات للقراءة فقط. تظل تواريخ السلاسل معزولة، ويتم دفق سلسلة واحدة فقط في كل مرة.