尝试挂钩“TerminateProcess”功能时出错。目标进程崩溃。谁能帮我?

时间:2010-04-14 07:32:05

标签: c++ windows winapi

使用visual studio 2005进行调试显示以下错误:procexp.exe中0x00000000处的未处理异常:0xC0000005:访问冲突读取位置0x00000000。

和线程信息:

  

2704 Win32 Thread 00000000 Normal 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  push        0         
004118B0  mov         eax,dword ptr [hProc]     
004118B3  push        eax        
004118B4  call        dword  ptr[__imp__TerminateProcess@8(4181E4h)]   
004118BA  cmp         esi,esp  // esi is zero.why ?   

2 个答案:

答案 0 :(得分:0)

不要自己写这种代码。使用Microsoft Research的{​​{3}}。

答案 1 :(得分:0)

什么是VDLL2_API定义为?它可能会干扰调用约定(对于此函数而言,这意味着是WINAPI,因为稍后在同一行上写它)。

退出时的堆栈问题(ESI,ESP)通常表示您的调用约定混淆了。您似乎在其他地方始终使用FARPROC,但由于您知道函数的确切原型,请尝试typedef - 将其作为要使用的类型:

typedef BOOL (WINAPI *TERMINATEPROCESS_PROC)(HANDLE, UINT); 

现在在任何地方使用TERMINATEPROCESS_PROC代替FARPROC