
مُحمِّل PE ومتعقِّب واجهة برمجة تطبيقات ويندوز. مفيد في تحليل البرامج الضارة.
تم إنشاء هذا المشروع لتسهيل عملية تحليل البرامج الضارة. الهدف هو إنشاء ملف ثنائي (activator) يقوم بتحميل ملف ثنائي يحدده المستخدم ومراقبة التنفيذ باستخدام خطافات (hooks) لواجهة برمجة تطبيقات Win32. يتم حفظ البيانات ذات الصلة على القرص. يدعم الكود كل من الملفات الثنائية x86 و x64.
لقد كتبت مقالة في المدونة تشرح كيفية عمله: http://antonioparata.blogspot.com/2022/06/thematrix-process-inspection-tool-aimed.html
لمراقبة ملف ثنائي جديد، من الضروري إنشاء مُفعّل (activator). سيقوم المُفعّل بتحميل ومراقبة ملف ثنائي يحدده المستخدم. لإنشاء مُفعّل، استخدم الخيار -add. مثال على الاستخدام هو التالي:
c:\>TheMatrix.exe -add c:\path\to\my\binary.dll
Activator file created
c:\>regsvr32.exe TheMatrix.build.dll
سيؤدي هذا الأمر إلى إنشاء ملف PE جديد يمثل المُفعّل. سيكون للمُفعّل نفس التنسيق (DLL أو EXE) الخاص بالملف الثنائي المُدخل.
بمجرد الإنشاء، يمكنك تشغيله بالطريقة التي تفضلها (بالنسبة لـ DLL، الطريقة الموصى بها هي استخدام أداة rundll32.exe).
أثناء التنفيذ، يتم حفظ البيانات الناتجة عن الوظائف المراقبة في المسار ./Desktop/thematrix/[process ID]/ (يعتمد هذا على وظيفة log_data المنفذة في utility.c).
القيود:
يقوم المشروع بتعديل بنية PEB.Ldr للسماح لواجهات برمجة تطبيقات محددة بالعمل بشكل صحيح (مثل GetModuleHandle، ...). إذا قمت بتشغيل المُفعّل على نظام WOW64 (ملف ثنائي x86 على نظام تشغيل x64)، فسيتم تعديل PEB.Ldr الخاص بـ x86 فقط (العمليات WOW64 تحتوي على كل من PEB الخاص بـ x86 و x64). عندما يتغير المعالج إلى x64، ستستخدم واجهات برمجة التطبيقات الأصلية لنظام Windows (ntdll.dll) إصدار x64 من PEB.Ldr. وهذا يعني أن المُفعّل قد لا يعمل بشكل صحيح. للتأكد من عمل إصدار x86، قم بتشغيل الملف الثنائي على نظام تشغيل x86.
لا يقوم الملف المُنشأ حديثًا بتصدير جميع الطرق ولا يحتوي على موارد الملف الأصلي. سيؤدي هذا إلى أخطاء محتملة، على سبيل المثال إذا استدعت DLL GetModuleFileName -> LoadLibrary -> FindResource. سيؤدي مسار الكود هذا إلى تحميل TheMatrix DLL الأصلي الذي لا يحتوي على المورد المطلوب.
إضافة وظائف جديدة إلى المراقب هي مهمة سهلة، ألق نظرة على ملف hooks.c للحصول على أمثلة على خطافات Kernel32.dll و bcrypt.dll. لإضافة خطاف جديد، يكفي استدعاء الوظيفة hook_add. فيما يلي مثال على إنشاء خطاف:
LPVOID __stdcall hook_BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, VOID* pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG* pcbResult, ULONG dwFlags)
{
// save plain data
if (cbInput) {
char name[MAX_PATH] = { 0 };
snprintf(name, sizeof(name), "BCryptEncrypt_%llx_%d", (uint64_t)pbInput, cbInput);
log_data(cbInput, pbInput, name);
}
LPVOID ret = call_original(
hKey,
pbInput,
cbInput,
pPaddingInfo,
pbIV,
cbIV,
pbOutput,
cbOutput,
pcbResult,
dwFlags
);
return ret;
}
hook_add("Bcrypt.dll", "BCryptEncrypt", hook_BCryptEncrypt);
يجب أن يكون للوظيفة نفس التوقيع (signature) الخاص بالوظيفة المُستهدفة. يتم استخدام الوظيفة call_original لاستدعاء الوظيفة الأصلية. يكفي استدعاء هذه الوظيفة مع معاملات الإدخال الأصلية، وسيقوم الإطار بالعمل الشاق نيابةً عنك لاستدعاء الوظيفة الصحيحة ;) يجب أن يتم استدعاء الوظيفة call_original في نفس الخيط (thread) الذي ينفذ الخطاف، وإلا ستتعطل العملية.