簡體   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