前几天看书 看到对自己的API hook 我就有感而发 能不能对不同的API HOOK 比如Sleep 然后我就写了这篇博客 vc++ 可以编译 其实也可以用 钩子直接写的(如果不想用汇编的话)(函数的调用方式不一样 要改的) 其中内容参考了 郁金香教学视频
感谢郁金香老师!
#include <windows.h>
#include "stdafx.h"
//函数调用结束后由被调用函数清除栈内数据。
VOID __stdcall mySleep(DWORD m)
{
MessageBoxA(0,"Hook 成功","IAT hook",MB_OK);
}
PVOID EnumAPI()
{
PBYTE ImageBase;
PIMAGE_THUNK_DATA r;
PIMAGE_NT_HEADERS pNtHeader;
PIMAGE_IMPORT_DESCRIPTOR pImport;
//取得DOS头基址
ImageBase=(PBYTE)GetModuleHandle(NULL);//0x400000
//PE头=ImageBase+[ImageBase+3c]
pNtHeader = (PIMAGE_NT_HEADERS) (ImageBase + ((PIMAGE_DOS_HEADER) ImageBase)->e_lfanew);
//IMAGE_DIRECTORY_ENTRY_IMPORT值为1 表示import tabale
pImport = (PIMAGE_IMPORT_DESCRIPTOR)
(ImageBase + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
遍历整个 输入表
for (; pImport->Name; pImport++)
{
printf("导入模块:%s\n",ImageBase+pImport->Name);
//遍历IAT信息 PIMAGE_THUNK_DATA基址
for (r = (PIMAGE_THUNK_DATA) (ImageBase + pImport->FirstThunk); r->u1.Function; r++) //枚举函数地址
{
if (Sleep==(PVOID)r->u1.Function)
{
DWORD pSleep=(DWORD)(&r->u1.Function);
__asm
{
push eax
push ebx
mov ebx,pSleep /// mov ebx,0x42A190
lea eax,mySleep
mov [ebx],eax
pop ebx
pop eax
}
//内嵌汇编 也可以用 WriteProcessMemmory 函数
//更严谨点应该改变页属性
}
printf("Function=%x \n", &(r->u1.Function));
}
}
return NULL;
}
int main(int argc, char* argv[])
{ //MessageBoxA(0,NULL,NULL,MB_OK) ;
//MessageBoxW(0,NULL,NULL,MB_OK);
EnumAPI();
Sleep(111);
return 0;
}