WriteProcessMemory 在函数内部失败

WriteProcessMemory fails inside function

本文关键字:失败 内部 函数 WriteProcessMemory      更新时间:2023-10-16

嗨,我是函数挂钩的新手,我正在使用一篇文章中的代码。

这是我的代码

#include <windows.h>
#include <iostream>
FARPROC messageBoxAddress = NULL;
SIZE_T bytesWritten = 0;
unsigned char messageBoxOriginalBytes[6] = { } ;
int __stdcall HookedMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) {
printf("la la la ");
printf("n");
WriteProcessMemory(GetCurrentProcess(), (LPVOID)messageBoxAddress, messageBoxOriginalBytes, sizeof(messageBoxOriginalBytes), &bytesWritten);
return MessageBoxA(NULL, lpText, lpCaption, MB_OK);
}

int main()
{
SIZE_T bytesRead = 0; 
HINSTANCE library = LoadLibraryA("user32.dll");
FARPROC messageBoxAddress =GetProcAddress(library, "MessageBoxA");
ReadProcessMemory(GetCurrentProcess(), messageBoxAddress, messageBoxOriginalBytes, 6, &bytesRead);
void* hookedMessageBoxAddress = &HookedMessageBox;
char patch[6] = { 0 };
memcpy_s(patch, 1, "x68", 1);
memcpy_s(patch + 1, 4, &hookedMessageBoxAddress, 4);
memcpy_s(patch + 5, 1, "xC3", 1);

WriteProcessMemory(GetCurrentProcess(), (LPVOID)messageBoxAddress, patch, sizeof(patch), &bytesWritten);

MessageBoxA(NULL, "hello", "Welcome", MB_OK);
return 0;
}

输出

la la la
la la la
la la la
la la la
la la la
la la la
la la la

问题是我只想要一个啦啦啦

这显示一千个啦啦啦

