
تحليل ثنائي متوازٍ باستخدام IDA Pro مع تسمية وظائف مدعومة بالذكاء الاصطناعي، ورسم بياني معرفي من Neo4j، ومحرك محاكاة/ربط/تشويش phantomrt للهندسة العكسية الآلية عبر صيغ PE وELF وNSO.
شبح عبر الثنائيات.
مساعد محلي لعكس الهندسة يعمل بالذكاء الاصطناعي: تحليل موازٍ باستخدام IDA Pro، تسمية وظائف بالذكاء الاصطناعي، طرفية لا تخذلك، رسم بياني معرفي Neo4j لكل شيء اكتشفه على الإطلاق، وخادم MCP يتيح لـ Claude البحث والتسلسل عبر هذا الرسم البياني مباشرة.
والآن — مع phantomrt — لم يعد يقرأ الجدران فحسب. بل يمشي عبرها: يحاكي، ويعترض، ويُخربش الوظائف التي سمّاها، ويكتب ما يحدث فعليًا مرة أخرى على الرسم البياني.
✓ 00 ✓ 01 ✓ 02 ✓ 03 ▸ 04 · 05 · 06 · 07 ✓ 08 ✓ 09 ✓ 10 ✓ 11 ✓ 12 ✓ 13 ▸ 14 · 15
14/16 shards │ 141,203 functions found ████████████████████████████░░░░ 89% ~4s remaining
---
## ما هو
التحليل التلقائي لـ IDA Pro هو ذو خيط واحد (single-threaded). على ملف il2cpp DLL بحجم 34 ميجابايت، قد يستغرق ذلك *دقائق*. يقوم spectrIDA بتقسيم الملف الثنائي إلى N من الأجزاء (shards)، وتشغيلها بالتوازي عبر idalib، ثم دمجها في ملف `.i64` واحد، ثم يترك نموذجًا مضبوطًا بدقة بحجم 8 مليار معلمة **لتسمية كل دالة** — كل ذلك من واجهة طرفية واحدة (terminal UI) ذات طابع سايبربانك وقدر مناسب من السخرية.
هذا هو الفصل الأول، وهو قائم بذاته: سرعة خالصة، لا حاجة للذكاء الاصطناعي إذا كنت لا تريده.
يحول الفصل الثاني المخرجات إلى شيء يعمر بعد الجلسة — رسم بياني في Neo4j يمكن لعميل MCP (Claude، [pi](https://pi.dev)، أو أي شيء يتحدث بلغة MCP) أن يعيش فيه بالفعل، بدلاً من أن تقوم بنسخ ولصق مخرجات المفكك (decompiler) في نافذة الدردشة دالةً تلو الأخرى:```
Binary ─▶ Parallel IDA Analysis ─▶ Demangle ─▶ AI Naming ─▶ Neo4j Graph ─▶ MCP Server ─▶ Claude
(N idalib shards) (free, real) (stripped (persists, (search/chain/
leftovers forever, rename, live)
only) across sessions)
الفصل الثالث (phantomrt) يضيف النصف الذي لا تمتلكه الأدوات الثابتة أبدًا: فهو يشغِّل الكود. يحاكي دالة بدون نظام تشغيل (يعمل على ملفات ثنائية لا يمكنك حتى تشغيلها، مثل .nso للسويتش)، أو يربط العملية الحية، أو يختبرها عشوائيًا — ويطبع الحكم (تعطل / يحتاج حالة حية / نظيف) على نفس عقدة الرسم البياني مع الاسم.
الملخص الكامل، بما في ذلك ما لا يزال في قائمة المهام، موجود بالأسفل في الفصل الثاني و الفصل الثالث.
إنها ليست Ghidra. تقوم بشيء واحد مزعج (تحليل بطيء + تسمية) بسرعة، ومن الممتع حقًا استخدامها. 199 تنزيلًا يتحدث عن نفسه.
لا سحابة. لا تتبع. يعمل بالكامل على جهازك.
| المهمة | الوقت |
|---|---|
| DLL لعبة Among Us — IDA أحادي الخيط | ~4 ساعات |
| DLL لعبة Among Us — spectrIDA (16 عاملاً) | 67 ثانية |
| ملف ثنائي بـ153,649 دالة — شاملة لتسمية كاملة | ليلة كاملة |
| نظرة عامة على الملف الثنائي (ماذا يفعل هذا الشيء؟) | ~30 ثانية |
العتاد الذي قيست عليه هذه الأرقام: AMD Ryzen 7 5800X3D (8C/16T)، 32 جيجابايت RAM، RTX 4070 12 جيجابايت.
العتاد المختلف يغير أرقام التحليل المتوازي (أنوية أكثر، شرائح أكثر، أسرع)؛
أرقام التسمية مرتبطة في الغالب بوحدة معالجة الرسوميات. أرقام 4 ساعات/67 ثانية للعبة Among Us سبقت الفصل الثاني
ولم يتم إعادة التحقق منها بشكل مستقل في كل إصدار — أعد تشغيل spectrida analyze بنفسك إذا
كنت تريد رقمًا لجهازك وملفك الثنائي، النتائج تختلف مع كثافة الشرائح وحجم الملف الثنائي.
الأرقام التي أعيد التحقق منها بالفعل أثناء تطوير الفصل الثاني، على نفس العتاد:
هذا الصف الخاص بـNSO هو المعادل الحقيقي للادعاء القديم "4 ساعات → 67 ثانية" الخاص بلعبة Among Us،
تم قياسه حديثًا في هذا الإصدار على ملف ثنائي للسويتش بـ74,790 دالة، بدون تسمية بالذكاء الاصطناعي (فك تسمية فقط — populate=False). المرحلة المتوازية (16 نواة، ~55 ثانية) تقوم بالاكتشاف المجزأ الأولي؛
مرحلة الدمج (~143 ثانية) هي أحادية الخيط حسب التصميم — قاعدة بيانات IDA واحدة، كاتب واحد — لذا إذا شاهدت
مدير المهام خلال ذلك الجزء ورأيت 15 نواة في وضع السكون، فهذا ليس تقرير خطأ، بل فيزياء.
الحصول على رقم صادق هنا كان قصة رعب صغيرة بحد ذاتها. الإصدار الأول من دعم NSO عمل بشكل نظيف، خرج برمز 0، وأعاد بفخر 727 دالة لملف ثنائي يحتوي على حوالي 75,000 منها — ليس تعطلًا، بل مجرد خطأ فادح وواثق، وهو أسوأ بطريقة ما. تبين أن IDA ليس لديه أداة تحميل أصلية لـNSO، لذا تم تحميل الملف بصمت على أنه x86 عادي ("metapc") على الرغم من أن السويتش يعمل بـARM64 منذ إطلاق الصندوق. كل شريحة قامت بتشغيل ماسح مقدمة x86 ضد تعليمات AArch64 خالصة وسمت أي شيء صادفته بالخطأ كـ"دالة." إصلاح المعمارية لم يصلح شيئًا بمفرده، لأن الملف الثنائي كان أيضًا لا يزال مضغوطًا بـLZ4 في الذاكرة — لذا نصف ما تم مسحه كان، بتسامح، ضوضاء. وحتى بعد فك الضغط بشكل صحيح ووضع علامة AArch64، كل شريحة كانت تبحث فقط عن أهداف استدعاء ضمن شريحتها الصغيرة من الملف الثنائي، مما يفقد كل استدعاء يعبر حدود الشريحة — وفي ملف ثنائي بهذا الحجم، هذا هو معظمها. ثلاثة أخطاء، رقم واحد، ولم يكن لأي منها اللطف في إلقاء استثناء. (حاولنا أيضًا تقليص مرحلة الدمج عن طريق تخطي تحليل إطار المكدس الخاص بـIDA — حصلنا على تسارع جميل وقاعدة بيانات حيث رفضت Hex-Rays بلطف فك ترجمة نصفها. تم التراجع عن ذلك بسرعة. أبقينا على تخطي توقيعات FLIRT الأصغر بكثير والأكثر أمانًا، والذي يساوي حوالي ~3% غير مهم ولم يكسر شيئًا، والذي شعرنا في هذه المرحلة بأنه سمة شخصية تستحق الاحتفاظ بها.)
حول دقة التسمية: ليست حقيقة أرضية بمستوى Ghidra، إنها نموذج 8B يخمن من الشيفرة الزائفة.
المساعدات العامة/الدوال الجالبة تميل إلى أن تكون جيدة؛ المنطق المرتبط باللعبة بعمق هو أكثر من مجرد رمي عملة.
أعد تسمية أي شيء يخطئ فيه — لهذا السبب يستمر rename_function مباشرة في الرسم البياني.
.i64 واحد. العمالة قابلة للتكوين عبر علم، ملف إعداد، أو متغير بيئة..so/لينكس) مضمنة مسبقًا؛ إضافة
تنسيق جديد هو ملف واحد، لا تغييرات جوهرية. spectrida formats يسرد المسجل. انظر
إضافة تنسيق ملف ثنائي جديد.N. شاهد وهو يفكر. يظهر الاسم.B لتسمية كل دالة sub_* في القائمة. ابتعد. عد.O أو شغّل spectrida overview file.i64. يقرأ النموذج 120
اسم دالة مأخوذة ويخبرك بما يفعله الملف الثنائي، ما هي أنظمته الفرعية، وأي شيء
ذو صلة بالأمان. حدد بشكل صحيح بيئة تشغيل IL2CPP بـ153 ألف دالة في 30 ثانية.C يعرض المستدعين والمستدعَين. يستخدمها النموذج كسياق
عند التسمية — دالة تُستدعى بواسطة Player$$TakeDamage تُسمى بشكل أفضل من تلك المنعزلة.pip install spectrida
المتطلبات: **IDA Pro 9.x** مع idalib · **Python 3.10+** · **Ollama**```bash
# install Ollama (Windows)
winget install Ollama.Ollama
# pull the model (8.7 GB — go get coffee)
ollama pull hf.co/gdfhhjk/spectrida-re-gguf:latest
# first run — detects your IDA install and sets everything up
spectrida onboard
# or just try the demo right now
spectrida --demo
spectrida analyze GameAssembly.dll spectrida analyze GameAssembly.dll --workers 8 # custom worker count
spectrida open file.i64
spectrida overview file.i64 spectrida overview file.i64 --addr 0x10001000 --addr 0x10353fd0 # include specific functions
spectrida export file.i64 -f idc # IDA script — apply names to any install spectrida export file.i64 -f json # full dump with addresses + sizes spectrida export file.i64 -f csv # spreadsheet spectrida export file.i64 -f symbols # addr name pairs spectrida export file.i64 --named-only # skip sub_* functions
spectrida serve
spectrida onboard
---
## مفاتيح واجهة TUI
| المفتاح | الإجراء |
|-----|--------|
| `N` | تسمية الدالة المختارة — الذكاء الاصطناعي يبث النتيجة مباشرة |
| `R` | إعادة تسمية — معبأة مسبقاً باقتراح الذكاء الاصطناعي |
| `D` | تبديل الكود الزائف المُفكك (Hex-Rays) |
| `C` | سلسلة الاستدعاء — المستدعون والمستدعات |
| `B` | تسمية مجمعة لجميع دوال `sub_*` في القائمة الحالية |
| `O` | نظرة عامة — ملخص الذكاء الاصطناعي للثنائي بأكمله |
| `/` | بحث تقريبي |
| `?` | تعليمات |
| `Q` | خروج |
---
## واجهة برمجة التطبيقات (API)
لا حاجة لواجهة TUI — قم بتشغيل spectrIDA من البرامج النصية، Claude Code، الدفاتر، أي شيء:```python
import asyncio
from spectrida.api import open_i64
async def main():
async with open_i64("GameAssembly.i64") as db:
# list all 153k functions
funcs = await db.list_functions()
# name one function — returns name + reasoning + confidence
result = await db.name_function(0x10001000)
print(result["new_name"]) # init_atexit_handler
print(result["reasoning"]) # allocates array of 3 fn ptrs, calls _atexit...
# batch name everything (with live progress)
async def on_progress(done, total, r):
print(f" {done}/{total} {r['old_name']} -> {r['new_name']}")
await db.batch_name(limit=500, rename=True, progress_cb=on_progress)
# ask what the binary does
overview = await db.overview()
print(overview)
# export to IDA script
await db.export("names.idc", fmt="idc", named_only=True)
asyncio.run(main())
hf.co/gdfhhjk/spectrida-re-gguf — Qwen3-8B مضبوط بدقة للهندسة العكسية.
تم التدريب على:
jtsylve/ida-mcp — IDA بدون واجهة رسومية مع idalibنهج التدريب: SFT موجه للخلايا العصبية + GRPO. يتم ضبط الخلايا العصبية ذات الصلة بالهندسة العكسية فقط — تظل معرفة Qwen3 الأساسية سليمة، لقد أضفت فقط مهارة محددة جدًا في الأعلى.
يعمل محليًا عبر Ollama. GGUF — يعمل على CPU أو GPU أو كليهما.
أنت تقوم بهندسة عكسية لشيء ما. لديك ملف ثنائي به 150,000 دالة. ربما 2,000 منها لها أسماء من البيانات الوصفية. الـ 148,000 الأخرى هي sub_XXXXXXXX. تريد العثور على كود الشبكة. لا يمكنك استخدام grep للبحث عنه لأنه لا يوجد شيء له اسم بعد.
يمكن لمهندس عكسي بشري تسمية حوالي 50-100 دالة في الساعة إذا كان سريعًا. بهذا المعدل، 150 ألف دالة = 3 سنوات.
يسميها spectrIDA بين عشية وضحاها. ليس بشكل مثالي — ربما دقة 70% على الدوال العامة، أعلى بكثير على الأنماط التي يتعرف عليها النموذج. ولكن الآن بدلاً من 148 ألف دالة sub_ لديك network_send_packet، serialize_player_state، validate_checksum — وأنت تعرف أين تبحث.
إنه لا يحل محل مهندس عكسي ماهر. إنه يقوم بالـ 80% المملة حتى تتمكن من التركيز على الـ 20% المثيرة للاهتمام. إنها طبقة التوجيه.
حالات استخدام حقيقية:
sub_140001234 لمدة 20 دقيقة وهو يفكر لا بد أن هناك طريقة أفضل~/.spectrida/config.toml:```toml
[ida]
idalib = "C:/Program Files/IDA Professional 9.1"
output_dir = "~/.spectrida/output"
[ollama] base_url = "http://localhost:11434" model = "spectrida-re" # any ollama model name works
[pipeline] workers = 16
تجاوزات متغيرات البيئة: `SPECTRIDA_IDALIB` · `SPECTRIDA_MODEL` · `SPECTRIDA_WORKERS` · `SPECTRIDA_OLLAMA_URL`
---
## إضافة تنسيق ثنائي جديد
دعم التنسيقات هو نظام إضافي، وليس كومة من فروع if/elif — PE وNSO وELF كلها مجرد ملفات تحت `spectrida/analysis/formats/`، تُكتشف تلقائيًا. قم بتشغيل `spectrida formats` لرؤية ما هو مسجل حاليًا.```bash
$ spectrida formats
ELF spectrida.analysis.formats.elf.ELFHandler
NSO spectrida.analysis.formats.nso.NSOHandler
PE spectrida.analysis.formats.pe.PEHandler
generic spectrida.analysis.formats.generic.GenericHandler
مهمة معالج التنسيق ضيقة — انظر إلى ملف وقل ما إذا كنت تملكه، ثم صف تخطيط الكود الخاص به. كل شيء آخر (استراتيجية التقسيم، فحص مقدمة GPU، دمج التقسيمات في ملف .i64 واحد) يُعالَج مرة واحدة، بشكل عام، خارج حزمة التنسيق. NSO هو المثال الكامل: منطق إلغاء ضغط LZ4 + mem2base/add_segm من idaapi كان موجودًا بالفعل في nso_loader.py (الإصلاح لأخطاء البنية الخاطئة/المضغوطة/نقطة الدخول العمياء محليًا من تاريخ الفصل 2) — formats/nso.py هو محول رقيق يكشف تلك الوحدة الموجودة والمُصدق عليها عبر عقد FormatHandler، وليس إعادة كتابة.
لإضافة تنسيق، ضع ملفًا جديدًا واحدًا في spectrida/analysis/formats/ ولا شيء آخر. لا تعديلات على parallel_analyze.py أو shard_worker.py أو السجل — يتم اكتشافه عن طريق مسح الدليل بحثًا عن أي وحدة تعرض مثيل HANDLER.```python
from spectrida.analysis.formats.base import FormatHandler, PreparedImage, Section
class MyFormatHandler(FormatHandler): name = "MYFMT"
@staticmethod
def sniff(header: bytes, path: str) -> bool:
return header[:4] == b"MYF0" # however you recognize the format
def prepare(self, path: str, workdir: str) -> PreparedImage:
# Format idalib already loads natively (ELF, PE, Mach-O)? Just parse
# the section/segment table — return the original path unchanged.
return PreparedImage(
binary_path=path,
image_base=0,
sections=[Section(name=".text", va=0x1000, raw_off=0x400,
raw_size=0x2000, vsize=0x2000, is_code=True)],
arch=None, # set "x86_64"/"arm64" only if IDA can't detect it itself
)
# Only needed if idalib has NO native loader for this format (NSO is the
# example): do any manual idaapi/ida_segment setup here, called right
# after idapro.open_database() succeeds, before analysis starts.
# def post_open(self) -> None: ...
HANDLER = MyFormatHandler()
هذا هو العقد بأكمله:
| الطريقة | مطلوبة؟ | ما تفعله |
|---|---|---|
| `sniff(header, path)` | نعم | فحص البايتات السحرية/الامتداد — هل يمتلك هذا المعالج الملف؟ |
| `prepare(path, workdir)` | نعم | إرجاع `PreparedImage`: الملف الذي يجب أن تفتحه idalib + جدول أقسامه |
| `post_open()` | لا (الافتراضي لا يقوم بشيء) | إعداد يدوي للمقاطع للتنسيقات التي ليس لها مُحمّل IDA أصلي (انظر `nso.py`) |
| `make_shard_binary(image, dst, va_start, va_end)` | لا (الافتراضي يعمل) | تجاوز فقط إذا كان تصفير بايتات الأقسام خارج الشظية خطأً لتنسيقك (انظر `nso.py` — لا تقم أبدًا بتصفير ملف مضغوط) |
| `code_range(image)` | لا (الافتراضي يعمل) | تجاوز فقط إذا كان 'الحد الأدنى/الأقصى لأقسام `is_code`' ليس الإجابة الصحيحة |
| `read_bytes(image, va_start, va_end)` | لا (الافتراضي يعمل) | تجاوز إذا كان `prepare()` يحمل بالفعل البايتات ذات الصلة في الذاكرة (NSO) بدلاً من القرص |
| `global_entry_points(image, text_start, text_end)` | لا (الافتراضي: لا شيء) | تجاوز فقط إذا كان الفحص المحلي لكل شظية سيفقد نقاط الدخول الحقيقية — يحتاج NSO إلى ذلك لأن وظائف الأوراق AArch64 لا يمكن اكتشافها إلا عبر أهداف BL التي تظهر في مكان آخر في الثنائي، وليس من خلال فحص مقدمة محلي |
انظر إلى `formats/pe.py` للحصول على أبسط معالج ممكن (تحليل رأس نقي، بدون تجاوزات) و `formats/nso.py` للحالة الكاملة (يغلف فك الضغط + إعداد المقطع اليدوي + كل التجاوزات).
يمكن لحزم الطرف الثالث أيضًا تسجيل معالج، دون لمس مصدر spectrIDA على الإطلاق، عبر مجموعة نقاط الدخول `spectrida.formats`:```toml
# in a separate package's pyproject.toml
[project.entry-points."spectrida.formats"]
myformat = "spectrida_myformat_plugin:HANDLER"
توجد تغطية اختبارية لنظام التنسيق في tests/test_formats.py — بلغة بايثون نقية، ولا تتطلب IDA/idalib، لذا تعمل في CI.
كان الفصل 1 أسرع وأكثر مرحًا من IDA. الفصل 2 هو spectrIDA كزميل في الفريق: رسم بياني معرفي دائم وقابل للاستعلام عن كل وظيفة سُميت من قبل، وخادم MCP بحيث يمكن لكلود (أو أي عميل MCP آخر — pi يعمل أيضًا) البحث والاستدلال من خلاله مباشرة، بدلاً من قيامك بنسخ ولصق مخرجات المفكك في نافذة الدردشة.```bash spectrida install mcp
ذلك كل شيء. يقوم بتسجيل الخادم مع Claude Code و pi تلقائيًا (يقوم بسحب `mcp` + `neo4j` إذا كان إجراء `pip install spectrida` المجرد قد تخطاها)، ويكتب التكوين الخاص بهما، ويخبرك بأي إعادة تشغيل تدين بها له.
**ما يحصل عليه Claude فعليًا، بمجرد تشغيل Neo4j (قسم `[graph]` في تكوين `spectrida`، أو فقط قم بتوجيهه إلى مثيل محلي):**
- `search_functions` / `get_function` / `get_callees` / `get_callers` / `trace_chain` — قراءات سريعة ومخزنة مؤقتًا للرسم البياني. تعيد `get_function` الكود الزائف **و** التفكيك (حدود التعليمات الدقيقة والمعاملات — التي لا يمكن لطبقة الكود الزائف توفيرها، وهو أمر مهم بمجرد الانتقال من 'ماذا يفعل هذا' إلى 'أين يجب تعديل هذا بالضبط') بالإضافة إلى المستدعين/المستدعين المضمّنين، لذلك يقرر Claude ما إذا كان سيستمر في السلسلة بشكل أعمق من خلال النظر إلى ما إذا كان المستدعى لا يزال `sub_*` في الاستجابة نفسها — دون رحلة ذهاب وإياب إضافية فقط لمعرفة أنه لا يوجد شيء آخر لرؤيته.
- `get_full_pseudocode` / `rename_function` — قراءات/كتابات حية وموثوقة مباشرة إلى `.i64` عندما لا تكون المقتطفات المخزنة كافية أو يتم معرفة اسم أخيرًا.
- `analyze_binary` — قم بتسليمه ملفًا ثنائيًا لم يره من قبل (PE أو NSO، مقسم بالتوازي في كلتا الحالتين) ويقوم بتشغيل خط الأنابيب بالكامل — تحليل ← فك التجميل (Itanium *و* MSVC) ← تسمية بالذكاء الاصطناعي للبقايا المجردة حقًا ← دفع كل شيء إلى الرسم البياني — كمهمة خلفية تستقصيها، بحيث لا يسد تشغيل متعدد الدقائق المحادثة.
- `doctor` / `start_all` — تحقق أو شغّل llama-server + Neo4j دون مغادرة الدردشة. إذا لم يكن خادم llama مثبتًا في أي مكان، يقوم `start_all` بجلبه عبر winget (Windows) أو brew (macOS) أولاً — لا حاجة لتنزيل/إعداد llama.cpp منفصل.
إنه ليس سحرًا — دالة لا تزال `sub_140001234` لأن أحدًا لم ينظر إليها بعد، فهي لا تزال `sub_140001234`. لكن الرسم البياني يتذكر كل ما قام النموذج *باكتشافه*، إلى الأبد، عبر الجلسات، ويمكن لـ Claude التجول فيه مثل زميل قرأ قاعدة البيانات بدلاً من التحديق في دالة واحدة في كل مرة.
**قيد التطوير:**
- **تسمية السياق العميق** — اتبع أشجار الاستدعاء بمستويات N عميقة، وأطعم السلسلة الكاملة للنموذج. يجب أن تعرف دالة تبعد 3 قفزات عن `encrypt_block` أنها في مسار التشفير.
- **إزالة التعتيم** — كشف نمط TigressVM وتتبع المعالج
- **التصحيح الفعلي** — التفكيك موجود الآن في الرسم البياني حتى يتمكن الوكيل *من* تخطيط تصحيح على مستوى البايت؛ تحويل 'هذه هي التعليمات الدقيقة للتغيير' إلى 'وهذه هي الكتابة' هو الخطوة التالية.
---
## الفصل الثالث — الشبح يمشي عبر الجدران
الفصلان الأول والثاني يقرآن الملف الثنائي ويتذكرانه. لكن قراءة دالة تخبرك ما *هي*، وليس ما *تفعله* عند الضغط على الزناد. الفصل الثالث — [**phantomrt**](https://pypi.org/project/phantomrt/) — يضغط على الزناد.```bash
pip install "spectrida[atlas]"
تأخذ دالة spectrIDA المسماة بالفعل وتقوم بأحد ثلاثة أمور مسكونة لها:
.nso لـ Switch أو ملف .so لأندرويد.ثم تختم الحكم على نفس عقدة Neo4j كخصائص dyn_*، بحيث يرى العميل الذي يجتاز الرسم البياني الاسم والسلوك في مكان واحد. ست أدوات MCP جديدة — emulate_function و hunt_crashes و live_trace و dynamic_overview و risk_functions و learn_vm — جميعها تدعم الرسم البياني الواحد. زاوية الاستدلال هي أي LLM يقود؛ phantomrt فقط يضمن أن لديه حقائق وقت تشغيل حقيقية ليعقل بها بدلاً من التخمينات.```
spectrIDA (names it) ─▶ phantomrt (runs it) ─▶ graph (dyn_status / crash / live args) ─▶ the agent reasons
**وفي روح قصة الرعب الخاصة بـ NSO أعلاه:** أول مطاردة حقيقية للأخطاء وجدت بصراحة
*لا شيء* — وكان السبب أكثر إثارة للاهتمام من أن يكون تعطلاً. عند توجيه الأداة نحو
نسخة قديمة حقيقية وضعيفة من FreeType، لم يعطِ التعتيم الأعمى أي نتيجة. ثم أبلغ التعتيم المُوجَّه بالتغطية عن تغطية منتصر بلغت **64,000 حافة** — وهي كذبة، لأن الملف الثنائي كان PIE و ASLR كان يعيد ترتيب العناوين بهدوء كل مرة تُشغَّل، لذا فإن "التغطية الجديدة" كانت في الغالب المُحمِّل وهو يُخلط الأوراق. عند تعطيل ASLR، ينخفض الرقم الصادق إلى 727 حافة حقيقية، ويتوقف عند هذا الحد — لأن كل بذرة كانت خط TrueType، لذا احتُجز المُعتِّم داخل محلل واحد ولم يستطع تحوير بنيويًا ليدخل إلى كود CFF/Type1/BDF حيث تعيش الأخطاء فعلًا. لم يكن الحل هو أداة تحوير أذكى، بل بذور أفضل: جلبت الوكيل عينات حقيقية من OpenType/Type1/BDF، وقفزت التغطية من 727 → 4,013 قبل تكرار تعتيم واحد، واستكشفت بشكل صحيح. لا يزال لا يوجد تعطل في الميزانية — وهي الحالة الصادقة لتشغيل لمدة 3 دقائق على نواة واحدة مقابل مهمة تستغرق عادةً ساعات. الآلية حقيقية. لقد اصطادت رقمها *المزيف* الخاص بدلاً من الإبلاغ عنه. هذا هو بيت القصيد.
**إخلاء مسؤولية شبحية صادقة:** phantomrt هي `0.1.0`. ألفا. إنها طبقة ديناميكية صلبة، وليست أداة كشف أخطاء سحرية — لقد وجدت أخطاءً مزروعة في هدف لعبة فوريًا، وفي الأهداف الحقيقية تُخبرك بصدق عندما تتعثر (`needs_state`)، وعندما يكون التعطل مجرد *مرشح* (اذهب وتحقق من أن المؤشر تحت سيطرة الإدخال بالفعل)، وعندما تحتاج فقط إلى المزيد من الوقت وبذور أفضل. مفاتيح التبديل الثنائية لا تعمل مباشرة — يحتاج Frida إلى شيء يمكنه تشغيله — لذا هناك، المحاكاة هي الباب الوحيد وسيظهر `needs_state` كثيرًا. هذا صادق، وليس معطلاً.
إنها الإضافة الثقيلة عمدًا (`torch`, `unicorn`, `frida`) — التثبيت الأساسي `pip install spectrida` لا يسحب أيًا منها. المصدر موجود في [`phantomrt/`](https://github.com/ggfuchsi-oss/spectrida-reverse_engineering_stack/blob/HEAD/phantomrt/)؛ وREADME الخاص بها بنكهتها الشبحية موجود [هناك](https://github.com/ggfuchsi-oss/spectrida-reverse_engineering_stack/blob/HEAD/phantomrt/README.md).
*الشبح الثابت يُسمي دوالّك. هذا الشبح يُجبرها على الاعتراف.* 👻
---
## الترخيص
MIT. افعل ما تشاء به. إذا عمل، رائع.
إذا لم يعمل، لُمْ تكميم GGUF.
بُني بحقد، قهوة، و RTX 4070.
النموذج لديه 199 تحميلاً بدون أي تسويق. كل تحميل يضيف 0.01% إلى سرعة التطوير.
(هذا ليس صحيحًا. لكنه قريب.) 👻
| الملف الثنائي | الدوال | المهمة | الوقت / النتيجة |
|---|
| test_small.dll (PE) | 189 | تحليل متوازي، 4 عمال، واجهة سطر أوامر | 6.4 ثوانٍ |
| test_small.dll (PE) | 164 | خط أنابيب MCP كامل (تحليل + فك تسمية + كتابة رسم بياني) | 9.8 ثوانٍ |
| main.nso — Mario Odyssey (NSO)، 16 عاملاً | 28,038 دالة أولية | مرحلة المسح المجزأ المتوازي | 54.5 ثانية |
| main.nso — Mario Odyssey (NSO)، 16 عاملاً | 74,790 دالة إجمالية | + مرحلة الدمج/التحليل الكامل | 143.1 ثانية |
| main.nso — Mario Odyssey (NSO)، 16 عاملاً | 74,790 دالة إجمالية | الوقت المستغرق من البداية للنهاية | 197.6 ثانية |
| main.nso — Mario Odyssey (NSO) | 74,790 | تم حلها عبر فك التسمية وحده (واجهة Itanium ABI، مجانية، بدون ذكاء اصطناعي) | 67,300 (90.0%) |
D يبدل شيفرة Hex-Rays الزائفة..idc، أو ملف رموز.
.idc يطبق جميع الأسماء المولدة بواسطة الذكاء الاصطناعي في أي تثبيت IDA بنقرة واحدة.from spectrida.api import open_i64. قم بقيادة كل شيء من السكريبتات،
الدفاتر، أو Claude Code دون لمس واجهة TUI.spectrida install mcp يربطه مباشرة بـClaude Code و/أو
pi، بدون تحرير JSON يدوي. يمكن لـClaude بعد ذلك البحث/القراءة/التسلسل عبر
رسم بياني للدوال مدعوم بـNeo4j (الاسم، الشيفرة الزائفة، التفكيك، المستدعين/المستدعَين) وبدء
تحليل جديد على ملف ثنائي بنفسه — analyze_binary يشغّل خط الأنابيب بالكامل (تحليل متوازي → فك تسمية → تسمية بالذكاء الاصطناعي → رسم بياني) من استدعاء أداة واحد، كمهمة خلفية يتحقق منها.
يعمل على PE وNSO. انظر الفصل الثاني بالأسفل.spectrida --demo) — جرب كل شيء مع إعداد صفري. بدون IDA، بدون Ollama.