注:これは進行中のプロトタイプです。そのように扱ってください。プルリクエストは大歓迎です!あなたは良い最初の問題であなたの足を濡らすことができます
Minidumpファイルでコードをエミュレートするための使いやすいライブラリ。 Dumpulatorを使用した投稿/ビデオへのリンクを次に示します。
ここにあなたの記事を追加するためのプルリクエストをお気軽に送ってください!
以下の例は、 StringEncryptionFun_x64.dmp (こちらのコピーをダウンロード)を開き、いくつかのメモリを割り当て、 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]
Prologを実行して、いくつかのレジスタを設定するだけです。
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デコレーターを使用して、syscallsを(再)実装できます。
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にあります。 APIの使用方法については、多くの例もあります。
既存の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 2番目の引数としてポインター値を渡すと、構造はメモリから読み取られます。 myptr: P[MY_STRUCT]を使用してポインターを宣言し、 myptr[0]で宣言することができます。
Minidumppluginと呼ばれる単純なX64DBGプラグインがありますMinidumpコマンドは、2022-10-10からx64dbgに統合されています。ダンプを作成するには、実行を一時停止し、コマンドMiniDump my.dmpを実行します。
Pypiから(最新リリース):
python -m pip install dumpulator
ソースからインストールするには:
python setup.py install
開発環境へのインストール:
python setup.py develop
SpeakeasyやQilingのようなサンドボックスと脱落器を際立たせるのは、完全なプロセスメモリが利用可能であることです。これにより、ユニコーンを離れることなくマルウェアの大部分をエミュレートできるため、パフォーマンスが向上します。さらに、現実的なWindows環境を提供するために、Syscallをエミュレートする必要があります(実際にはすべてが正当なプロセス環境であるため)。