C API挂接使用JMP指令失败
我正在使用JMP指令拦截Win32函数调用,该指令在 我能够成功地将DLL注入进程地址空间,但无法用新函数截获调用。下面是注入到调用win32函数的进程中的DLL代码。它在“VirtualProtect2失败”时失败,错误代码为998(访问无效)。我在接听电话时有什么错误吗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
// 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或未指向有效变量,则函数失败。“