尝试挂钩“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

在回调函数中使用 setState 挂钩时反应过多的重新渲染

挂钩 ExtTextOut 会返回意外结果

自定义帖子类型动作挂钩/瞬态

无效的挂钩调用。钩子只能在使用 react-apollo 的函数组件内部调用