Hooking Win API Call MessageBoxW



我正试图跳过Windows函数MessageBoxW,让我自己的函数运行。然而,我遇到了一个"访问违规"写入位置。在这一行:

*(reinterpret_cast <std::uint32_t*>(reinterpret_cast<std::uint32_t>(hook_addr) + 1)) = rel_addr;

下面是我的程序代码:

#include "Windows.h"
#include <cstdint>
#include <cstring>
#include <iostream>
#include <string> 
using namespace std;
int hookedFunc(void* thisptr, void* not_edx, HWND hWnd, LPCSTR lpText, LPCWSTR lpCaption, UINT uType) {
cout << "Hooked function called";
return MessageBoxW(NULL, L"HOOKED BOX", L"HOOKED CAPTION", MB_YESNOCANCEL);
}
std::uint32_t tramp_hook(void* hook_addr, void* new_func, std::uint32_t instr_size)
{
constexpr auto jmp_instr_size = 5; // minimum size required for a JMP instruction

DWORD vp_old_prot{ 0u };
VirtualProtect(hook_addr, instr_size, PAGE_EXECUTE_READWRITE, &vp_old_prot); // In order to overwrite code, we need proper access.
std::memset(hook_addr, 0x90, instr_size); // setting the bytes we will overwrite to 0x90 / nop ( no operation )

const auto rel_addr = (reinterpret_cast<std::uint32_t>(new_func) - reinterpret_cast<std::uint32_t>(hook_addr)) - jmp_instr_size; // relative address calculation. in a relative jmp / call, the result of this calculation will be used by the CPU to add to the EIP ( instruction pointer ).

*(static_cast<std::uint8_t*>(hook_addr)) = 0xE9; // overwriting a byte to the JMP opcode ( 0xE9 )
// problem
*(reinterpret_cast <std::uint32_t*>(reinterpret_cast<std::uint32_t>(hook_addr) + 1)) = rel_addr; // setting the result of our relative address calculation as the relative jmp operand.

VirtualProtect(hook_addr, instr_size, vp_old_prot, nullptr); // resetting our access
return reinterpret_cast<std::uint32_t>(hook_addr) + 5; // returning the address next instruction to be executed to be used later
}
typedef int (__fastcall* MESSAGEBOXW)(void* thisptr, void* not_edx, HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

MESSAGEBOXW hookedBox = reinterpret_cast<MESSAGEBOXW>(&hookedFunc);
int main() {
MessageBoxW(NULL, L"not hooked", L"this is the caption", MB_YESNO);
HMODULE dllHandl = LoadLibrary(L"user32.dll");
void* msgBoxAddr = GetProcAddress(dllHandl, "MessageBoxW");
cout << hookedBox << endl;
tramp_hook(msgBoxAddr, hookedBox, 5);
MessageBoxW(NULL, L"not hooked 2", L"this is the caption", MB_YESNO);
}

有人能解释一下发生了什么吗?我可以设置nop字节并编写JMP代码,但是当设置相对地址计算时,会发生访问冲突。

我已经检查了第一个VirtualProtect的返回值;它不是非零的,所以一切都很好。

我的水晶球说你正在编译你的程序为64位,所以当你强制指针进入std::uint32_t时,它会切断地址的前32位,现在你有一个无效的指针。

当你把指针当作一个数字时,你应该使用std::uintptr_t,它是一个无符号整数,大小与指针的大小相同。

写JMP操作码是有效的,因为在这种情况下你不会将指针强制转换为std::uint32_t

最新更新