ملاحظة: هذا نموذج أولي في العمل ، يرجى معالجته على هذا النحو. طلبات السحب موضع ترحيب! يمكنك أن تبلل قدميك بمشكلات أولية جيدة
مكتبة سهلة الاستخدام لمحاكاة التعليمات البرمجية في ملفات Minidump. فيما يلي بعض الروابط إلى المنشورات/مقاطع الفيديو باستخدام مولاؤه:
لا تتردد في إرسال طلب سحب لإضافة مقالتك هنا!
المثال أدناه يفتح StringEncryptionFun_x64.dmp (قم بتنزيل نسخة هنا) ، يخصص بعض الذاكرة ويستدعي وظيفة decryption على 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 هنا
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 بقمع السجلات حول DLLs المحملة وإعداد مناطق الذاكرة (للاستخدام في البرامج النصية حيث تريد تقليل سجل البريد العشوائي).
يمكنك (إعادة) تنفيذ syscalls باستخدام ديكور @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يمكن العثور على جميع النماذج الأولية لوظيفة Syscall في ntsyscalls.py. هناك أيضًا الكثير من الأمثلة حول كيفية استخدام واجهة برمجة التطبيقات.
لتوصيل تطبيق Syscall الحالي ، يمكنك القيام بما يلي:
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:Windowsexplorer.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 في X64DBG منذ 2022-10-10. لإنشاء تفريغ وإيقاف التنفيذ وتنفيذ الأمر MiniDump my.dmp .
من PYPI (أحدث إصدار):
python -m pip install dumpulator
للتثبيت من المصدر:
python setup.py install
التثبيت لبيئة التطوير:
python setup.py develop
ما يميز مواجهته عن صناديق الرمل مثل Speakeasy و Qiling هو أن ذاكرة العملية الكاملة متوفرة. هذا يحسن الأداء لأنه يمكنك محاكاة أجزاء كبيرة من البرامج الضارة دون مغادرة يونيكورن. بالإضافة إلى ذلك ، يجب محاكاة Syscalls فقط لتوفير بيئة واقعية للنوافذ (نظرًا لأن كل شيء في الواقع هو بيئة عملية مشروعة).