bool CCallToolDlg::GetCallCountHook(PBYTE pModBaseAddr, PCHAR szExePath, HANDLE hProcess)
{
打开需分析的可执行文件…
设置文件读取游标为文件开始处…
读取文件内容到申请的内容…
用反汇编引擎反汇编文件内容,寻找call xxx、call [xxx]调用,并记录下总共call数量;
使用VirtualAllocEx(hProcess… 在进程内存中为每个call申请3个DWORD内存空间;
if
(申请成功)
{
…
BYTE shellcode[] =
{
0x60, 0x8D, 0x35, 0x24, 0x09, 0x3E, 0x00, 0x8B, 0x06, 0x40, 0x89, 0x06, 0x61, 0x68, 0x7E, 0x38, 0x00, 0x01, 0xE9, 0x30,
0x14, 0xC2, 0x00
};
while
(循环读取代码段)
{
用反汇编引擎反汇编…
寻找0xE8(call xxx)、0xFF 0x15(call [xxx])调用…
获得Call xxxx中xxxx内容…
把Call xxxx中xxxx内容由
"相对地址"
转换为
"绝对地址"
(在申请的内存中)…
加判断,防止把数据识别成代码,
RtlCopyMemory(CI.ShellCode, shellcode, 23);
//
把shellcode copy到结构体
*(PDWORD)(CI.ShellCode + 3) = pRemoteAddr + sizeof(DWORD) * 2;
//
赋值shellcode中的lea esi,dword ptr ds:[3E0924] 为目标进程dwCount位置
*(PDWORD)(CI.ShellCode + 0x0e) = dwCodeAddr + 5;
//
赋值shellcode中的push 100387E 为原Call的地址下一条指令[Call(0xE8)指令占字节]
*(PDWORD)(CI.ShellCode + 0x13) = dwTarget - (pRemoteAddr + sizeof(DWORD) * 4 + 0x12) - 5;
//
赋值shellcode中jmp 01001D73 计算跳转偏移(为原Call到shellcode的偏移)
WriteProcessMemory(hProcess, (LPVOID)pRemoteAddr, &CI, sizeof(CALL_INFO), &NumberOfBytes);
//
写入shellcode到申请的空间
更改Call Target 为JMP ShellCode…
}
}
关闭打开的文件…
}