[!IMPORTANT]

inline_hook 一般的想法就是替换某个函数的第1个汇编命令 改成 jmp 目标函数的想法

另外需要注意的是 hook 函数与被hook处的函数 的 调用类型 要相同

1.x86 下的Inline hook

x86 下 一般都是使用jmp 指令 : 5个字节 (0xE9 ** ** ** ** ) 后面四个字节就是偏移地址

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
#include<stdio.h>
#include<Windows.h>
int WINAPI hookMessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType)
{
printf("%s;%s\n", lpText, lpCaption);
return 0;
}
void inlinehook(void* target, void* hook_address) {
unsigned char jump_hook[10] = { 0 };
jump_hook[0] = 0xE9;
int offest = (int)hook_address - (int(target) + 5);
*(int*)&jump_hook[1] = offest;
DWORD oldprotect = 0;
VirtualProtect(target, 4096, PAGE_EXECUTE_READWRITE, &oldprotect);
memcpy(target, jump_hook, 5);
VirtualProtect(target, 4096, PAGE_EXECUTE_READWRITE, &oldprotect);
}
int main()
{
inlinehook(MessageBoxA, hookMessageBox);
//void* targetFunction = (void*)MessageBoxA;
//void* p2 = (void*)hookMessageBox;
//printf("Address of MessageBoxA: %p\n", targetFunction);
//printf("Address of HookMessageBoxA %p\n", p2);
MessageBoxA(NULL, "hello world!", "inline_hook", MB_OK);
return 0;
}

上面这种inline hook 方式 会 使得 target 处的函数不能正确执行 ,一般是使用下面这种 hook 方式

InlineHook.h

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
#pragma once

#include <Windows.h>

typedef unsigned char byte;
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef uint32_t boolean_t;

typedef struct _HOOK_STUB
{
byte jz[2];
byte jnz[2];
byte flag[4];
byte nop[5];
byte jmp_handler[5];
byte origin_code[15];
byte jmp_origin_fun[5];
byte flag2[4];
}HOOK_STUB, *PHOOK_STUB;


class CInlineHook
{
public:
CInlineHook();
~CInlineHook();

bool InstallHook(const char* ModuleName, const char* ApiName, void* HandlerAddress);
bool InstallHook(void* TargetAddress, void* HandlerAddress);
bool UninstallHook();

void* GetOriginFunction() {
return m_OriginFunction;
}


protected:
//
// 获取汇编指令长度,用于HOOK
//
static int InstructLen(void* Address);
static const uint8_t c_opinfo[256];


protected:
void InitHookStub(PHOOK_STUB HookStub);

PHOOK_STUB m_HookStub;
void* m_OriginFunction;
void* m_TargetAddress;
int m_HookLen;
};


InlineHook.cpp

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#include "InlineHook.h"
#include <stdio.h>

/**
* info structure:
* 0x26 means: 6 2 (high-low, low-high)
*
* Bit 0:
* 1 - has ModR/M
* 0 - no ModR/M byte
* Bit 1~3:
* 0 - no imm
* 1 - Ib, Jb
* 2 - Iw
* 3 - Iv, Iz, Jz
* 4 - Ib + Iw
*
* special cases:
* 1. group f6xx, f7xx: nnn = 000,001 -- uses Iz
* 2. 9a, ea: Ap (xxxx:xxxxxxxx), 6-byte imm
* 3. Ob, Ov: 4-byte long offset
*/

