我正在使用JMP interception
中给出的JMP指令拦截Win32函数调用我能够成功地将DLL注入进程地址空间但无法使用新函数拦截调用。这是DLL代码,它被注入到调用win32函数的进程中。它在“VirtualProtect2 failed”时失败,错误代码为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
}
答案 0 :(得分:0)
下面链接中的VirtualProtect的msdn描述表明,如果lpfOldProtect参数为NULL并且看起来你正在使用NULL,则VirtualProtect会失败。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx
“lpflOldProtect [out] 指向变量的指针,该变量接收指定页面区域中第一页的先前访问保护值。 如果此参数为NULL或未指向有效变量,则函数将失败。“