-
-
[原创]发个StepInlineHook,跳过inline hook
-
发表于:
2014-2-26 17:04
3874
-
[原创]发个StepInlineHook,跳过inline hook
UINT StepInlineHook(HMODULE hMod);
本函数用于跳过对一些系统dll开头的mov edi,edi实现short jmp,long jmp 方式的hook。
原理:
一般系统函数开头指令一般是mov edi,edi,前面还有5个nop,这是为了方便inline hook设计的。
跳过这种HOOK的方式比较简单,判断函数头的前2个字节是否0xFF8B,或者第1字节为0x74,第3字节为0x55(已被inline hook)。
如果是的话把得到的函数地址+2即可跳过。但是这种方法仅适用于GetModuleHandle GetProcAddress方式调用函数。
StepInlineHook函数可以修改指定模块hMod的导入地址表,判断地址开头,如果条件成立,自动把Import Address Table的值+2。
返回的值是修改的函数数量。
源代码:
typedef union _OPDWORD
{
BYTE Byte[4];
WORD Word[2];
DWORD DWord;
} OPDWORD , *POPDWORD;
UINT StepInlineHook(HMODULE hMod)
{
UINT ic = 0;
UINT i = 0;
UINT j;
DWORD OldProtect;
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hMod;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE) return 0;
PIMAGE_NT_HEADERS pPeHeader = (PIMAGE_NT_HEADERS)((UINT)hMod + pDos->e_lfanew);
if (pPeHeader->Signature != IMAGE_NT_SIGNATURE) return 0;
if (pPeHeader->FileHeader.SizeOfOptionalHeader < 0xE0U) return 0;
PIMAGE_OPTIONAL_HEADER32 pOptHead = &pPeHeader->OptionalHeader;
PIMAGE_IMPORT_DESCRIPTOR pImpDir = (PIMAGE_IMPORT_DESCRIPTOR)((UINT)hMod + pOptHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if (!VirtualProtect((PVOID)((UINT)hMod + pOptHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
pOptHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, PAGE_EXECUTE_READWRITE, &OldProtect)) return 0;
PIMAGE_THUNK_DATA32 pThunk32;
POPDWORD pOpcode;
while (pImpDir[i].OriginalFirstThunk)
{
j = 0;
pThunk32 = (PIMAGE_THUNK_DATA32)((UINT)hMod + pImpDir[i].FirstThunk);
while (pThunk32[j].u1.Function)
{
pOpcode = (POPDWORD)pThunk32[j].u1.Function;
if (pOpcode->Word[0] == 0xFF8B || (pOpcode->Byte[0] == 0x74 && pOpcode->Byte[2] == 0x55))
{
pThunk32[j].u1.Function += 2;
ic++;
}
j++;
}
i++;
}
VirtualProtect((PVOID)((UINT)hMod + pOptHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
pOptHead->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, OldProtect, (DWORD *)&j);
return ic;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)