
Windows x64 के लिए रिफ्लेक्टिव PE मैपर और एवेज़न-हार्डन्ड मॉड्यूल स्टॉम्पिंग इंजन
Windows x64 के लिए एक न्यूनतम रिफ्लेक्टिव PE मैपर और मॉड्यूल स्टॉम्पिंग इंजन, जो एक साफ़ IPlugin ABI के इर्द-गिर्द बनाया गया है। मेमोरी में एक बाइट बफ़र से DLL को मैप करता है, एक्सपोर्ट्स को रिज़ॉल्व करता है, और प्लगइन फ़ंक्शन्स को कॉल करता है — या तो अनाम मेमोरी से (क्लासिक रिफ्लेक्टिव लोड) या एक वैध रूप से लोड की गई बलि DLL के अंदर से (मॉड्यूल स्टॉम्पिंग)।
मॉड्यूल स्टॉम्पिंग पथ एवेज़न-हार्डन्ड है: प्रति-सेक्शन सुरक्षा (कोई RWX नहीं), प्राइवेट मैपिंग क्लीनअप, मूल बाइट रिस्टोरेशन, और हीप स्क्रबिंग। pe-sieve, Moneta, hollows_hunter, BeaconEye, और YARA के साथ पोस्ट-क्लीनअप स्कैन स्टॉम्प्ड मॉड्यूल पर शून्य निष्कर्ष लौटाते हैं।
Windows पर CMake 3.15+ और MSVC, Clang, या MinGW में से कोई एक आवश्यक है।
# Configure (defaults to Release)
cmake -B build -G Ninja
# Build
cmake --build build
# The build produces:
# build/Modules/CmdPlugin/cmdplugin.dll (example plugin)
# build/Testing/harness.exe (test harness)
डिबग बिल्ड के लिए पूर्ण डायग्नोस्टिक आउटपुट के साथ:
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build
.\harness.exe cmdplugin.dll whoami
प्लगइन को VirtualAlloc'd मेमोरी में मैप करता है। कोई PEB प्रविष्टि नहीं, कोई लोडर सूचना नहीं।
.\harness.exe cmdplugin.dll whoami --stomp xpsservices.dll
.\harness.exe cmdplugin.dll "dir C:\" --stomp mscms.dll
LoadLibrary के माध्यम से sacrificial DLL को वैध रूप से लोड करता है, फिर उसके .text को plugin के साथ एक सतत image के रूप में अधिलेखित करता है। निष्पादन sacrificial DLL के address space से होता है — call stacks और module lists कोड को sacrificial module को आरोपित करते हैं।
Harness cleanup के बाद रुक जाता है ताकि आप process के विरुद्ध memory scanners चला सकें।
1. MapImage(plugin) private reflective mapping
2. LoadLibrary(sacrificial) legitimate load, PEB entry
3. Save original .text bytes for later restoration
4. Copy plugin image -> .text contiguous image preserves RIP-relative offsets
5. Relocate stomped code fix addresses for new base
6. Patch entry point mov eax,1; ret (safe FreeLibrary)
7. Per-section protections RX / R / RW per section (never RWX)
8. Resolve exports from private mapping, return stomped addresses
9. Free private mapping eliminates floating PE artifact
10. Execute plugin code runs inside "sacrificial.dll"
11. Restore original .text bytes sacrificial code back in place
12. FreeLibrary(sacrificial) unloads the module
13. LoadLibrary(sacrificial) fresh load = clean file-backed pages
14. Scrub heap buffers zero saved bytes + raw DLL data
क्लीनअप के बाद, बलि DLL सामान्य रूप से लोड किए गए मॉड्यूल से अप्रभेद्य होती है। पेज फ़ाइल-बैक्ड (निजी नहीं) होते हैं, सामग्री ऑन-डिस्क फ़ाइल से मेल खाती है, और हीप पर कोई PE आर्टिफ़ैक्ट शेष नहीं रहता।
| IOC | शमन |
|---|---|
| RWX मेमोरी क्षेत्र | प्रति-सेक्शन सुरक्षा: .text RX, .rdata R, .data RW |
| निजी निष्पादन योग्य मेमोरी (फ़्लोटिंग PE) | एक्सपोर्ट रिज़ॉल्यूशन के बाद निजी मैपिंग को VirtualFree करें |
| संशोधित मॉड्यूल कोड | मूल .text बाइट्स को पुनर्स्थापित करें, फिर स्वच्छ फ़ाइल-बैक्ड पेजों के लिए FreeLibrary + LoadLibrary करें |
| हीप पर PE हेडर | मुक्त करने से पहले रॉ DLL बफ़र और सहेजे गए बाइट्स को memset(0) करें |
| अनलोड पर DllMain क्रैश | स्टॉम्पिंग से पहले एंट्री पॉइंट को mov eax,1; ret पर पैच किया गया |
ReflectivePluginLoader/
├── CMakeLists.txt
├── Include/
│ ├── IPlugin.h Plugin ABI (TaskApi, IPlugin)
│ ├── ReflectiveLoaderEngine.h PE mapper + export resolver
│ └── StompedLoaderEngine.h Module stomping engine
├── Modules/
│ └── CmdPlugin/
│ ├── cmdplugin.cpp Command execution plugin
│ └── CMakeLists.txt
├── Testing/
│ ├── main.cpp Test harness
│ └── CMakeLists.txt
└── Tools/
└── file2hex.py DLL to C byte array converter
Modules/ के अंतर्गत एक डायरेक्टरी बनाएं और IPlugin.h शामिल करें।IPlugin इंटरफ़ेस को लागू करें:#include "IPlugin.h"
class MyPlugin : public IPlugin {
public:
void init() const override { /* setup */ }
void execute(TaskApi* task) const override { /* work */ }
void cleanup() const override { /* tear */ }
};
पाँच एंट्री पॉइंट्स (create_plugin, destroy_plugin, plugin_init, plugin_exec, plugin_cleanup) एक्सपोर्ट करें। CRT-सुरक्षित एलोकेशन के लिए HeapAlloc + placement new का उपयोग करें।
एक CMakeLists.txt जोड़ें और इसे रूट में add_subdirectory() के साथ रजिस्टर करें।
बलिदानी DLL के .text सेक्शन का आकार प्लगइन के वर्चुअल इमेज साइज़ से बड़ा होना चाहिए। इसे प्रोसेस द्वारा सक्रिय रूप से उपयोग या रनटाइम पर इंटीग्रिटी-चेक नहीं किया जाना चाहिए।
अच्छे उम्मीदवार: xpsservices.dll (1.8 MB .text), mscms.dll, colorui.dll, npmproxy.dll
खराब उम्मीदवार: ntdll.dll, kernel32.dll (सक्रिय रूप से उपयोग किए जाते हैं), clr.dll (इंटीग्रिटी चेक किया जाता है)
.text सेक्शन में फिट होनी चाहिएयह रिलीज़ मूल प्रूफ-ऑफ-कॉन्सेप्ट का पूर्ण पुनर्लेखन है:
StompedLoaderEngine.h) — पूर्ण एवेज़न क्लीनअप के साथ सन्निहित इमेज स्टॉम्पिंग.text RX, .rdata R, .data RW; अब RWX क्षेत्र नहींFreeLibrary + LoadLibrary चक्र प्राइवेटाइज़्ड पेजों को साफ़ फ़ाइल-बैक्ड पेजों से बदल देता है.text को ज़ीरो कर दिया जाता हैmov eax,1; ret FreeLibrary के दौरान DllMain क्रैश को रोकता हैVirtualFree करें (फ्लोटिंग PE को समाप्त करता है)ReflectiveLoaderEngine.h) — इनपुट बफ़र से सीधी मैपिंग, कोई मध्यवर्ती VirtualAlloc कॉपी नहींIPlugin.h) — डेड हेल्पर्स (BeaconCout, CStrLenA, PluginAlloc, PluginFree) हटाए गएmain.cpp) — NDEBUG के माध्यम से कंडीशनल कंपाइलेशन; Release बिल्ड केवल कमांड आउटपुट और स्कैन कमांड दिखाते हैं-nostartfiles (रिफ्लेक्टिव-लोडेड कोड में कोई CRT नहीं)