
PEローダーおよびWindows APIトレーサー。マルウェア解析に有用。
このプロジェクトはマルウェア解析プロセスを容易にするために作成されました。目的は、ユーザ定義のバイナリをロードし、Win32 APIフックを使用して実行を監視するアクティベータバイナリを作成することです。関連データはディスクに保存されます。コードはx86とx64の両方のバイナリをサポートしています。
動作の仕組みを説明したブログ記事を書きました: http://antonioparata.blogspot.com/2022/06/thematrix-process-inspection-tool-aimed.html
新しいバイナリを監視するには、アクティベータを作成する必要があります。アクティベータはユーザが入力したバイナリをロードして監視します。アクティベータを作成するには、-addオプションを使用します。使用例は次の通りです:
c:\>TheMatrix.exe -add c:\path\to\my\binary.dll
Activator file created
c:\>regsvr32.exe TheMatrix.build.dll
このコマンドにより、アクティベータを表す新しいPEファイルが作成されます。アクティベータは入力バイナリと同じ形式(DLLまたはEXE)になります。
作成後は、お好みの方法で実行できます(DLLの場合、推奨方法はrundll32.exeユーティリティを使用することです)。
実行中、監視対象の関数によって生成されたデータは ./Desktop/thematrix/[プロセスID]/ に保存されます(これはutility.cに実装されているlog_data関数に依存します)。
制限事項:
プロジェクトは、特定のAPI(_GetModuleHandle_など)が正しく動作するように_PEB.Ldr_構造を変更します。WOW64システム(x64 OS上のx86バイナリ)でアクティベータを実行すると、x86_PEB.Ldr_のみが変更されます(WOW64プロセスはx86とx64の両方のPEBを持ちます)。CPUがx64に切り替わると、WindowsネイティブAPI(ntdll.dll)はx64版の_PEB.Ldr_を使用します。そのため、アクティベータが正しく動作しない可能性があります。x86が確実に動作するようにするには、x86 OS上でバイナリを実行してください。
新しく作成されたファイルはすべてのメソッドをエクスポートせず、元のファイルリソースを含みません。これにより、例えばDLLが_GetModuleFileName_ -> LoadLibrary -> FindResource_を呼び出した場合にエラーが発生する可能性があります。このコードパスは、目的のリソースを含まない元の_TheMatrix DLLをロードします。
監視対象に新しい関数を追加するのは簡単です。hooks.cファイルでKernel32.dllとbcrypt.dllのフックの例を確認してください。新しいフックを追加するには、hook_add関数を呼び出せば十分です。以下にフック作成の例を示します:
LPVOID __stdcall hook_BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, VOID* pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG* pcbResult, ULONG dwFlags)
{
// save plain data
if (cbInput) {
char name[MAX_PATH] = { 0 };
snprintf(name, sizeof(name), "BCryptEncrypt_%llx_%d", (uint64_t)pbInput, cbInput);
log_data(cbInput, pbInput, name);
}
LPVOID ret = call_original(
hKey,
pbInput,
cbInput,
pPaddingInfo,
pbIV,
cbIV,
pbOutput,
cbOutput,
pcbResult,
dwFlags
);
return ret;
}
hook_add("Bcrypt.dll", "BCryptEncrypt", hook_BCryptEncrypt);
関数はフック対象の関数と同じシグネチャを持つ必要があります。call_original関数は元の関数を呼び出すために使用されます。元の関数の入力パラメータを渡してこの関数を呼び出すだけで、フレームワークが適切な関数を呼び出すためのすべての処理を行います ;)。call_original関数の呼び出しはフックを実行している同じスレッドで行う必要があります。そうしないとプロセスがクラッシュします。