
PE 로더 및 Windows API 추적기. 악성코드 분석에 유용합니다.
이 프로젝트는 악성코드 분석 과정을 간소화하기 위해 만들어졌습니다. 목표는 사용자가 정의한 바이너리를 로드하고 Win32 API 후킹을 통해 실행을 모니터링하는 activator 바이너리를 생성하는 것입니다. 관련 데이터는 디스크에 저장됩니다. 이 코드는 x86 및 x64 바이너리를 모두 지원합니다.
작동 방식에 대한 블로그 게시물을 작성했습니다: http://antonioparata.blogspot.com/2022/06/thematrix-process-inspection-tool-aimed.html
새로운 바이너리를 모니터링하려면 activator를 생성해야 합니다. activator는 사용자가 입력한 바이너리를 로드하고 모니터링합니다. activator를 생성하려면 -add 옵션을 사용하세요. 사용 예는 다음과 같습니다:
c:\>TheMatrix.exe -add c:\path\to\my\binary.dll
Activator file created
c:\>regsvr32.exe TheMatrix.build.dll
이 명령은 activator를 나타내는 새로운 PE 파일을 생성합니다. activator는 입력 바이너리와 동일한 형식(DLL 또는 EXE)을 가집니다.
생성된 후에는 원하는 방식으로 실행하면 됩니다(DLL의 경우 rundll32.exe 유틸리티를 사용하는 것이 좋습니다).
실행 중 모니터링되는 함수에 의해 생성된 데이터는 **./Desktop/thematrix/[프로세스 ID]/**에 저장됩니다(이는 utility.c에 구현된 log_data 함수에 따라 달라집니다).
Limitation:
이 프로젝트는 특정 API(예: GetModuleHandle 등)가 올바르게 작동하도록 PEB.Ldr 구조를 수정합니다. WOW64 시스템(x64 OS에서 x86 바이너리)에서 activator를 실행하면 x86 _PEB.Ldr_만 수정됩니다(WOW64 프로세스는 x86 및 x64 PEB를 모두 가집니다). CPU가 x64로 전환되면 Windows 네이티브 API(ntdll.dll)가 x64 버전의 _PEB.Ldr_을 사용합니다. 이는 activator가 제대로 작동하지 않을 수 있음을 의미합니다. 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 함수에 대한 호출은 후크를 실행하는 동일한 스레드에서 수행되어야 하며, 그렇지 않으면 프로세스가 충돌합니다.