- 73
- 5
Помогите с реализацией кода на C для установки хука на функцию в DLL. Или может будут у кого-то уже готовые примеры
Я работаю над проектом, который включает установку хука на функцию в DLL, и я хотел бы переписать свой Lua скрипт на C. Мой Lua скрипт использует FFI для установки хука на функцию в `samp.dll`. Вот как он выглядит:
Мне нужно переписать этот код на C. В частности, я хочу:
1. Получать базовый адрес `samp.dll` с помощью `GetModuleHandle`.
2. Устанавливать и удалять хук на функцию в этой DLL.
3. Реализовать саму функцию хука на C.
Вот пример того, как я начал это делать на C:
Может кто-то помочь с завершением этого кода? Я хочу понять, как правильно использовать `VirtualProtect`, как корректно извлечь оригинальные байты и как управлять установкой и удалением хука.
Я работаю над проектом, который включает установку хука на функцию в DLL, и я хотел бы переписать свой Lua скрипт на C. Мой Lua скрипт использует FFI для установки хука на функцию в `samp.dll`. Вот как он выглядит:
Рабочий куд на луа для лука диалога:
local ffi = require("ffi")
ffi.cdef[[
int VirtualProtect(void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect);
]]
local hook = { hooks = {} }
function hook.new(cast, callback, hook_addr, size)
jit.off(callback, true)
local size = size or 5
local new_hook = {}
local detour_addr = tonumber(ffi.cast('intptr_t', ffi.cast('void*', ffi.cast(cast, callback))))
local void_addr = ffi.cast('void*', hook_addr)
local old_prot = ffi.new('unsigned long[1]')
local org_bytes = ffi.new('uint8_t[?]', size)
ffi.copy(org_bytes, void_addr, size)
local hook_bytes = ffi.new('uint8_t[?]', size, 0x90)
hook_bytes[0] = 0xE9
ffi.cast('uint32_t*', hook_bytes + 1)[0] = detour_addr - hook_addr - 5
new_hook.call = ffi.cast(cast, hook_addr)
new_hook.status = false
local function set_status(bool)
new_hook.status = bool
ffi.C.VirtualProtect(void_addr, size, 0x40, old_prot)
ffi.copy(void_addr, bool and hook_bytes or org_bytes, size)
ffi.C.VirtualProtect(void_addr, size, old_prot[0], old_prot)
end
new_hook.stop = function() set_status(false) end
new_hook.start = function() set_status(true) end
new_hook.start()
table.insert(hook.hooks, new_hook)
return setmetatable(new_hook, {
__call = function(self, ...)
self.stop()
local res = self.call(...)
self.start()
return res
end
})
end
local samp = getModuleHandle("samp.dll")
local str = ffi.string
local originalCDialog_Show
local CDialog_ShowPrototype = 'void(__thiscall*)(void*, int, int, const char*, const char*, const char*, const char*, bool)'
function CDialog_Show(this, nId, nType, szCaption, szText, szLeftButton, szRightButton, bServerside)
local caption = str(szCaption)
local text = str(szText)
local leftButton = str(szLeftButton)
local rightButton = str(szRightButton)
print("show dialog: ", nId, nType, caption, text, leftButton, rightButton, bServerside)
return originalCDialog_Show(this, nId, nType, szCaption, szText, szLeftButton, szRightButton, bServerside)
end
originalCDialog_Show = hook.new(CDialog_ShowPrototype, CDialog_Show, samp + 0x6B9C0)
Мне нужно переписать этот код на C. В частности, я хочу:
1. Получать базовый адрес `samp.dll` с помощью `GetModuleHandle`.
2. Устанавливать и удалять хук на функцию в этой DLL.
3. Реализовать саму функцию хука на C.
Вот пример того, как я начал это делать на C:
Код на си:
#include <windows.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
typedef void (__thiscall *CDialog_Show_t)(void*, int, int, const char*, const char*, const char*, const char*, int);
static CDialog_Show_t originalCDialog_Show = NULL;
static void* samp_base = NULL;
void set_hook(void* hook_addr, CDialog_Show_t new_func, size_t size) {
DWORD old_protect;
uint8_t* addr = (uint8_t*)hook_addr;
uint8_t org_bytes[5];
memcpy(org_bytes, addr, size);
uint8_t hook_bytes[5] = {0xE9};
*(uint32_t*)(hook_bytes + 1) = (uint32_t)((intptr_t)new_func - (intptr_t)hook_addr - 5);
VirtualProtect(hook_addr, size, PAGE_EXECUTE_READWRITE, &old_protect);
memcpy(addr, hook_bytes, size);
VirtualProtect(hook_addr, size, old_protect, &old_protect);
originalCDialog_Show = (CDialog_Show_t)org_bytes;
}
void __thiscall CDialog_Show(void* thisPtr, int nId, int nType, const char* szCaption, const char* szText, const char* szLeftButton, const char* szRightButton, int bServerside) {
printf("show dialog: %d %d %s %s %s %s %d\n", nId, nType, szCaption, szText, szLeftButton, szRightButton, bServerside);
originalCDialog_Show(thisPtr, nId, nType, szCaption, szText, szLeftButton, szRightButton, bServerside);
}
__declspec(dllexport) void init_hook(void* base_addr) {
samp_base = base_addr;
set_hook((void*)(samp_base + 0x6B9C0), CDialog_Show, 5);
}
Может кто-то помочь с завершением этого кода? Я хочу понять, как правильно использовать `VirtualProtect`, как корректно извлечь оригинальные байты и как управлять установкой и удалением хука.