 |

04.09.2024, 14:40
|
|
Познающий
Регистрация: 20.02.2021
Сообщений: 74
С нами:
2751726
Репутация:
8
|
|
Помогите с реализацией кода на C для установки хука на функцию в DLL. Или может будут у кого-то уже готовые примеры
Я работаю над проектом, который включает установку хука на функцию в 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
#include
#include
#include
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`, как корректно извлечь оригинальные байты и как управлять установкой и удалением хука.
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|