const uint8_t CInlineHook::c_opinfo[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* --------------------------------------- */
/* 00 */ 0x11, 0x11, 0x26, 0x00, 0x11, 0x11, 0x26, 0x00,
/* 10 */ 0x11, 0x11, 0x26, 0x00, 0x11, 0x11, 0x26, 0x00,
/* 20 */ 0x11, 0x11, 0x26, 0x00, 0x11, 0x11, 0x26, 0x00,
/* 30 */ 0x11, 0x11, 0x26, 0x00, 0x11, 0x11, 0x26, 0x00,
/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 60 */ 0x00, 0x11, 0x00, 0x00, 0x67, 0x23, 0x00, 0x00,
/* 70 */ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
/* 80 */ 0x37, 0x33, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
/* B0 */ 0x22, 0x22, 0x22, 0x22, 0x66, 0x66, 0x66, 0x66,
/* C0 */ 0x33, 0x40, 0x11, 0x37, 0x80, 0x40, 0x02, 0x00,
/* D0 */ 0x11, 0x11, 0x22, 0x00, 0x11, 0x11, 0x11, 0x11,
/* E0 */ 0x22, 0x22, 0x22, 0x22, 0x66, 0x02, 0x00, 0x00,
/* F0 */ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11,
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* --------------------------------------- */
0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, /* 0F 00 */
0x11, 0x11, 0x11, 0x11, 0x10, 0x00, 0x00, 0x01, /* 0F 10 */
0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, /* 0F 20 */
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, /* 0F 30 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F 40 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F 50 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F 60 */
0x33, 0x11, 0x11, 0x10, 0x00, 0x00, 0x11, 0x11, /* 0F 70 */
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* 0F 80 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F 90 */
0x00, 0x01, 0x31, 0x00, 0x00, 0x01, 0x31, 0x11, /* 0F A0 */
0x11, 0x11, 0x11, 0x11, 0x00, 0x11, 0x11, 0x11, /* 0F B0 */
0x11, 0x31, 0x33, 0x31, 0x00, 0x00, 0x00, 0x00, /* 0F C0 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F D0 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* 0F E0 */
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10 /* 0F F0 */
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* --------------------------------------- */
};

enum cpu_mode_t { cm_legacy = -1, cm_compat = 0, cm_64bit = 1 };

int CInlineHook::InstructLen(void* Address)
{
enum cpu_mode_t cm = cm_compat;
register uint8_t* p = (uint8_t*)Address;
register uint8_t b = 0;
register boolean_t pre_66 = false;
uint8_t info;
register int tbl_fixup = 0;
register uint8_t i_info = 0;
register uint8_t modrm = 0;

if (!Address)
return -1;

while (1)
{
b = *p++;

if (b >= 0x40 && b <= 0x4f && cm == cm_64bit)
continue;
else if (b == 0x66) {
pre_66 = true;
continue;
}
else if (b == 0xf0 || b == 0xf2 || b == 0xf3 ||
b == 0x26 || b == 0x2e || b == 0x36 ||
b == 0x3e || b == 0x64 || b == 0x65 ||
b == 0x67)
continue;
break;
}

if (b == 0x0f) {
b = *p++;
tbl_fixup = 128;
}

info = c_opinfo[(b >> 1) + tbl_fixup];
info = ((b % 2) ? info : (info >> 4)) & 0x0f;
i_info = (info >> 1) & 7;

if (info & 0x01) {
/* has modrm */
modrm = *p++;
do {
register uint8_t sib = 0;
boolean_t has_sib = false;
register uint8_t tmp = 0;

if ((modrm & 0xc0) == 0xc0) /* mod == 3 */
break;

if (cm != cm_legacy && (modrm & 0x07) == 4) {
has_sib = true;
sib = *p++;
}
/* displacement */
tmp = has_sib ? sib : modrm;
if (!(modrm & 0xc0)) { /* mod == 00b */
if ((tmp & 0x07) == 5)
p += (cm == cm_legacy) ? 2 : 4;
}
else if ((modrm & 0xc0) == 0x40) { /* mod == 01b */
++p;
}
else { /* mod == 0x10b */
p += (cm == cm_legacy) ? 2 : 4;
}
} while (0);
}

/* special cases */
do
{
register uint8_t tmp = (modrm & 0x38) >> 3; /* nnn */
if (tmp == 0 || tmp == 1) {
if (b == 0xf6)
i_info |= 1;
else if (b == 0xf7)
i_info |= 3; /* Iz */
}
if (b == 0x9a || b == 0xea) /* Ap */
p += 6;
if (b >= 0xa0 && b <= 0xa3)
p += 4;

} while (0);

/* take care of immediate value */
switch (i_info) {
case 0: break;
case 1: ++p; break;
case 2: p += 2; break;
case 3: p += pre_66 ? 2 : 4; break;
case 4: p += 3; break;
}

return (int)(p - (uint8_t*)Address);
}



