Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Peacoor Zomboss
miscellaneous
提交
8505aced
M
miscellaneous
项目概览
Peacoor Zomboss
/
miscellaneous
通知
152
Star
9
Fork
18
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
2
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
miscellaneous
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
2
Issue
2
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
8505aced
编写于
2月 02, 2023
作者:
Peacoor Zomboss
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add inline hook demo
上级
0d4ef669
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
274 addition
and
0 deletion
+274
-0
230131-inlinehook/build.bat
230131-inlinehook/build.bat
+4
-0
230131-inlinehook/multithreadhook.cpp
230131-inlinehook/multithreadhook.cpp
+157
-0
230131-inlinehook/simplehook.cpp
230131-inlinehook/simplehook.cpp
+113
-0
未找到文件。
230131-inlinehook/build.bat
0 → 100644
浏览文件 @
8505aced
i686
-w
64
-mingw
32
-g
++
-O
simplehook
.cpp
-o
simplehook32
x86_64
-w
64
-mingw
32
-g
++
-O
simplehook
.cpp
-o
simplehook64
i686
-w
64
-mingw
32
-g
++
-O
multithreadhook
.cpp
-o
multithreadhook32
x86_64
-w
64
-mingw
32
-g
++
-O
multithreadhook
.cpp
-o
multithreadhook64
230131-inlinehook/multithreadhook.cpp
0 → 100644
浏览文件 @
8505aced
#include <windows.h>
#include <stdio.h>
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
#define _CPU_X64
#elif defined(__i386__) || defined(_M_IX86)
#define _CPU_X86
#else
#error "Unsupported CPU"
#endif
#define HOOK_JUMP_LEN 5
typedef
WINBOOL
(
WINAPI
*
WRITECONSOLEA
)
(
HANDLE
,
CONST
VOID
*
,
DWORD
,
LPDWORD
,
LPVOID
);
#ifdef _CPU_X64
static
void
*
FindModuleTextBlankAlign
(
HMODULE
hmodule
)
{
BYTE
*
p
=
(
BYTE
*
)
hmodule
;
p
+=
((
IMAGE_DOS_HEADER
*
)
p
)
->
e_lfanew
+
4
;
// 根据DOS头获取PE信息偏移量
p
+=
sizeof
(
IMAGE_FILE_HEADER
)
+
((
IMAGE_FILE_HEADER
*
)
p
)
->
SizeOfOptionalHeader
;
// 跳过可选头
WORD
sections
=
((
IMAGE_FILE_HEADER
*
)
p
)
->
NumberOfSections
;
// 获取区段长度
for
(
int
i
=
0
;
i
<
sections
;
i
++
)
{
IMAGE_SECTION_HEADER
*
psec
=
(
IMAGE_SECTION_HEADER
*
)
p
;
p
+=
sizeof
(
IMAGE_SECTION_HEADER
);
if
(
memcmp
(
psec
->
Name
,
".text"
,
5
)
==
0
)
{
// 是否.text段
BYTE
*
offset
=
(
BYTE
*
)
hmodule
+
psec
->
VirtualAddress
+
psec
->
Misc
.
VirtualSize
;
// 计算空白区域偏移量
offset
+=
16
-
(
INT_PTR
)
offset
%
16
;
// 对齐16字节
long
long
*
buf
=
(
long
long
*
)
offset
;
while
(
buf
[
0
]
!=
0
||
buf
[
1
]
!=
0
)
// 找到一块全是0的区域
buf
+=
16
;
return
(
void
*
)
buf
;
}
}
return
0
;
}
#endif
HANDLE
hstdout
=
NULL
;
void
*
old_entry
=
NULL
;
void
*
hook_func
=
NULL
;
char
hook_jump
[
HOOK_JUMP_LEN
];
WRITECONSOLEA
_WriteConsoleA
;
WINBOOL
WINAPI
fk_WriteConsoleA
(
HANDLE
hConsoleOutput
,
CONST
VOID
*
lpBuffer
,
DWORD
nNumberOfCharsToWrite
,
LPDWORD
lpNumberOfCharsWritten
,
LPVOID
lpReserved
)
{
char
buf
[
128
];
strcpy
(
buf
,
(
char
*
)
lpBuffer
);
buf
[
nNumberOfCharsToWrite
-
1
]
=
'\0'
;
strcat
(
buf
,
"
\t
[hook]
\n
"
);
int
len
=
nNumberOfCharsToWrite
+
8
;
return
_WriteConsoleA
(
hConsoleOutput
,
buf
,
len
,
NULL
,
NULL
);
}
#ifdef _CPU_X64
#define ENTRY_LEN 9
#endif
#ifdef _CPU_X86
#define ENTRY_LEN 5
#endif
void
dohook
()
{
HMODULE
hmodule
=
GetModuleHandleA
(
"kernelbase.dll"
);
hook_func
=
(
void
*
)
GetProcAddress
(
hmodule
,
"WriteConsoleA"
);
// 允许func_ptr处最前面的5字节内存可读可写可执行
VirtualProtect
(
hook_func
,
HOOK_JUMP_LEN
,
PAGE_EXECUTE_READWRITE
,
NULL
);
// 使用VirtualAlloc申请内存,使其可读可写可执行
old_entry
=
VirtualAlloc
(
NULL
,
32
,
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
#ifdef _CPU_X64
union
{
void
*
ptr
;
struct
{
long
lo
;
long
hi
;
};
}
ptr64
;
void
*
blank
=
FindModuleTextBlankAlign
(
hmodule
);
// 找到第一处空白区域
VirtualProtect
(
blank
,
14
,
PAGE_EXECUTE_READWRITE
,
NULL
);
// 可读写
hook_jump
[
0
]
=
0xE9
;
// 跳转代码
*
(
long
*
)
&
hook_jump
[
1
]
=
(
BYTE
*
)
blank
-
(
BYTE
*
)
hook_func
-
5
;
// 跳转到空白区域
ptr64
.
ptr
=
(
void
*
)
fk_WriteConsoleA
;
BYTE
blank_jump
[
14
];
blank_jump
[
0
]
=
0x68
;
// push xxx
*
(
long
*
)
&
blank_jump
[
1
]
=
ptr64
.
lo
;
// xxx,即地址的低4位
blank_jump
[
5
]
=
0xC7
;
blank_jump
[
6
]
=
0x44
;
blank_jump
[
7
]
=
0x24
;
blank_jump
[
8
]
=
0x04
;
// mov dword [rsp+4], yyy
*
(
long
*
)
&
blank_jump
[
9
]
=
ptr64
.
hi
;
// yyy,即地址的高4位
blank_jump
[
13
]
=
0xC3
;
// ret
// 写入真正的跳转代码到空白区域
WriteProcessMemory
(
GetCurrentProcess
(),
blank
,
&
blank_jump
,
14
,
NULL
);
// 保存原来的入口代码
memcpy
(
old_entry
,
hook_func
,
ENTRY_LEN
);
ptr64
.
ptr
=
(
BYTE
*
)
hook_func
+
ENTRY_LEN
;
// 设置新的跳转代码
BYTE
*
new_jump
=
(
BYTE
*
)
old_entry
+
ENTRY_LEN
;
new_jump
[
0
]
=
0x68
;
*
(
long
*
)(
new_jump
+
1
)
=
ptr64
.
lo
;
new_jump
[
5
]
=
0xC7
;
new_jump
[
6
]
=
0x44
;
new_jump
[
7
]
=
0x24
;
new_jump
[
8
]
=
0x04
;
*
(
long
*
)(
new_jump
+
9
)
=
ptr64
.
hi
;
new_jump
[
13
]
=
0xC3
;
#endif
#ifdef _CPU_X86
hook_jump
[
0
]
=
0xE9
;
// 跳转代码
*
(
long
*
)
&
hook_jump
[
1
]
=
(
BYTE
*
)
fk_WriteConsoleA
-
(
BYTE
*
)
hook_func
-
5
;
// 直接到hook的代码
memcpy
(
old_entry
,
hook_func
,
ENTRY_LEN
);
// 保存入口
BYTE
*
new_jump
=
(
BYTE
*
)
old_entry
+
ENTRY_LEN
;
*
new_jump
=
0xE9
;
// 跳回去的代码
*
(
long
*
)(
new_jump
+
1
)
=
(
BYTE
*
)
hook_func
+
ENTRY_LEN
-
new_jump
-
5
;
#endif
_WriteConsoleA
=
(
WRITECONSOLEA
)
old_entry
;
WriteProcessMemory
(
GetCurrentProcess
(),
hook_func
,
&
hook_jump
,
HOOK_JUMP_LEN
,
NULL
);
}
void
unhook
()
{
WriteProcessMemory
(
GetCurrentProcess
(),
hook_func
,
old_entry
,
HOOK_JUMP_LEN
,
NULL
);
VirtualFree
(
old_entry
,
0
,
MEM_RELEASE
);
}
DWORD
WINAPI
thread_writehello
(
void
*
stdh
)
{
DWORD
id
=
GetCurrentThreadId
();
char
str
[
64
];
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
int
len
=
sprintf
(
str
,
"%d: Hello World %d
\n
"
,
id
,
i
);
WriteConsoleA
(
stdh
,
str
,
len
,
NULL
,
NULL
);
}
return
0
;
}
#define THREAD_COUNT 5
int
main
()
{
dohook
();
hstdout
=
GetStdHandle
(
-
11
);
HANDLE
hthreads
[
THREAD_COUNT
];
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
hthreads
[
i
]
=
CreateThread
(
NULL
,
0
,
thread_writehello
,
hstdout
,
CREATE_SUSPENDED
,
NULL
);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
ResumeThread
(
hthreads
[
i
]);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
WaitForSingleObject
(
hthreads
[
i
],
1000
);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
CloseHandle
(
hthreads
[
i
]);
WriteConsoleA
(
hstdout
,
"Must hook
\n
"
,
10
,
NULL
,
NULL
);
unhook
();
WriteConsoleA
(
hstdout
,
"Not hook
\n
"
,
9
,
NULL
,
NULL
);
}
230131-inlinehook/simplehook.cpp
0 → 100644
浏览文件 @
8505aced
#include <windows.h>
#include <stdio.h>
#if defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) || defined(_M_AMD64)
#define _CPU_X64
#elif defined(__i386__) || defined(_M_IX86)
#define _CPU_X86
#else
#error "Unsupported CPU"
#endif
#ifdef _CPU_X64
#define HOOK_JUMP_LEN 14
#endif
#ifdef _CPU_X86
#define HOOK_JUMP_LEN 5
#endif
WINBOOL
WINAPI
fk_WriteConsoleA
(
HANDLE
,
CONST
VOID
*
,
DWORD
,
LPDWORD
,
LPVOID
);
HANDLE
hstdout
=
NULL
;
void
*
hook_func
=
NULL
;
char
hook_jump
[
HOOK_JUMP_LEN
];
char
old_entry
[
HOOK_JUMP_LEN
];
void
inithook
()
{
HMODULE
hmodule
=
GetModuleHandleA
(
"kernelbase.dll"
);
hook_func
=
(
void
*
)
GetProcAddress
(
hmodule
,
"WriteConsoleA"
);
VirtualProtect
(
hook_func
,
HOOK_JUMP_LEN
,
PAGE_EXECUTE_READWRITE
,
NULL
);
#ifdef _CPU_X64
union
{
void
*
ptr
;
struct
{
long
lo
;
long
hi
;
};
}
ptr64
;
ptr64
.
ptr
=
(
void
*
)
fk_WriteConsoleA
;
hook_jump
[
0
]
=
0x68
;
// push xxx
*
(
long
*
)
&
hook_jump
[
1
]
=
ptr64
.
lo
;
// xxx,即地址的低4位
hook_jump
[
5
]
=
0xC7
;
hook_jump
[
6
]
=
0x44
;
hook_jump
[
7
]
=
0x24
;
hook_jump
[
8
]
=
0x04
;
// mov dword [rsp+4], yyy
*
(
long
*
)
&
hook_jump
[
9
]
=
ptr64
.
hi
;
// yyy,即地址的高4位
hook_jump
[
13
]
=
0xC3
;
// ret
ReadProcessMemory
(
GetCurrentProcess
(),
hook_func
,
old_entry
,
HOOK_JUMP_LEN
,
NULL
);
#endif
#ifdef _CPU_X86
hook_jump
[
0
]
=
0xE9
;
*
(
long
*
)
&
hook_jump
[
1
]
=
(
BYTE
*
)
fk_WriteConsoleA
-
(
BYTE
*
)
hook_func
-
5
;
ReadProcessMemory
(
GetCurrentProcess
(),
hook_func
,
old_entry
,
HOOK_JUMP_LEN
,
NULL
);
#endif
}
void
dohook
()
{
WriteProcessMemory
(
GetCurrentProcess
(),
hook_func
,
hook_jump
,
HOOK_JUMP_LEN
,
NULL
);
}
void
unhook
()
{
WriteProcessMemory
(
GetCurrentProcess
(),
hook_func
,
old_entry
,
HOOK_JUMP_LEN
,
NULL
);
}
WINBOOL
WINAPI
fk_WriteConsoleA
(
HANDLE
hConsoleOutput
,
CONST
VOID
*
lpBuffer
,
DWORD
nNumberOfCharsToWrite
,
LPDWORD
lpNumberOfCharsWritten
,
LPVOID
lpReserved
)
{
unhook
();
char
buf
[
128
];
strcpy
(
buf
,
(
char
*
)
lpBuffer
);
buf
[
nNumberOfCharsToWrite
-
1
]
=
'\0'
;
strcat
(
buf
,
"
\t
[hook]
\n
"
);
int
len
=
nNumberOfCharsToWrite
+
8
;
WINBOOL
result
=
WriteConsoleA
(
hConsoleOutput
,
buf
,
len
,
NULL
,
NULL
);
dohook
();
return
result
;
}
DWORD
WINAPI
thread_writehello
(
void
*
stdh
)
{
DWORD
id
=
GetCurrentThreadId
();
char
str
[
64
];
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
int
len
=
sprintf
(
str
,
"%d: Hello World %d
\n
"
,
id
,
i
);
WriteConsoleA
(
stdh
,
str
,
len
,
NULL
,
NULL
);
}
return
0
;
}
#define THREAD_COUNT 5
int
main
()
{
inithook
();
dohook
();
hstdout
=
GetStdHandle
(
-
11
);
HANDLE
hthreads
[
THREAD_COUNT
];
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
hthreads
[
i
]
=
CreateThread
(
NULL
,
0
,
thread_writehello
,
hstdout
,
CREATE_SUSPENDED
,
NULL
);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
ResumeThread
(
hthreads
[
i
]);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
WaitForSingleObject
(
hthreads
[
i
],
1000
);
for
(
int
i
=
0
;
i
<
THREAD_COUNT
;
i
++
)
CloseHandle
(
hthreads
[
i
]);
WriteConsoleA
(
hstdout
,
"Must hook
\n
"
,
10
,
NULL
,
NULL
);
unhook
();
WriteConsoleA
(
hstdout
,
"Not hook
\n
"
,
9
,
NULL
,
NULL
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录