-
Notifications
You must be signed in to change notification settings - Fork 1
/
inline_hook.hpp
118 lines (90 loc) · 2.58 KB
/
inline_hook.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Repository: https://github.com/git-xiaocao/inline_hook
// Author: 小草
// Date: 2023/1/16
#pragma once
#include <Windows.h>
#include <functional>
#ifdef _WIN64
// mov rax, addr
// push rax,
// ret
constexpr SIZE_T byte_code_length = 2 + 2 + sizeof(LONG_PTR);//12
#else
// jmp addr
constexpr SIZE_T byte_code_length = 1 + sizeof(LONG_PTR);//5
#endif
template<typename F>
class InlineHook
{
private:
//原始函数字节码
BYTE original_bytes_[byte_code_length];
//asm jmp 字节码
BYTE jmp_bytes_[byte_code_length];
// 原始地址
ULONG_PTR original_address_;
// 目标地址
ULONG_PTR self_address_;
F original_func_;
DWORD MotifyMemoryAttributes(ULONG_PTR address, DWORD attributes = PAGE_EXECUTE_READWRITE)
{
DWORD old_attributes;
VirtualProtect(reinterpret_cast<void*>(address), byte_code_length, attributes, &old_attributes);
return old_attributes;
}
public:
InlineHook(ULONG_PTR original_address, F self_func)
{
original_func_ = reinterpret_cast<F>(original_address);
original_address_ = original_address;
self_address_ = reinterpret_cast<ULONG_PTR>(self_func);
#ifdef _WIN64
//mov rax
jmp_bytes_[0] = 0x48;
jmp_bytes_[1] = 0xB8;
*(PLONG_PTR)(jmp_bytes_ + 2) = self_address_;
//push rax
//ret
*(PBYTE)(jmp_bytes_ + 2 + sizeof(self_address_)) = 0x50;
*(PBYTE)(jmp_bytes_ + 2 + sizeof(LONG_PTR) + 1) = 0xC3;
#else
//计算偏移
LONG_PTR offset = self_address_ - (original_address_ + byte_code_length);
//jmp offset
jmp_bytes_[0] = 0xE9;
*(PLONG_PTR)(jmp_bytes_ + 1) = offset;
#endif
//修改内存属性
DWORD attributes = MotifyMemoryAttributes(original_address_);
//保存原始函数地址的字节码
RtlCopyMemory(original_bytes_, reinterpret_cast<PBYTE>(original_address_), byte_code_length);
//恢复内存属性
MotifyMemoryAttributes(original_address_, attributes);
}
~InlineHook() {
Restore();
}
//调用原始函数
template<typename... Args>
auto CallOriginalFunc(Args&&... args) {
Restore();
auto result = original_func_(std::forward<Args>(args)...);
Motify();
return result;
}
//修改地址
void Motify()
{
DWORD attributes = MotifyMemoryAttributes(original_address_);
//写入字节码
RtlCopyMemory(reinterpret_cast<PBYTE>(original_address_), jmp_bytes_, byte_code_length);
MotifyMemoryAttributes(original_address_, attributes);
}
//恢复字节码
void Restore()
{
DWORD attributes = MotifyMemoryAttributes(original_address_);
RtlCopyMemory(reinterpret_cast<PBYTE>(original_address_), original_bytes_, byte_code_length);
MotifyMemoryAttributes(original_address_, attributes);
}
};