C API挂接使用JMP指令失败

C API挂接使用JMP指令失败,c,windows,winapi,hook,detours,C,Windows,Winapi,Hook,Detours,我正在使用JMP指令拦截Win32函数调用,该指令在 我能够成功地将DLL注入进程地址空间,但无法用新函数截获调用。下面是注入到调用win32函数的进程中的DLL代码。它在“VirtualProtect2失败”时失败,错误代码为998(访问无效)。我在接听电话时有什么错误吗 // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" #define SIZE 6 typedef

我正在使用JMP指令拦截Win32函数调用,该指令在

我能够成功地将DLL注入进程地址空间,但无法用新函数截获调用。下面是注入到调用win32函数的进程中的DLL代码。它在“VirtualProtect2失败”时失败,错误代码为998(访问无效)。我在接听电话时有什么错误吗

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

#define SIZE 6  
typedef HANDLE (WINAPI *pFindFirstFileA)(LPCSTR,LPWIN32_FIND_DATAA);  // Messagebox protoype
HANDLE WINAPI MyFindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);            // Our detour
 void BeginRedirect(LPVOID);                                        
 pFindFirstFileA pOrigMBAddress = NULL;                                // address of original
 BYTE oldBytes[SIZE] = {0};                                         // backup
 BYTE JMP[SIZE] = {0};                                              // 6 byte JMP instruction
 DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE; 

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        OutputDebugStringA("dll attach");
                 pOrigMBAddress = (pFindFirstFileA)                      
                 GetProcAddress(GetModuleHandleA("Kernel32.dll"),               // get address of original 
                       "FindFirstFileA");  
                 if(pOrigMBAddress != NULL) 
                 {
                    OutputDebugStringA("dll attach orig address is not null");
                   BeginRedirect(MyFindFirstFileA); 
                 }
                 else
                    OutputDebugStringA("dll attach orig address is null");
                 // start detouring
                 break;  
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
                memcpy(pOrigMBAddress, oldBytes, SIZE);                       // restore backup
        break;
    }
    return TRUE;
}

void BeginRedirect(LPVOID newFunction)  
{  
    OutputDebugStringA("dll beginredirect");
    BYTE tempJMP[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};         // 0xE9 = JMP 0x90 = NOP oxC3 = RET
    memcpy(JMP, tempJMP, SIZE);                                        // store jmp instruction to JMP
    DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);  // calculate jump distance
    bool ret = VirtualProtect((LPVOID)pOrigMBAddress, SIZE,                       // assign read write protection
           PAGE_EXECUTE_READWRITE, &oldProtect);  
    if(!ret)
        OutputDebugStringA("VirtualProtect1 failed");
    memcpy(oldBytes, pOrigMBAddress, SIZE);                            // make backup
    memcpy(&JMP[1], &JMPSize, 4);                              // fill the nop's with the jump distance (JMP,distance(4bytes),RET)
    memcpy(pOrigMBAddress, JMP, SIZE);                                 // set jump instruction at the beginning of the original function
    ret = VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
    if(!ret)
    {
        char str[200];
        sprintf(str,"VirtualProtect2 failed %d",GetLastError());
        OutputDebugStringA(str);
    }
    // reset protection
}

HANDLE WINAPI MyFindFirstFileA(LPCSTR lpFileName,LPWIN32_FIND_DATAA lpFindFileData) 
{  
    OutputDebugStringA("success hook");
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL);     // assign read write protection
    memcpy(pOrigMBAddress, oldBytes, SIZE);                            // restore backup
    HANDLE retValue = FindFirstFileA(lpFileName,lpFindFileData);       // get return value of original function
    memcpy(pOrigMBAddress, JMP, SIZE);                                 // set the jump instruction again
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);    // reset protection
    return retValue;                                                   // return original return value
} 

下面链接中对VirtualProtect的msdn描述说,如果lpfOldProtect参数为NULL,并且看起来您使用的是NULL,则VirtualProtect将失败

“LPFLOLPROTECT[输出] 指向一个变量的指针,该变量在指定的页面区域中接收第一页以前的访问保护值。如果此参数为NULL或未指向有效变量,则函数失败。