|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 dycc 于 2013-4-29 07:55 编辑
根据《windows程序设计》中书上的演示代码,可以实现通过对目标模块导入表的覆盖实现对某AIP的拦截,然后调用自定义的函数。
在VC++6.0编译器上的debug版本程序能够实现正常覆盖,但是编译成release版本就会出现在hook函数中覆盖掉而且会正确hook掉目标API,但是返回到主函数后就无法实现拦截,而是再次还原成目标API的真实地址,也不会导致崩溃,hook函数返回后能正常调用真正的目标API,这样就没有实现hook函数的功能,为什么会有这种现象?代码是书上的没错,思路也没错,但还是有这种现象,换到XP下运行也有这种现象,不知道是什么问题以及如何解决,请大大们解答下,不胜感激!!!
这是release版本
这是debug版本
- #include <windows.h>
- #include <stdio.h>
- // 挂钩指定模块hMod对MessageBoxA的调用
- BOOL SetHook(HMODULE hMod);
- // 定义MessageBoxA函数原型
- typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
- // 保存MessageBoxA函数的真实地址
- PROC g_orgProc = (PROC)MessageBoxA;
- void main()
- {
- // 调用原API函数
- ::MessageBox(NULL, "原函数", "09HookDemo", 0);
- // 挂钩后再调用
- printf("覆盖前主函数MessageBoxA地址:\n%x\n",(PROC)MessageBoxA);
- SetHook(::GetModuleHandle(NULL));
- GetProcAddress(::GetModuleHandle(NULL),);
- ::MessageBox(NULL, "原函数", "09HookDemo", 0);
- }
- // 用于替换MessageBoxA的自定义函数
- int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
- {
- return ((PFNMESSAGEBOX)g_orgProc)(hWnd, "新函数", "09HookDemo", uType);
- }
- BOOL SetHook(HMODULE hMod)
- {
- IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;
- IMAGE_OPTIONAL_HEADER * pOptHeader =
- (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);
-
- IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)
- ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
- // 在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出
- while(pImportDesc->FirstThunk)
- {
- char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name);
复制代码- if(lstrcmpiA(pszDllName, "user32.dll") == 0)
复制代码- {
- break;
- }
- pImportDesc++;
- }
- if(pImportDesc->FirstThunk)
- {
- // 一个IMAGE_THUNK_DATA就是一个双字,它指定了一个导入函数
- // 调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组
- IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hMod + pImportDesc->FirstThunk);
- while(pThunk->u1.Function)
- {
- // lpAddr指向的内存保存了函数的地址
- DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function);
- if(*lpAddr == (DWORD)g_orgProc)
- {
- printf("覆盖前自定义函数中保存MessageBoxA地址的地址与MessageBoxA的地址:\n%x %x\n",lpAddr,*lpAddr);
- DWORD dwOldProtect;
- MEMORY_BASIC_INFORMATION mbi;
- VirtualQuery(lpAddr,&mbi,sizeof(mbi));
- VirtualProtect(lpAddr,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldProtect);
- // 修改IAT表项,使其指向我们自定义的函数,相当于“*lpAddr = (DWORD)MyMessageBoxA;”
- DWORD* lpNewProc = (DWORD*)MyMessageBoxA;
- ::WriteProcessMemory(::GetCurrentProcess(),
- lpAddr, &lpNewProc, sizeof(DWORD), NULL);
- printf("覆盖后自定义函数中保存MessageBoxA地址的地址与MessageBoxA的地址:\n%x %x\n",lpAddr,*lpAddr);
- printf("覆盖后自定义函数中MessageBoxA地址:\n%x\n",(PROC)MessageBoxA);
- ::MessageBox(NULL, "原函数", "09HookDemo", 0);
- VirtualProtect(lpAddr,sizeof(DWORD),dwOldProtect,0);
- return TRUE;
- }
- pThunk++;
- }
- }
- return TRUE;
- }
复制代码
|
|