
يتيح لك محاكاة مكتبة أندرويد أصلية، ومحاكاة iOS تجريبية.
يتيح لك محاكاة مكتبة أندرويد أصلية (native library)، بالإضافة إلى محاكاة تجريبية لنظام iOS.
هذا مشروع تعليمي لمعرفة المزيد عن تنسيق ملفات ELF/MachO ولغة تجميع ARM.
استخدمه على مسؤوليتك الخاصة!
يدعم unidbg Model Context Protocol (MCP) لتصحيح الأخطاء بمساعدة الذكاء الاصطناعي. عندما يكون المصحح نشطًا، اكتب mcp في وحدة التحكم لبدء خادم MCP يمكن لأدوات الذكاء الاصطناعي (مثل Cursor) الاتصال به.
يحتوي unidbg MCP على وضعي تشغيل:
الوضع 1: تصحيح نقاط التوقف — اربط المصحح وشغّل الكود الخاص بك. عند الوصول إلى نقطة توقف، يقوم Breaker.debug() بإيقاف المحاكي مؤقتًا — اكتب mcp في وحدة التحكم لبدء خادم MCP ودع الذكاء الاصطناعي يساعد في التحليل. جميع أدوات التصحيح متاحة (السجلات، الذاكرة، التفكيك، التنقل خطوة بخطوة، التتبّع، إلخ). بعد الاستئناف، إذا تم الوصول إلى نقطة توقف أخرى، يتوقف المصحح مرة أخرى. بمجرد اكتمال التنفيذ دون الوصول إلى نقطة توقف، تنتهي العملية ويتم إيقاف تشغيل MCP.
Debugger debugger = emulator.attach();
debugger.addBreakPoint(address);
// run your emulation logic — debugger pauses when breakpoint is hit
الوضع 2: أدوات مخصصة (قابلة للتكرار) — استخدم McpToolkit لتسجيل أدوات مخصصة ودع الذكاء الاصطناعي يعيد تشغيل الدوال المستهدفة بمعاملات مختلفة. يتم تحميل المكتبة الأصلية مرة واحدة فقط؛ وبعد كل تنفيذ تبقى العملية حية ويظل MCP نشطًا للتشغيل التالي.
McpToolkit toolkit = new McpToolkit();
toolkit.addTool(new McpTool() {
@Override public String name() { return "encrypt"; }
@Override public String description() { return "Run encryption"; }
@Override public String[] paramNames() { return new String[]{"input"}; }
@Override public void execute(String[] params) {
String input = params.length > 0 ? params[0] : "default";
// call encryption with input
}
});
toolkit.run(emulator.attach());
عندما يتوقف المصحح، اكتب mcp (أو mcp 9239 لتحديد المنفذ) في وحدة التحكم. ثم أضِف إلى إعدادات MCP في Cursor:
{
"mcpServers": {
"unidbg-mcp-server": {
"url": "http://localhost:9239/sse"
}
}
}
الحالة والمعلومات
| الأداة | الوصف |
|---|---|
check_connection | حالة المحاكي: العائلة، البنية، إمكانيات الواجهة الخلفية، isRunning، الوحدات المحمّلة |
list_modules / get_module_info | سرد الوحدات المحمّلة والحصول على التفاصيل بما في ذلك عدد الرموز المُصدَّرة والتبعيات |
list_exports | سرد الرموز المُصدَّرة/الديناميكية لوحدة مع فلتر اختياري وإزالة تشويش أسماء C++ |
find_symbol | العثور على رمز بالاسم أو العثور على أقرب رمز عند عنوان |
get_threads | سرد جميع سلاسل العمليات/المهام في المحاكي |
السجلات والتفكيك
| الأداة | الوصف |
|---|---|
get_registers / get_register / set_register | قراءة/كتابة سجلات وحدة المعالجة المركزية |
disassemble | تفكيك التعليمات عند عنوان (تُضاف تلقائيًا تعليقات توضيحية بأسماء الرموز إلى أهداف الفروع) |
assemble | تجميع نص تعليمة إلى كود آلي |
get_callstack | الحصول على مكدس الاستدعاءات الحالي (التتبّع الخلفي) |
الذاكرة
| الأداة | الوصف |
|---|---|
read_memory / write_memory | قراءة/كتابة وحدات البايت الخام للذاكرة |
read_string / read_std_string | قراءة سلسلة C أو سلسلة C++ std::string (مع كشف SSO) |
read_pointer | قراءة سلسلة مؤشرات مع حل الرموز |
read_typed | قراءة الذاكرة كقيم بنمط محدد (int8–int64, float, double, pointer) |
search_memory | البحث في الذاكرة عن أنماط بايت مع عوامل تصفية للنطاق/الأذونات |
list_memory_map | سرد جميع تعيينات الذاكرة مع الأذونات |
allocate_memory / free_memory / list_allocations | تخصيص (malloc/mmap) مع بيانات أولية اختيارية، وتحرير، وتتبّع كتل الذاكرة |
patch | كتابة تعليمات مُجمَّعة إلى الذاكرة |
نقاط التوقف والتنفيذ
| الأداة | الوصف |
|---|---|
add_breakpoint / add_breakpoint_by_symbol / add_breakpoint_by_offset | إضافة نقاط توقف حسب العنوان أو الرمز أو الوحدة+الإزاحة |
remove_breakpoint / list_breakpoints | إزالة أو سرد نقاط التوقف (مع التفكيك) |
continue_execution | استئناف التنفيذ. استخدم poll_events لانتظار breakpoint_hit أو execution_completed |
step_over / step_into / step_out | تجاوز، أو الدخول إلى (N من التعليمات)، أو الخروج من الدالة |
next_block | التوقف عند الكتلة الأساسية التالية (Unicorn فقط) |
step_until_mnemonic | التوقف عند التعليمة التالية المطابقة للرمز التذكيري، مثل bl، ret (Unicorn فقط) |
poll_events | الاستعلام عن breakpoint_hit و execution_completed وأحداث التتبّع |
التتبّع
| الأداة | الوصف |
|---|---|
trace_code | تتبّع التعليمات مع قيم قراءة/كتابة السجلات (regs_read, prev_write) |
trace_read / trace_write | تتبّع قراءات/كتابات الذاكرة في نطاق عناوين |
استدعاءات الدوال
| الأداة | الوصف |
|---|---|
call_function | استدعاء دالة أصلية حسب العنوان مع وسائط بنمط محدد (hex, string, bytes, null). يُرجع القيمة مع حل الرموز ومعاينة الذاكرة |
call_symbol | استدعاء دالة مُصدَّرة حسب الوحدة + اسم الرمز، مثل libc.so + malloc |
iOS فقط (متاح عندما تكون العائلة Family=iOS)
| الأداة | الوصف |
|---|---|
inspect_objc_msg | فحص استدعاء objc_msgSend: عرض اسم فئة المستقبِل والمُحدِّد، مثل -[NSString length] |
get_objc_class_name | الحصول على اسم فئة ObjC لكائن في عنوان معين (تحليل ذاكرة خالص، دون تغيير الحالة) |
dump_objc_class | تفريغ تعريف فئة ObjC (الخصائص والطرق والبروتوكولات و ivars) |
dump_gpb_protobuf | تفريغ مخطط رسالة GPB protobuf بصيغة .proto (64-bit فقط) |
استخدم McpToolkit لتسجيل أدوات مخصصة، حيث تنفّذ كل أداة واجهة McpTool. يستبدل هذا التوزيع اليدوي if-else بفئات أدوات نظيفة ومكتفية ذاتيًا. في هذه المرحلة تكون المكتبة الأصلية محمّلة بالكامل (تم تنفيذ JNI_OnLoad / نقطة الدخول بالفعل)، لذا فإن الكود داخل execute() لكل أداة هو منطق الدالة المستهدفة المراد تحليلها. يمكن للذكاء الاصطناعي تعيين نقاط توقف وتتبعات قبل تشغيل أداة مخصصة، ثم فحص نتائج التنفيذ عبر مدخلات مختلفة دون إعادة تشغيل العملية.
مثال أندرويد — راجع Utilities64.java للحصول على مثال JNI لأندرويد مع أدوات MCP مخصصة:
DalvikModule dm = vm.loadLibrary(new File("libtmessages.29.so"), true);
dm.callJNI_OnLoad(emulator);
cUtilities = vm.resolveClass("org/telegram/messenger/Utilities");