Итак, я узнал о концепции перехвата и использования батутов для обхода / выполнения данных в функции перехвата WinAPI (в другом исполняемом файле с использованием инъекции DLL). Пока я знаю, как сделать это (батут и крюк), используя смесь сборки и C, но, похоже, я не могу сделать это просто с помощью C, так как мне что-то не хватает. Буду признателен, если кто-нибудь скажет мне, что я делаю не так и как это исправить.
Прямо сейчас мой код:
#include <Windows.h>
unsigned char* address = 0;
__declspec(naked) int __stdcall MessageBoxAHookTrampoline(HWND Window, char* Message, char* Title, int Type) {
__asm
{
push ebp
mov ebp, esp
mov eax, address
add eax, 5
jmp eax
}
}
int __stdcall MessageBoxAHook(HWND Window, char* Message, char* Title, int Type) {
wchar_t* WMessage = L"Hooked!";
wchar_t* WTitle = L"Success!";
MessageBoxW(0, WMessage, WTitle, 0);
return MessageBoxAHookTrampoline(Window, Message, Title, Type);
}
unsigned long __stdcall Thread(void* Context) {
address = (unsigned char*)GetProcAddress(LoadLibraryA("user32"), "MessageBoxA");
ULONG OP = 0;
if (VirtualProtect(address, 1, PAGE_EXECUTE_READWRITE, &OP)) {
memset(address, 0x90, 5);
*address = 0xE9;
*(unsigned long*)(address + 1) = (unsigned long)MessageBoxAHook - (unsigned long)address - 5;
}
else {
MessageBoxA(0, "Failed to change protection", "RIP", 0);
}
return 1;
}
// Entry point.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
CreateThread(0, 0, Thread, 0, 0, 0);
}
else if (fdwReason == DLL_PROCESS_DETACH) {
}
return true;
}
Итак, вопрос: как мне заставить функцию сказать
InstallHook
, которая установит крючок и вернет батут, чтобы я мог легко его использовать? Прототипом функции, вероятно, будет:void* InstallHook(void* originalFunc, void* targetFunc, int jumpsize)
, или так я понял, читая онлайн, но не уверен, для чегоjumpsize
будет использоваться.
Пока я знаю, что первые 5 байтов должны быть сохранены и восстановлены, а затем происходит переход к адресу исходной перехваченной функции. Поэтому мне пришлось бы использовать malloc для выделения памяти, memcpy для копирования байтов, 0xE9
- это значение инструкции перехода и тому подобное, но я просто не знаю, как реализовать это, используя только чистый C.