CInlineHook::CInlineHook()
{
m_HookStub = NULL;
m_OriginFunction = NULL;
m_TargetAddress = NULL;
m_HookLen = 0;
}


CInlineHook::~CInlineHook()
{
if (m_HookStub)
{
delete m_HookStub;
m_HookStub = NULL;
}
}

void CInlineHook::InitHookStub(PHOOK_STUB HookStub)
{
if (HookStub == NULL)
{
return;
}

ZeroMemory(HookStub, sizeof(HOOK_STUB));
HookStub->jz[0] = 0x74;
HookStub->jz[1] = 0x06;
HookStub->jnz[0] = 0x75;
HookStub->jnz[1] = 0x04;
memcpy(HookStub->flag, "xuan", sizeof(HookStub->flag));
memset(HookStub->nop, 0x90, sizeof(HookStub->nop));
HookStub->jmp_handler[0] = 0xE9;
memset(HookStub->origin_code, 0x90, sizeof(HookStub->origin_code));
HookStub->jmp_origin_fun[0] = 0xE9;
memcpy(HookStub->flag2, "yuan", sizeof(HookStub->flag2));
}

bool CInlineHook::InstallHook(const char* ModuleName, const char* ApiName, void* HandlerAddress)
{
HMODULE hModule = NULL;
void* targetAddress = NULL;
bool bRet = false;

do
{
hModule = GetModuleHandleA(ModuleName);
if (!hModule)
break;

targetAddress = GetProcAddress(hModule, ApiName);
if (!targetAddress)
break;

bRet = InstallHook(targetAddress, HandlerAddress);

} while (false);

return bRet;
}

bool CInlineHook::InstallHook(void* TargetAddress, void* HandlerAddress)
{
DWORD OldPageProperty = 0;

if (TargetAddress == NULL || HandlerAddress == NULL || m_HookStub)
{
return false;
}

//
// 计算要HOOK的字节长度
//
int hook_len = 0;
uint8_t* start_address = (uint8_t*)TargetAddress;
while (hook_len < 5)
{
int instruct_len = InstructLen(start_address);
if (instruct_len <= 0 || instruct_len >= 10)
break;

hook_len += instruct_len;
start_address += instruct_len;
}

//
// 分配中间跳指令区,并设置可执行属性
//
m_HookStub = new HOOK_STUB();
if (m_HookStub == NULL)
{
return false;
}
if (!VirtualProtect(m_HookStub, sizeof(HOOK_STUB), PAGE_EXECUTE_READWRITE, &OldPageProperty))
{
delete m_HookStub;
m_HookStub = NULL;
return false;
}

//
// 准备hook中间跳转指令
//
InitHookStub(m_HookStub);
memcpy(m_HookStub->origin_code, TargetAddress, hook_len);
*((unsigned long *)(&m_HookStub->jmp_handler[1])) = (unsigned long)HandlerAddress - ((unsigned long)&m_HookStub->jmp_handler + 5);
*((unsigned long *)(&m_HookStub->jmp_origin_fun[1])) = ((unsigned long)TargetAddress + hook_len) - ((unsigned long)&m_HookStub->jmp_origin_fun + 5);


//
// 准备Hook目标入口跳转指令
//
byte jmp_entry[20] = { 0 };
memset(jmp_entry, 0x90, sizeof(jmp_entry));
jmp_entry[0] = 0xE9;
*((unsigned long*)(&jmp_entry[1])) = (unsigned long)m_HookStub - ((unsigned long)TargetAddress + 5);

//
// 开始安装钩子
//
OldPageProperty = 0;
VirtualProtect(TargetAddress, hook_len, PAGE_READWRITE, &OldPageProperty);
memcpy(TargetAddress, jmp_entry, hook_len);
VirtualProtect(TargetAddress, hook_len, OldPageProperty, &OldPageProperty);

m_OriginFunction = &m_HookStub->origin_code;
m_TargetAddress = TargetAddress;
m_HookLen = hook_len;
return true;
}

