尝试挂钩“TerminateProcess”函数时出错。目标进程崩溃。谁能帮我?
Posted
技术标签:
【中文标题】尝试挂钩“TerminateProcess”函数时出错。目标进程崩溃。谁能帮我?【英文标题】:Error while Trying to Hook "TerminateProcess" Function. Target Process crashes. Can anyone help me? 【发布时间】:2011-02-07 19:13:34 【问题描述】:使用 Visual Studio 2005 进行调试显示以下错误:
procexp.exe 中 0x00000000 处未处理的异常:0xC0000005:访问 违规读取位置0x00000000。
和线程信息:
2704 Win32 线程 00000000 正常 0
extern "C" VDLL2_API BOOL WINAPI MyTerminateProcess(HANDLE hProcess,UINT uExitCode)
SetLastError(5);
return FALSE;
FARPROC HookFunction(char *UserDll,FARPROC pfn,FARPROC HookFunc)
DWORD dwSizeofExportTable=0;
DWORD dwRelativeVirtualAddress=0;
HMODULE hm=GetModuleHandle(NULL);
FARPROC pfnOriginalAddressToReturn;
PIMAGE_DOS_HEADER pim=(PIMAGE_DOS_HEADER)hm;
PIMAGE_NT_HEADERS pimnt=(PIMAGE_NT_HEADERS)((DWORD)pim +
(DWORD)pim->e_lfanew);
PIMAGE_DATA_DIRECTORY
pimdata=(PIMAGE_DATA_DIRECTORY)&(pimnt->OptionalHeader.DataDirectory);
PIMAGE_OPTIONAL_HEADER pot=&(pimnt->OptionalHeader);
PIMAGE_DATA_DIRECTORY
pim2=(PIMAGE_DATA_DIRECTORY)((DWORD)pot+(DWORD)104);
dwSizeofExportTable=pim2->Size;
dwRelativeVirtualAddress=pim2->VirtualAddress;
char *ascstr;
PIMAGE_IMPORT_DESCRIPTOR
pimexp=(PIMAGE_IMPORT_DESCRIPTOR)(pim2->VirtualAddress + (DWORD)pim);
while(pimexp->Name)
ascstr=(char *)((DWORD)pim + (DWORD)pimexp->Name);
if(strcmpi(ascstr,UserDll) == 0)
break;
pimexp++;
PIMAGE_THUNK_DATA
pname=(PIMAGE_THUNK_DATA)((DWORD)pim+(DWORD)pimexp->FirstThunk);
LPDWORD lpdw=&(pname->u1.Function);
DWORD dwError=0;
DWORD OldProtect=0;
while(pname->u1.Function)
if((DWORD)pname->u1.Function == (DWORD)pfn)
lpdw=&(pname->u1.Function);
VirtualProtect((LPVOID)lpdw,sizeof(DWORD),PAGE_READWRITE,&OldProtect);
pname->u1.Function=(DWORD)HookFunc;
VirtualProtect((LPVOID)lpdw,sizeof(DWORD),PAGE_READONLY,&OldProtect);
return pfn;
pname++;
return (FARPROC)0;
FARPROC CallHook(void)
HMODULE hm=GetModuleHandle(TEXT("Kernel32.dll"));
FARPROC fp=GetProcAddress(hm,"TerminateProcess");
HMODULE hm2=GetModuleHandle(TEXT("vdll2.dll"));
FARPROC fpHook=GetProcAddress(hm2,"MyTerminateProcess");
dwAddOfTerminateProcess=HookFunction("Kernel32.dll",fp,fpHook);
if(dwAddOfTerminateProcess == 0)
MessageBox(NULL,TEXT("Unable TO Hook Function."),TEXT("Parth"),MB_OK);
else
MessageBox(NULL,TEXT("Success Hooked."),TEXT("Parth"),MB_OK);
return 0;
提前感谢您的帮助。
004118AC mov esi,esp 004118AE推0 004118B0 mov eax,dword ptr [hProc] 004118B3 推eax 004118B4 调用 dword ptr[__imp__TerminateProcess@8(4181E4h)] 004118BA cmp esi,esp
esi
返回零。为什么 ?
【问题讨论】:
【参考方案1】:VDLL2_API 定义为什么?它可能会干扰调用约定(这意味着该函数的 WINAPI,因为您稍后在同一行上编写它)。
退出时的堆栈问题(ESI、ESP)通常表明您的调用约定混淆了。您似乎在其他任何地方一直使用FARPROC
,但由于您知道该函数的确切原型,请尝试使用typedef
-ing 作为替代类型:
typedef BOOL (WINAPI *TERMINATEPROCESS_PROC)(HANDLE, UINT);
现在到处使用TERMINATEPROCESS_PROC
,而不是FARPROC
。
【讨论】:
【参考方案2】:不要自己编写这种代码。使用来自 Microsoft Research 的 Detours library。
【讨论】:
我知道我不应该自己写这种代码。但我是出于实验目的而编写它,并看到我能够编写这种代码。我想知道程序中的错误。无论如何,谢谢你回答我的问题。 如果你不知道如何调试,你就写不出这样的代码。也许它应该是实验的一部分。其他人为您调试此代码并不能帮助您将来编写和调试此类代码。祝你好运! 我知道如何调试这种程序,最近两天一直在调试它。但是我没有发现任何错误,所以我在 *** 中询问。无论如何,我在调试过程中发现了一些有趣的信息,这些信息已添加到问题中。看一看。 编译器期望被调用函数保留esi寄存器的值。重定向功能不会发生这种情况。不知道为什么,看一下替换函数的汇编代码。编译器可能已经对其进行了优化,通过寄存器传递参数。因为它可能没有外部链接。 Detours 4 自 2016 年起在 MIT 许可下发布,覆盖在 the faq。以上是关于尝试挂钩“TerminateProcess”函数时出错。目标进程崩溃。谁能帮我?的主要内容,如果未能解决你的问题,请参考以下文章
ExitProcess,TerminateProcess,CreateToolhelp32Snapshot,Process32First,Process32Next,OpenProcess