Posted on 2006-10-28 20:05
紫雨轩 C++ 阅读(1631)
评论(1) 编辑 收藏 引用
详细说明《Windows 核心编程》中有。贴段代码,我写得比他写得简洁多了。自己会查找 Image Import descriptor 的地址,而不像书中所用的调用 ImageHlp.dll 或者 DbgHelp.dll 中的函数 ImageDirectoryToData 来实现。为了使用一些 PE 结构类型,请 #include (不会导入他的函数)。
使用方法:
HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MessageBox, MyMessageBox);
取消Hook:
HookAPI((PBYTE) GetModuleHandle(NULL), "User32.dll", MyMessageBox, MessageBox);
原本以为用这种方法能 Hook User32.dll 中的 SetScrollInfo 实现 ClassXP 自绘 Scroll 的。因为需要 HookAPI((PBYTE) GetModuleHandle("User32.dll"), "User32.dll", SetScrollInfo, MySetScrollInfo) ,后来发现 User32.dll 根本不是导入自己的函数,而是直接调用——早该想到了,晕死!
所以替换 IAT 方法 Hook,还是有限制的,没办法在ClassXP中使用:(只好替换SetScrollInfo的入口点代码了:(
PVOID HookAPI(PBYTE pbModule, PCSTR pszName, PVOID pvOrg, PVOID pvNew)
{
PIMAGE_THUNK_DATA r;
PIMAGE_NT_HEADERS p;
PIMAGE_IMPORT_DESCRIPTOR q;
p = (PIMAGE_NT_HEADERS) (pbModule + ((PIMAGE_DOS_HEADER) pbModule)->e_lfanew);
q = (PIMAGE_IMPORT_DESCRIPTOR) (pbModule + p->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (; q->Name; q++)
{
if (lstrcmpiA(pszName, (PCSTR) (pbModule + q->Name)) == 0)
{
for (r = (PIMAGE_THUNK_DATA) (pbModule + q->FirstThunk); r->u1.Function; r++)
{
if ((PVOID) r->u1.Function == pvOrg)
{
WriteProcessMemory(GetCurrentProcess(), &r->u1.Function, &pvNew, sizeof(PVOID), NULL);
return pvOrg;
}
}
}
}
return NULL;
}
下面是替换函数入口的方法,只能用于X86的平台中,尚不完善。 PVOID HookApi(PVOID pvOrg, PVOID pvNew) { DWORD dwProtect; if (VirtualProtect(pvOrg, 16, PAGE_READWRITE, &dwProtect)) { PBYTE p = (PBYTE) pvOrg; PDWORD q = (PDWORD) (p + 1); *p = 0xE9; *q = (LONG) pvNew - (LONG) (p + 5); VirtualProtect(pvOrg, 16, dwProtect, &dwProtect); return pvOrg; } return NULL; }