bool CInlineHook::UninstallHook()
{
if (m_HookStub == NULL)
{
return false;
}

DWORD OldPageProperty = 0;

VirtualProtect(m_TargetAddress, m_HookLen, PAGE_READWRITE, &OldPageProperty);
memcpy(m_TargetAddress, m_HookStub->origin_code, m_HookLen);
VirtualProtect(m_TargetAddress, m_HookLen, OldPageProperty, &OldPageProperty);

delete m_HookStub;
m_HookStub = NULL;

return true;

}

Test.cpp

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
// Test.cpp : 定义控制台应用程序的入口点。
//

#include <Windows.h>
#include "InlineHook.h"

#include <map>
#include <string>
using namespace std;

map<string, CInlineHook*> hookTable;

typedef int (WINAPI *PFN_MessageBoxA) (
__in_opt HWND hWnd,
__in_opt LPCSTR lpText,
__in_opt LPCSTR lpCaption,
__in UINT uType);
int WINAPI HookMessageBoxA(
__in_opt HWND hWnd,
__in_opt LPCSTR lpText,
__in_opt LPCSTR lpCaption,
__in UINT uType)
{
printf("%s: %s\n", lpText, lpCaption);

CInlineHook* hook = hookTable["MessageBoxA"];

PFN_MessageBoxA pfn_MessageBoxA = (PFN_MessageBoxA)hook->GetOriginFunction();

pfn_MessageBoxA(hWnd, lpText, lpCaption, uType);

return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{

CInlineHook hook;

hook.InstallHook("user32.dll", "MessageBoxA", HookMessageBoxA);
hookTable.insert(pair<string, CInlineHook*>("MessageBoxA", &hook));

MessageBoxA(NULL, "this is my Blog!", "@Xhani", MB_OK);
hookTable["MessageBoxA"]->UninstallHook();
return 0;
}

此hook 方法不会 影响原函数的正确 执行

Todo1.编程实现HOOK WriteFile 这个Windows API,实现每次调用这个函数的时候,在写入的数据后面增加一个字符串:”xhani!!!”。然后程序里尝试打开一个文件,并写入一些数据,最后打开文件看看是否有这个字符串内容。

Todo1.cpp

1.方法一
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
// Todo1.cpp : 定义控制台应用程序的入口点。
//
#include <Windows.h>
#include "InlineHook.h"
#include<string.h>

#include <map>
#include <string>
using namespace std;

map<string, CInlineHook*> hookTable;

typedef
BOOL
(WINAPI* PFN_WriteFile)(
_In_ HANDLE hFile,
_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped);

BOOL
WINAPI
HookWriteFile(
_In_ HANDLE hFile,
_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
)
{
CInlineHook* hook = hookTable["WriteFile"];

const char str[] = "Xhani!!!";
size_t len = strlen(str) + nNumberOfBytesToWrite;
char *newbuffer=(char *)malloc(len+1);
if (newbuffer == NULL) return false;
memcpy(newbuffer,lpBuffer,nNumberOfBytesToWrite);
memcpy(newbuffer+nNumberOfBytesToWrite-1, str, strlen(str)+1);
nNumberOfBytesToWrite += strlen(str);

PFN_WriteFile pfn_WriteFile = (PFN_WriteFile)hook->GetOriginFunction();

pfn_WriteFile(hFile, newbuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
return true;
}


int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = CreateFile(
L"example.txt", // 文件名
GENERIC_WRITE, // 写入访问权限
0, // 不共享
NULL, // 默认安全性
CREATE_ALWAYS, // 如果文件存在则覆盖
FILE_ATTRIBUTE_NORMAL, // 普通文件
NULL // 无模板文件
);
CInlineHook hook;
hook.InstallHook("kernel32.dll", "WriteFile", HookWriteFile);

hookTable.insert(pair<string, CInlineHook*>("WriteFile", &hook));

char buffer[]="1112211213";
//fgets(buffer, sizeof(buffer), stdin);
DWORD bytesWritten;

WriteFile(hFile, buffer,sizeof(buffer),&bytesWritten,NULL);

hookTable["WriteFile"]->UninstallHook();
CloseHandle(hFile);
return 0;
}
2.方法二
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
// 使用backup  拷贝修改处的指令
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void* Backup;
#define BUFFER_SIZE 1024

void inline_hook(void* target, void* hook_address, void* Backup);
void uninstall_hook(void* target, void* backup);

BOOL WINAPI hookWriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
)
{
uninstall_hook(WriteFile,Backup);

char str[] = "Xhani!!!!!";
size_t NewSize = strlen(str) + nNumberOfBytesToWrite;
char* buffer = (char*)malloc(NewSize+1);
if (buffer == NULL) return false;
memcpy(buffer,lpBuffer ,nNumberOfBytesToWrite);
memcpy(buffer + nNumberOfBytesToWrite, str,strlen(str)+1);
nNumberOfBytesToWrite += strlen(str);

bool success = WriteFile(hFile, buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);

inline_hook(WriteFile,hookWriteFile,Backup);// 安装钩子,确保下次是调用到钩子
return success;
}
void inline_hook(void* target, void* hook_address,void *Backup)
{
unsigned char jump_Code[10] = { 0 };
jump_Code[0] = 0xE9;
int offest = (int)hook_address - (int)target - 5;
*(int*)&jump_Code[1] = offest;
DWORD oldproperty = 0;
VirtualProtect(target, sizeof(jump_Code), PAGE_EXECUTE_READWRITE, &oldproperty);
memcpy(Backup, target, 5);
memcpy(target, jump_Code, 5);
VirtualProtect(target, sizeof(jump_Code), oldproperty, &oldproperty);
return;
}

