
استخراج وتصنيف حتمي عبر PyGhidra، وخط أنابيب خلفية مترجم بنموذج لغوي محلي لإعادة التنفيذ بلغة C.
شكرًا لتنزيلك خط أنابيب Ghidra + LLM الخاص بي.
هذا أول README أكتبه. لغة الإشارة الأمريكية (ASL) هي لغتي الأولى، لذا فإن إنجليزيتي ليست مثالية. بذلت قصارى جهدي.
أحب محاكاة قديمة للحاسوب ألعبها منذ طفولتي، وأريد تحسينها من الداخل.
النظر إلى الألعاب مفتوحة المصدر مثل OpenRA وOpenTTD علّمني هذا: إعادة التنفيذ من قِبل أحد الهواة لا تتعلق بالحصول على الشيفرة المصدرية الأصلية. بل تتعلق ببناء نسخة مفتوحة المصدر جديدة من اللعبة يمكنها تحميل أصول اللعبة الأصلية. عندها يمكن لأي شخص توسيعها أو المساهمة فيها.
للقيام بالعمل أستخدم نوعين من الذكاء الاصطناعي معًا:
تحصل كل دالة على تسمية واحدة. هذا يوفر الكثير من الوقت، لأنني لا أُهدر الجهد على الكم الكبير من نفايات نظام التشغيل وبيئة التشغيل.
|-----------|------------------------------------------------------------------------------------------------------------------
| التسمية | المعنى |
|---|---|
| KEEP | منطق اللعبة الخاص (مثل نموذج الطيران، ونموذج الضرر، وTrackIR) |
| WRAP | طبقة لاصقة موجهة لـ Java تستدعي واجهات برمجة نظام التشغيل أو الإدخال: احتفظ بالتوقيع، واكتب جسمًا جديدًا. |
| (IL-2 1946 محرك مثير للاهتمام: C++ وJava معًا.) | |
| REPLACE | بيئة تشغيل C القديمة، والموزّع (allocator)، وthunks: يوفرها المترجم أو نظام التشغيل، لذا لا تحتاجها نسخة 64-بت جديدة |
| UNKNOWN | غير واضح: انظر إليه يدويًا |
| ----------- | ------------------------------------------------------------------------------------------------------------------ |
في برنامج الاختبار الخاص بي، كان حوالي 44% من الدوال من نوع REPLACE، لذا لم تكن بحاجة إلى التحويل أبدًا.
في البداية وثقت بأن شيفرة C الزائفة تملك كل الإجابات. كان ذلك ساذجًا. فهي تفسير Ghidra للتجميع، وهي تخمّن (أنواع المتغيرات، والوسائط المفقودة).
التجميع هو الحقيقة الخام. لا يحتوي على أنواع متغيرات، لكنه يحمل السلوك الدقيق لكل دالة. لذا تقرأ السكربتات التجميع، وتحوّله إلى مخطط (blueprint) بصيغة شبيهة بـ C. ويُحتفظ بشيفرة C الخاصة بـ Ghidra كتلميح فقط.
استخدمت اختباراتي المبكرة نماذج LLM المحلية (Qwen 2.5 Coder، وDeepSeek Coder V2 Lite، وMellum 2) لقراءة التجميع مباشرة. لم ينجح ذلك بشكل موثوق أبدًا. فقد هلوسوا، لأنهم مصممون لكتابة الشيفرة، لا لقراءة شيفرة الآلة الخام.
بعد العديد من التجارب الفاشلة قسّمت العمل:
ملاحظة: كيف تتحقق Python من الإجابة
الفحوصات النصية: اسم الدالة، وكل استدعاء، ومتغير عام ونص من المخطط، والحلقات، وأحجام الخطوات، والثوابت المقارَنة، وقيمة الإرجاع، وأنه لم تتبقَّ أي أسماء سجلات أو أسماء مبتكرة.
فحص الترجمة بواسطة gcc: يُترجم الكود باستخدام gcc (فحص صياغي فقط، لا يُنفَّذ شيء). ساعد هذا كثيرًا. في تشغيل مبكر، اجتازت الفحوصات النصية إجابات Mellum 2، لكن لم يُترجم أي منها، بسبب تعليق رأسي مكتوب خارج تعليق. يلتقط gcc ما لا تستطيع الفحوصات النصية رؤيته: المتغيرات غير المعلنة أو المعاد إعلانها، والأنواع الخاطئة، والأقواس أو الفواصل المنقوطة المكسورة. تُحتسب الدالة PASS فقط عندما تكون الفحوصات النصية والترجمة سليمتين معًا. لا يثبت gcc صحة المنطق، لذا ما زلت أقرأ الكود مقارنةً بالمخطط.
إذا فشل فحص، يحصل النموذج اللغوي (LLM) على قائمة بما فشل ويحاول مرة أخرى.
يصلح Python الأخطاء الصغيرة بنفسه، دون النموذج اللغوي: يعلن كل متغير مرة واحدة، ويلف الأسطر الرأسية السائبة في تعليق، ويجعل آخر return يُرجع النتيجة الصحيحة، ويضيف التضمينات والتعريفات.
جاءت قائمة التحقق بعد أن رأيت النماذج اللغوية تفشل في الدوال الطويلة جدًا. وهي تعمل مثل قائمة التحقق التي يستخدمها الطيار قبل الإقلاع والهبوط. يكتبها Python من الدالة، ويفحص الإجابة مقابلها. في اختباراتي بدأت الدوال الطويلة تنجح، وأصبحت التشغيلات أسرع.
|-------------------|---------------------------------------|---------------------------------------------
| المجلد | ما الذي يفعله | اقرأ |
|---|---|---|
ghidra_pipeline | التفريغ، التجميع، الفرز، الأدوار | ghidra_pipeline/INSTRUCTION.txt |
llm_pipeline | المخططات ومشغّل النموذج اللغوي (v3) | llm_pipeline/INSTRUCTION_BLUEPRINT_LLM.txt |
| ------------------- | --------------------------------------- | --------------------------------------------- |
ابدأ بـ ghidra_pipeline، ثم انتقل إلى llm_pipeline عندما تكون جاهزًا لاستخدام نماذجك اللغوية المحلية.
أولًا، حلّل برنامجك في PyGhidra وشغّل PyGhidra Scripts/decompile_full_dump.py.
يشرح ملفا INSTRUCTION إعداد المجلدات. ثم:
أولًا، حلّل برنامجك في PyGhidra وشغّل PyGhidra Scripts/decompile_full_dump.py.
يشرح ملفا INSTRUCTION إعداد المجلدات. ثم:
python .\make_full_lite_v2.py --in . --out .\OUT
python .\triage_evidence_v2.py --lite .\OUT\LITE_AC
python .\build_roles_v2.py --triage .\OUT\TRIAGE
python .\blueprint_v3.py --group ".\SOURCE\LITE_AC\<GroupName>" --out ".\G_<GroupName>\BLUEPRINT_v3"
python .\run_blueprint_llm_v3.py --bp ".\G_<GroupName>\BLUEPRINT_v3" --out ".\G_<GroupName>\RUN1_v3_<model>" --model <model name>
تحتاج إلى Ghidra مع PyGhidra، وPython 3، وLM Studio (مع تحميل نموذج واحد)، وgcc (موصى به، يُستخدم كفحص للترجمة).
يحتوي هذا المستودع على سكربتات ووثائق فقط. لا ملفات ألعاب ولا شيفرة ولا بيانات. استخدمه فقط على البرامج التي تملكها، واتبع القواعد التي تنطبق عليها.
جرّبه على لعبة أخرى وأخبرني بما نجح وما لم ينجح. الأفكار والتحسينات مرحّب بها.