繁体   English   中英

挂钩 Win API 调用 MessageBoxW

[英]Hooking Win API Call MessageBoxW

我正在尝试跳转挂钩 Windows function MessageBoxW并让我自己的 function 运行。 但是,我在这一行遇到了“访问冲突写入位置”:

*(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 ,它是一个无符号的 integer,与指针的大小相同。

编写 JMP 操作码是可行的,因为在这种情况下您不会将指针转换为std::uint32_t

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM