
मेमोरी डंप का अनुकरण करने के लिए एक आसान-से-उपयोग लाइब्रेरी। मैलवेयर विश्लेषण (कॉन्फ़िग निष्कर्षण, अनपैकिंग) और सामान्य रूप से डायनेमिक विश्लेषण (सैंडबॉक्सिंग) के लिए उपयोगी।
नोट: यह एक कार्य-प्रगति प्रोटोटाइप है, कृपया इसे वैसे ही मानें। पुल रिक्वेस्ट का स्वागत है! आप अच्छे पहले मुद्दों से शुरुआत कर सकते हैं
मिनिडंप फ़ाइलों में कोड को एम्युलेट करने के लिए एक आसान-से-उपयोग लाइब्रेरी। dumpulator का उपयोग करने वाले पोस्ट/वीडियो के लिंक यहाँ दिए गए हैं:
अपना लेख यहाँ जोड़ने के लिए पुल रिक्वेस्ट भेजने में संकोच न करें!
नीचे दिया गया उदाहरण StringEncryptionFun_x64.dmp (यहाँ से एक कॉपी डाउनलोड करें here) खोलता है, कुछ मेमोरी आवंटित करता है और 0x140001000 पर डिक्रिप्शन फ़ंक्शन को कॉल करके 0x140017000 पर स्ट्रिंग को डिक्रिप्ट करता है:
from dumpulator import Dumpulator
dp = Dumpulator("StringEncryptionFun_x64.dmp")
temp_addr = dp.allocate(256)
dp.call(0x140001000, [temp_addr, 0x140017000])
decrypted = dp.read_str(temp_addr)
print(f"decrypted: '{decrypted}'")
StringEncryptionFun_x64.dmp को tests/StringEncryptionFun उदाहरण के एंट्री पॉइंट पर एकत्र किया गया है। आप StringEncryptionFun के संकलित बाइनरी यहाँ here से प्राप्त कर सकते हैं
from dumpulator import Dumpulator
dp = Dumpulator("StringEncryptionFun_x64.dmp", trace=True)
dp.start(dp.regs.rip)
यह StringEncryptionFun_x64.dmp.trace बनाएगा जिसमें निष्पादित निर्देशों की सूची और मॉड्यूल स्विच करते समय कुछ उपयोगी संकेत होंगे। ध्यान दें कि अनुरेखण एम्युलेशन को काफी धीमा कर देता है और यह मुख्यतः डिबगिंग के लिए है।
from dumpulator import Dumpulator
dp = Dumpulator("my.dmp")
buf = dp.call(0x140001000)
dp.read_str(buf, encoding='utf-16')
मान लीजिए आपके पास निम्नलिखित फ़ंक्शन है:
00007FFFC81C06C0 | mov qword ptr [rsp+0x10],rbx ; prolog_start
00007FFFC81C06C5 | mov qword ptr [rsp+0x18],rsi
00007FFFC81C06CA | push rbp
00007FFFC81C06CB | push rdi
00007FFFC81C06CC | push r14
00007FFFC81C06CE | lea rbp,qword ptr [rsp-0x100]
00007FFFC81C06D6 | sub rsp,0x200 ; prolog_end
00007FFFC81C06DD | mov rax,qword ptr [0x7FFFC8272510]
आप केवल प्रोलॉग को निष्पादित करना चाहते हैं और कुछ रजिस्टर सेट करना चाहते हैं:
from dumpulator import Dumpulator
prolog_start = 0x00007FFFC81C06C0
# we want to stop the instruction after the prolog
prolog_end = 0x00007FFFC81C06D6 + 7
dp = Dumpulator("my.dmp", quiet=True)
dp.regs.rcx = 0x1337
dp.start(begin=prolog_start, end=prolog_end)
print(f"rsp: {hex(dp.regs.rsp)}")
quiet फ्लैग DLL लोड होने और मेमोरी क्षेत्रों के सेटअप के बारे में लॉग को दबा देता है (स्क्रिप्ट में उपयोग के लिए जहां आप लॉग स्पैम को कम करना चाहते हैं)।
आप @syscall डेकोरेटर का उपयोग करके सिस्कॉल को (पुनः) कार्यान्वित कर सकते हैं:
from dumpulator import *
from dumpulator.native import *
from dumpulator.handles import *
from dumpulator.memory import *
@syscall
def ZwQueryVolumeInformationFile(dp: Dumpulator,
FileHandle: HANDLE,
IoStatusBlock: P[IO_STATUS_BLOCK],
FsInformation: PVOID,
Length: ULONG,
FsInformationClass: FSINFOCLASS
):
return STATUS_NOT_IMPLEMENTED
सभी सिस्कॉल फ़ंक्शन प्रोटोटाइप ntsyscalls.py में पाए जा सकते हैं। API का उपयोग करने के कई उदाहरण भी वहाँ हैं।
किसी मौजूदा सिस्कॉल कार्यान्वयन को हुक करने के लिए आप निम्नलिखित कर सकते हैं:
import dumpulator.ntsyscalls as ntsyscalls
@syscall
def ZwOpenProcess(dp: Dumpulator,
ProcessHandle: Annotated[P[HANDLE], SAL("_Out_")],
DesiredAccess: Annotated[ACCESS_MASK, SAL("_In_")],
ObjectAttributes: Annotated[P[OBJECT_ATTRIBUTES], SAL("_In_")],
ClientId: Annotated[P[CLIENT_ID], SAL("_In_opt_")]
):
process_id = ClientId.read_ptr()
assert process_id == dp.parent_process_id
ProcessHandle.write_ptr(0x1337)
return STATUS_SUCCESS
@syscall
def ZwQueryInformationProcess(dp: Dumpulator,
ProcessHandle: Annotated[HANDLE, SAL("_In_")],
ProcessInformationClass: Annotated[PROCESSINFOCLASS, SAL("_In_")],
ProcessInformation: Annotated[PVOID, SAL("_Out_writes_bytes_(ProcessInformationLength)")],
ProcessInformationLength: Annotated[ULONG, SAL("_In_")],
ReturnLength: Annotated[P[ULONG], SAL("_Out_opt_")]
):
if ProcessInformationClass == PROCESSINFOCLASS.ProcessImageFileNameWin32:
if ProcessHandle == dp.NtCurrentProcess():
main_module = dp.modules[dp.modules.main]
image_path = main_module.path
elif ProcessHandle == 0x1337:
image_path = R"C:\Windows\explorer.exe"
else:
raise NotImplementedError()
buffer = UNICODE_STRING.create_buffer(image_path, ProcessInformation)
assert ProcessInformationLength >= len(buffer)
if ReturnLength.ptr:
dp.write_ulong(ReturnLength.ptr, len(buffer))
ProcessInformation.write(buffer)
return STATUS_SUCCESS
return ntsyscalls.ZwQueryInformationProcess(dp,
ProcessHandle,
ProcessInformationClass,
ProcessInformation,
ProcessInformationLength,
ReturnLength
)
v0.2.0 से अपनी स्वयं की संरचनाओं को आसानी से घोषित करने का समर्थन है:
from dumpulator.native import *
class PROCESS_BASIC_INFORMATION(Struct):
ExitStatus: ULONG
PebBaseAddress: PVOID
AffinityMask: KAFFINITY
BasePriority: KPRIORITY
UniqueProcessId: ULONG_PTR
InheritedFromUniqueProcessId: ULONG_PTR
इन संरचनाओं को इंस्टेंटिएट करने के लिए आपको एक Dumpulator इंस्टेंस का उपयोग करना होगा:
pbi = PROCESS_BASIC_INFORMATION(dp)
assert ProcessInformationLength == Struct.sizeof(pbi)
pbi.ExitStatus = 259 # STILL_ACTIVE
pbi.PebBaseAddress = dp.peb
pbi.AffinityMask = 0xFFFF
pbi.BasePriority = 8
pbi.UniqueProcessId = dp.process_id
pbi.InheritedFromUniqueProcessId = dp.parent_process_id
ProcessInformation.write(bytes(pbi))
if ReturnLength.ptr:
dp.write_ulong(ReturnLength.ptr, Struct.sizeof(pbi))
return STATUS_SUCCESS
यदि आप दूसरे तर्क के रूप में एक पॉइंटर मान पास करते हैं तो संरचना मेमोरी से पढ़ी जाएगी। आप myptr: P[MY_STRUCT] के साथ पॉइंटर घोषित कर सकते हैं और myptr[0] के साथ उन्हें डीरेफरेंस कर सकते हैं।
x64dbg के लिए एक सरल प्लगइन उपलब्ध है जिसे MiniDumpPlugin कहते हैं minidump कमांड को 2022-10-10 से x64dbg में एकीकृत कर दिया गया है। डंप बनाने के लिए, निष्पादन को रोकें और MiniDump my.dmp कमांड निष्पादित करें।
python -m pip install dumpulator
स्रोत से स्थापित करने के लिए:
python setup.py install
एक विकास वातावरण के लिए स्थापित करें:
python setup.py develop
डंपुलेटर को speakeasy और qiling जैसे सैंडबॉक्स से अलग करने वाली बात यह है कि पूरी प्रक्रिया मेमोरी उपलब्ध है। यह प्रदर्शन में सुधार करता है क्योंकि आप बिना कभी unicorn छोड़े मैलवेयर के बड़े हिस्सों को एम्युलेट कर सकते हैं। इसके अतिरिक्त एक यथार्थवादी Windows वातावरण प्रदान करने के लिए केवल सिस्कॉल को एम्युलेट करना होता है (क्योंकि वास्तव में सब कुछ एक वैध प्रक्रिया वातावरण है)।