void uninstall_hook(void* target, void* backup) {
DWORD oldproperty = 0;
VirtualProtect(target, 4096, PAGE_EXECUTE_READWRITE, &oldproperty);
memcpy(target, backup, 5);
VirtualProtect(target, 4096, oldproperty, &oldproperty);
return;
}
int main()
{
HANDLE hFile = CreateFile(
L"example.txt", // 文件名
GENERIC_WRITE, // 写入访问权限
0, // 不共享
NULL, // 默认安全性
CREATE_ALWAYS, // 如果文件存在则覆盖
FILE_ATTRIBUTE_NORMAL, // 普通文件
NULL // 无模板文件
);
Backup = malloc(5);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD bytesWritten; // 实际写入的字节数
char buffer[] = "123456";
inline_hook(WriteFile, hookWriteFile,Backup);
WriteFile(hFile, buffer, strlen(buffer), &bytesWritten, NULL);
}
CloseHandle(hFile);
free(Backup);
return 0;
}

2.x64 位下的Inline hook

需要注意的是x64 下的 jmp 指令实际是 14个字节(间接跳转) : jmp指令(FF 25)+ offest1(4字节)+0ffest2(8字节) [因为64位下寻址更慢]

[!NOTE]

首先是计算出 jmp + offset1 的地址p1 ,然后寻址到p1处,在计算出p1+offest2 ,即为目标地址

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
#include<stdio.h>
#include<Windows.h>
void sh() {
printf("true");
return;
}
void sa()
{
printf("false");
return;
}
void inlinehook(__int64* target, __int64* hook_address) {
char jump_hook[14] = {0xFF,0x25,00,00,00,00,00,00,00,00,00,00,00,00 };
__int64* p = (_int64*)&hook_address;
memcpy(jump_hook + 6,p , sizeof(void*));
//char jump_hook[] = {0xFF,0x25,0x01,00,00,00,00,00,00,00,00,00,00,00,00 };
//__int64* p = (_int64*)&hook_address;
//memcpy(jump_hook + 7,p , sizeof(void*));
DWORD oldprotect = 0;
VirtualProtect(target, sizeof(jump_hook), PAGE_EXECUTE_READWRITE, &oldprotect);
memcpy(target, jump_hook, sizeof(jump_hook));
VirtualProtect(target, sizeof(jump_hook), oldprotect, &oldprotect);
return;
}
int main()
{
inlinehook((__int64 *)sa,(_int64 *)sh);
sa();
return 0;
}