
استغل اختطاف ملفات DLL كسلاح بسهولة. أضف بابًا خلفيًا لأي دالة في أي ملف DLL.

يقوم DllShimmer بتحليل ملف DLL الأصلي واستخراج معلومات حول الدوال المُصدَّرة (الاسم، الرقم الترتيبي، ومعلومات إعادة التوجيه). بناءً على هذه المعلومات، يُنشئ DllShimmer ملف C++ جاهزًا (.cpp). يتيح لك الملف المُنشأ إضافة الكود الخاص بك إلى كل دالة مُصدَّرة من ملف DLL الأصلي دون تعطيل التشغيل الطبيعي للبرنامج. لا يتطلب الأمر أي هندسة عكسية أو حقن أدوات تتبّع، لأن DllShimmer لا يعتمد على توقيعات الدوال (انظر المزيد في «القيود»).
الملف الثاني المُنشأ هو ملف .def، والذي يضمن أن جميع الدوال المُصدَّرة من ملف DLL الوكيل بعد الترجمة ستحمل نفس الأسماء والأرقام الترتيبية الموجودة في ملف DLL الأصلي.
بعد الترجمة، يكون جدول العناوين المُصدَّرة (EAT) في ملف DLL الوكيل نسخة طبق الأصل من EAT في ملف DLL الأصلي. جميع أسماء وأرقام الدوال المُصدَّرة متطابقة، والدوال المُعاد توجيهها تظل مُعاد توجيهها كذلك. لا يقوم DllShimmer بإعادة توجيه جميع الدوال بشكل صريح (كما تفعل معظم الأدوات)، مما يؤدي إلى إنشاء بنية EAT جديدة ومريبة تمامًا.
قم بترجمة كود Go المصدري أو حمّل الملف الثنائي المُجمَّع.
التبعيات:
x86_64-w64-mingw32-g++x86_64-w64-mingw32-dlltoolمثال:
# Backdoor version.dll (proxy to absolute path)
./DllShimmer -i version.dll -o project/ -x "C:/Windows/System32/version.dll" -m
# Backdoor random chat.dll (proxy to relative path)
./DllShimmer -i chat.dll -o project/ -x "lib/chat2.dll" -m
# Backdoor random app.dll (static linking to the original DLL)
./DllShimmer -i app.dll -o project/ -x "app2.dll" -m --static
المعاملات:
-i / --input <path> [مطلوب]
ملف DLL الأصلي الذي تريد زرع باب خلفي فيه.
-o / --output <path> [مطلوب]
المسار إلى الدليل حيث سيحفظ DllShimmer جميع الملفات المُنشأة.
-x / --original <path> [مطلوب]
في حالة الربط الديناميكي (الافتراضي)، وفّر المسار الذي سيجد فيه ملف DLL الوكيل ملف DLL الأصلي على النظام الهدف.
في حالة الربط الثابت (--static)، حدّد اسم ملف DLL الأصلي فقط. سيتم البحث عنه وفقًا لترتيب التحميل الافتراضي في Windows.
-m / --mutex [اختياري]
تفعيل هذا الخيار سيضيف كائن مزامنة (mutex) إلى الملف المصدري، مما يمنع تنفيذ الباب الخلفي أكثر من مرة خلال تشغيل واحد للبرنامج. ستستمر جميع الدوال الأصلية في العمل بشكل طبيعي.
--static [اختياري]
يفعّل الربط الثابت بين ملف DLL الوكيل (IAT) وملف DLL الأصلي (EAT). يُنشئ هذا ملف .lib إضافيًا في دليل الإخراج، يعمل كملف DLL الأصلي للترجمة الثابتة.
تحمل هذه التقنية بعض القيود الخطيرة مقارنةً بالربط الديناميكي:
ومع ذلك، قد يكون الربط الثابت أكثر تمويهًا وطبيعية في بعض السيناريوهات.
الافتراضي: يستخدم DllShimmer دائمًا الربط الديناميكي مع الدالتين LoadLibraryA() وGetProcAddress().
--debug-file <path> [اختياري]
احفظ سجلات التصحيح في ملف. تُكتب السجلات إلى ملف بشكل مستمر أثناء تشغيل البرنامج. إذا تم الاختيار، لا تتم طباعة السجلات إلى STDOUT.
الافتراضي: يكتب DllShimmer دائمًا سجلات التصحيح إلى STDOUT.
مثال على مخرجات التصحيح:

قبل البدء في استكشاف الأخطاء وإصلاحها:
--static). من الأسهل التصحيح باستخدام الربط الديناميكي (الافتراضي).--debug-file)..cpp المُنشأ، لا أرى جميع الدوال المُصدَّرة من ملف DLL الأصلي.الدوال المعرّفة في ملف DLL الأصلي على أنها «مُعاد توجيهها» (forwarded) غير مضمنة في ملف .cpp. ومع ذلك، فهي ظاهرة في ملف .def. سيتم تصديرها أيضًا بعد الترجمة، تمامًا كما في ملف DLL الأصلي.
أحيانًا، يعرض ملف DLL الوكيل خطأً عند تحميل ملف DLL الأصلي، ويكون رمز الخطأ 126، حتى لو حددت نظريًا المسار النسبي الصحيح في معامل -x. لماذا لا يعمل؟!؟
يتم البحث عن ملفات DLL في Current Directory. في 98% من الحالات، يكون هذا ببساطة موقع ملف EXE الرئيسي، لكن هناك برامج (معظمها برامج قديمة) تغيّر Current Directory بشكل تعسفي باستخدام، على سبيل المثال، SetCurrentDirectoryW(). البرنامج الرئيسي على دراية بهذا التغيير، لذا فهو يحمّل ملف DLL الوكيل بشكل صحيح، لكنك غير مدرك لذلك وتحاول تحميل ملف DLL الأصلي بشكل نسبي، بينما يبحث البرنامج عنه في Current Directory المُغيَّر.
تنطبق هذه القاعدة على كل من التحميل الثابت والديناميكي لملف DLL الأصلي. لسوء الحظ، مع الربط الثابت، يصعب اكتشاف هذه المشكلة كثيرًا لأنه لا تتوفر لدينا معلومات تصحيح. يفشل محمّل النظام وينتهي الأمر. لهذا أوصي دائمًا باستخدام الربط الديناميكي الافتراضي أولاً.
في حالة الربط الديناميكي، لدينا خياران:
-x وفقًا لوضع Current Directory الجديد.Current Directory ديناميكيًا للبحث عن ملفات DLL في المكان الذي نريده.في حالة الربط الثابت، لدينا في الحقيقة خيار واحد فقط:
Current Directory.