int main( ( 中的 WriteProcessMemory 可以工作,但 'HookedMessageBox' 里面的

内存不起作用。有人可以指出我的解决方法吗

我也想坚持基础知识。有图书馆绕道等。但是坚持基本帮助我理解它。

我试图使用 GetLastError(( 获取错误,它显示 998 表示访问被拒绝(在网上搜索(

这称为钩子递归,为了解决这个问题,你需要使用蹦床钩子。

蹦床钩就像一个普通的绕道,它会跳到你的代码,但随后它会按照你的实际jmp指令跳回到地址,这样它就不会一遍又一遍地执行你的代码。

在内部工作时,你不需要使用 WriteProcessMemory((,你不应该修改钩子内部的钩子。

这是我对您的问题的解决方案,它使用蹦床钩子,希望有一些更有意义的代码:

#include <iostream>
#include <Windows.h>
bool Detour32(char* src, char* dst, const intptr_t len)
{
if (len < 5) return false;
DWORD  curProtection;
VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &curProtection);
intptr_t  relativeAddress = (intptr_t)(dst - (intptr_t)src) - 5;
*src = (char)'xE9';
*(intptr_t*)((intptr_t)src + 1) = relativeAddress;
VirtualProtect(src, len, curProtection, &curProtection);
return true;
}
char* TrampHook32(char* src, char* dst, const intptr_t len)
{
// Make sure the length is greater than 5
if (len < 5) return 0;
// Create the gateway (len + 5 for the overwritten bytes + the jmp)
void* gateway = VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//Write the stolen bytes into the gateway
memcpy(gateway, src, len);
// Get the gateway to destination addy
intptr_t  gatewayRelativeAddr = ((intptr_t)src - (intptr_t)gateway) - 5;
// Add the jmp opcode to the end of the gateway
*(char*)((intptr_t)gateway + len) = 0xE9;
// Add the address to the jmp
*(intptr_t*)((intptr_t)gateway + len + 1) = gatewayRelativeAddr;
// Perform the detour
Detour32(src, dst, len);
return (char*)gateway;
}
typedef int(__stdcall* tMessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
tMessageBoxA oMessageBoxA = nullptr;
int __stdcall hkMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
lpText = "hax0red";
return oMessageBoxA(hWnd, lpText, lpCaption, uType);
}
int main()
{
oMessageBoxA = (tMessageBoxA)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
oMessageBoxA = (tMessageBoxA)TrampHook32((char*)oMessageBoxA, (char*)hkMessageBoxA, 5);
MessageBoxA(NULL, "Body Message", "Title Here", MB_OK);
return 0;
}

谢谢@GuidedHacking,我终于做了一个 64 的工作代码。

更名为Detour64和TrampHook64。

#include <iostream>
#include <Windows.h>
bool Detour64(char* src, char* dst, const intptr_t len)
{
if (len < 12) return false;
DWORD  curProtection;
VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &curProtection);
intptr_t  absoluteAddress = (intptr_t)(dst);
*src = (char)'x48';
*(src + 1) = (char)'xb8';
*(src + 2) = absoluteAddress % 256;
*(src + 3) = (absoluteAddress/256) % 256;
*(src + 4) = (absoluteAddress/65536) % 256;
*(src + 5) = (absoluteAddress/(65536*256)) % 256;
*(src + 6) = (absoluteAddress/((long long)65536*65536)) % 256;
*(src + 7) = (absoluteAddress/((long long)65536*65536*256)) % 256;
*(src + 8) = (absoluteAddress/((long long)65536*65536*65536))%256;
*(src + 9) = (absoluteAddress/((long long)65536*65536*65536*256)) % 256;
*(src + 10) = (char)'xff';
*(src + 11) = (char)'xe0';
VirtualProtect(src, len, curProtection, &curProtection);
return true;
}
char* TrampHook64(char* src, char* dst, const intptr_t len)
{
// Make sure the length is greater than 5
if (len < 12) return 0;
// Create the ga+teway (len + 5 for the overwritten bytes + the jmp)
void* gateway = VirtualAlloc(0, len + 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//Write the stolen bytes into the gateway
memcpy(gateway, src, len);
// Get the gateway to destination addy
intptr_t  gatewayAbsoluteAddr = (intptr_t)src+len;    
// Add the jmp opcode to the end of the gateway
*((char*)gateway + len) = 0xFF;
*((char*)gateway + len + 1) = 0x25;
*((char*)gateway + len + 2) = 0;
*((char*)gateway + len + 3) = 0;
*((char*)gateway + len + 4) = 0;
*((char*)gateway + len + 5) = 0;
// Add the address to the jmp
*((char*)gateway + len + 6) = gatewayAbsoluteAddr % 256;
*((char*)gateway + len + 7) = (gatewayAbsoluteAddr / 256) % 256;
*((char*)gateway + len + 8) = (gatewayAbsoluteAddr / 65536) % 256;
*((char*)gateway + len + 9) = (gatewayAbsoluteAddr / (65536 * 256)) % 256;
*((char*)gateway + len + 10) = (gatewayAbsoluteAddr / ((long long)65536 * 65536)) % 256;
*((char*)gateway + len + 11) = (gatewayAbsoluteAddr / ((long long)65536 * 65536 * 256)) % 256;
*((char*)gateway + len + 12) = (gatewayAbsoluteAddr / ((long long)65536 * 65536 * 65536)) % 256;
*((char*)gateway + len + 13) = (gatewayAbsoluteAddr / ((long long)65536 * 65536 * 65536 * 256)) % 256;

// Perform the detour
Detour64(src, dst, len);
return (char*)gateway;
}
typedef int(__stdcall* tMessageBoxA)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
tMessageBoxA oMessageBoxA = nullptr;
int __stdcall hkMessageBoxA(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{

lpText = LPCTSTR("hax0red");

return oMessageBoxA(hWnd, lpText, lpCaption, uType);
}
int main()
{
HINSTANCE libr = LoadLibrary(L"User32.dll");

oMessageBoxA = (tMessageBoxA)GetProcAddress(libr, "MessageBoxA");
oMessageBoxA = (tMessageBoxA)TrampHook64((char*)oMessageBoxA, (char*)hkMessageBoxA, 14);

MessageBoxA(NULL, "Body Message", "Title Here", MB_OK);
return 0;
}

希望它总是正确的。

有关@GuidedHacking代码的小但关键信息。请务必"测量"您传递的钩子长度,它并不总是 5,取决于您的原始函数具有的指令,它可能是 5,可能是 6,等等,您可以在 IDA 中看到它并输入正确的大小