Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gaolinghu
miscellaneous
提交
98a7367f
M
miscellaneous
项目概览
gaolinghu
/
miscellaneous
与 Fork 源项目一致
Fork自
Peacoor Zomboss / miscellaneous
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
miscellaneous
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
98a7367f
编写于
1月 31, 2024
作者:
Peacoor Zomboss
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix crash on different Windows versions
上级
8cc794d9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
319 addition
and
21 deletion
+319
-21
230130-hookgamesendto/inc/inlinehook.h
230130-hookgamesendto/inc/inlinehook.h
+1
-1
230130-hookgamesendto/inc/insn_len.h
230130-hookgamesendto/inc/insn_len.h
+309
-0
230130-hookgamesendto/src/fkhook.cpp
230130-hookgamesendto/src/fkhook.cpp
+3
-14
230130-hookgamesendto/src/inlinehook.cpp
230130-hookgamesendto/src/inlinehook.cpp
+6
-6
未找到文件。
230130-hookgamesendto/inc/inlinehook.h
浏览文件 @
98a7367f
...
...
@@ -11,7 +11,7 @@ private:
char
hook_entry
[
HOOK_JUMP_LEN
];
// hook跳转的代码
void
*
func_ptr
;
// 被hook函数的地址
public:
InlineHook
(
HMODULE
hmodule
,
const
char
*
name
,
void
*
fake_func
,
int
entry_len
);
InlineHook
(
HMODULE
hmodule
,
const
char
*
name
,
void
*
fake_func
);
~
InlineHook
();
void
hook
();
void
unhook
();
...
...
230130-hookgamesendto/inc/insn_len.h
0 → 100644
浏览文件 @
98a7367f
/* Copyright 2011 oblique. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY OBLIQUE ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OBLIQUE OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of oblique.
*/
/* Modified by PeaZomboss
*/
/* References:
* Intel 64 and IA-32 Architectures Software Developer's Manuals - Volume 2A Ch. 2
* http://ref.x86asm.net
* http://sandpile.org
*/
#pragma once
#ifdef __cplusplus
extern
"C"
{
#endif
#define Mod_M 0xc0
#define RM_M 0x7
#define Base_M 0x7
#define REX_W 0x8
#define MAX_INSN_LEN_x86 15
#define MAX_INSN_LEN_x86_32 MAX_INSN_LEN_x86
#define MAX_INSN_LEN_x86_64 MAX_INSN_LEN_x86
enum
__bits
{
__b16
,
__b32
,
__b64
};
#if defined(__i386__) || defined(_M_IX86)
#define insn_len(insn) insn_len_x86_32(insn)
#define MAX_INSN_LEN MAX_INSN_LEN_x86_32
#elif defined(__x86_64__) || defined(_M_X64)
#define insn_len(insn) insn_len_x86_64(insn)
#define MAX_INSN_LEN MAX_INSN_LEN_x86_64
#endif
/* This function returns the length of an x86 instruction.
* I assume that instruction is valid.
*/
static
inline
int
__insn_len_x86
(
void
*
insn
,
enum
__bits
bits
)
{
int
len
=
0
,
twobytes
=
0
,
has_modrm
=
0
;
enum
__bits
operand_bits
=
__b32
,
addr_bits
=
bits
;
unsigned
char
*
c
=
(
unsigned
char
*
)
insn
,
modrm
,
opcode
;
/* prefixes
*
* 0xf0, 0xf2, 0xf3, 0x2e, 0x36
* 0x3e, 0x26, 0x64, 0x65, 0x66, 0x67
*/
// skip prefixes
while
(
*
c
==
0xf0
||
*
c
==
0xf2
||
*
c
==
0xf3
||
*
c
==
0x2e
||
*
c
==
0x36
||
*
c
==
0x3e
||
*
c
==
0x26
||
(
*
c
&
0xfc
)
==
0x64
)
{
if
(
*
c
==
0x66
)
// 16bits operands
operand_bits
=
__b16
;
if
(
*
c
==
0x67
)
// 16bits addressing (x86-32), 32bits addressing (x86-64)
addr_bits
=
bits
==
__b32
?
__b16
:
__b32
;
c
++
;
len
++
;
}
if
(
bits
==
__b64
&&
(
*
c
&
0xf0
)
==
0x40
)
{
// x86-64 && REX byte
if
(
*
c
&
REX_W
)
operand_bits
=
__b64
;
c
++
;
len
++
;
}
/* 0x9b prefix is used only by the following 1byte opcodes
*
* 0xd9 Mod != 11 Reg/Op = 110 or 111
* 0xdb ModR/M = 0xe2 or 0xe3
* 0xdd Reg/Op = 110 or 111
* 0xdf ModR/M = 0xe0
*/
// check for 2bytes opcodes (0x0f prefix)
if
(
*
c
==
0x0f
)
{
twobytes
=
1
;
c
++
;
len
++
;
}
else
if
(
*
c
==
0x9b
&&
// check 0x9b prefix
((
c
[
1
]
==
0xd9
&&
(
c
[
2
]
&
Mod_M
)
!=
Mod_M
&&
(
c
[
2
]
&
0x30
)
==
0x30
)
||
(
c
[
1
]
==
0xdb
&&
(
c
[
2
]
==
0xe2
||
c
[
2
]
==
0xe3
))
||
(
c
[
1
]
==
0xdd
&&
(
c
[
2
]
&
0x30
)
==
0x30
)
||
(
c
[
1
]
==
0xdf
&&
c
[
2
]
==
0xe0
)
))
{
c
++
;
len
++
;
}
opcode
=
*
c
++
;
len
++
;
/* 1byte opcodes that use ModR/M byte:
*
* 0x00 - 0x03, 0x08 - 0x0b,
* 0x10 - 0x13, 0x18 - 0x1b,
* 0x20 - 0x23, 0x28 - 0x2b,
* 0x30 - 0x33, 0x38 - 0x3b,
* 0x62, 0x63, 0x69, 0x6b,
* 0x80 - 0x8f, 0xc0, 0xc1,
* 0xc4 - 0xc7,
* 0xd0 - 0xd3, 0xd8 - 0xdf
* 0xf6, 0xf7, 0xfe, 0xff
*/
if
(
!
twobytes
&&
((
opcode
&
0xf4
)
==
0
||
(
opcode
&
0xf4
)
==
0x10
||
(
opcode
&
0xf4
)
==
0x20
||
(
opcode
&
0xf4
)
==
0x30
||
opcode
==
0x62
||
opcode
==
0x63
||
opcode
==
0x69
||
opcode
==
0x6b
||
(
opcode
&
0xf0
)
==
0x80
||
opcode
==
0xc0
||
opcode
==
0xc1
||
(
opcode
&
0xfc
)
==
0xc4
||
(
opcode
&
0xfc
)
==
0xd0
||
(
opcode
&
0xf8
)
==
0xd8
||
opcode
==
0xf6
||
opcode
==
0xf7
||
opcode
==
0xfe
||
opcode
==
0xff
))
has_modrm
=
1
;
/* 2bytes opcodes that they *don't* use ModR/M byte:
*
* 0x05 - 0x09, 0x0b, 0x0e,
* 0x30 - 0x37, 0x77, 0x80 - 0x8f,
* 0xa0 - 0xa2, 0xa8 - 0xaa, 0xb9
* 0xc8 - 0xcf
*/
if
(
twobytes
)
{
if
(
!
((
opcode
>=
0x05
&&
opcode
<=
0x09
)
||
opcode
==
0x0b
||
opcode
==
0x0e
||
(
opcode
&
0xf8
)
==
0x30
||
opcode
==
0x77
||
(
opcode
&
0xf0
)
==
0x80
||
(
opcode
>=
0xa0
&&
opcode
<=
0xa2
)
||
(
opcode
>=
0xa8
&&
opcode
<=
0xaa
)
||
(
opcode
&
0xf8
)
==
0xc8
||
opcode
==
0xb9
))
has_modrm
=
1
;
// 3bytes opcodes
if
(
opcode
==
0x38
||
opcode
==
0x3a
)
{
c
++
;
len
++
;
}
// 3DNow! opcode
if
(
opcode
==
0x0f
)
len
++
;
}
if
(
has_modrm
)
{
len
++
;
modrm
=
*
c
++
;
if
(
addr_bits
!=
__b16
&&
(
modrm
&
(
Mod_M
|
RM_M
))
==
5
)
// Mod = 00 R/M = 101
len
+=
4
;
if
(
addr_bits
==
__b16
&&
(
modrm
&
(
Mod_M
|
RM_M
))
==
6
)
// Mod = 00 R/M = 110 and 16bits addressing
len
+=
2
;
if
((
modrm
&
Mod_M
)
==
0x40
)
// Mod = 01
len
+=
1
;
if
((
modrm
&
Mod_M
)
==
0x80
)
// Mod = 10
len
+=
addr_bits
==
__b16
?
2
:
4
;
// check SIB byte
if
(
addr_bits
!=
__b16
&&
(
modrm
&
Mod_M
)
!=
Mod_M
&&
(
modrm
&
RM_M
)
==
4
)
{
// if it has SIB
len
++
;
if
((
modrm
&
Mod_M
)
==
0
&&
(
*
c
&
Base_M
)
==
5
)
// Mod = 00 SIB Base = 101
len
+=
4
;
c
++
;
}
}
/* Immediate operands
*
* 1byte opcode list:
*
* imm8 (1 byte)
*
* 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c, 0x6a, 0x6b, 0x70 - 0x7f,
* 0x80, 0x82, 0x83, 0xa8, 0xb0 - 0xb7, 0xc0, 0xc1, 0xc6, 0xcd, 0xd4,
* 0xd5, 0xe0 - 0xe7, 0xeb, 0xf6 (Reg/Op = 000 or Reg/Op = 001)
*
* imm16 (2 bytes)
*
* 0xc2, 0xca
*
* imm16/32 (2 bytes if operand_bits == __b16 else 4 bytes)
*
* 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d, 0x68, 0x69, 0x81, 0xa9
* 0xc7, 0xe8, 0xe9
*
* imm16/32/64 (2 bytes if operand_bits == __b16, 4 bytes if __b32, 8 bytes if __b64)
*
* 0xb8 - 0xbf, 0xf7 (Reg/Op = 000 or Reg/Op = 001)
*
* moffs (2 bytes if addr_bits == __b16, 4 bytes if __b32, 8 bytes if __b64)
*
* 0xa0, 0xa1, 0xa2, 0xa3
*
* others
*
* 0xea, 0x9a: imm16 + imm16/32
* 0xc8: imm16 + imm8
*
*
* 2bytes opcode list:
*
* imm8 (1 byte)
*
* 0x70 - 0x73, 0xa4, 0xac, 0xba, 0xc2, 0xc4 - 0xc6
*
* imm16/32 (2 bytes if operand_bits == __b16 else 4 bytes)
*
* 0x80 - 0x8f
*
*
* all 3bytes opcodes with 0x3a prefix have imm8
*/
if
(
!
twobytes
)
{
// 1byte opcodes
// imm8
if
(((
opcode
&
7
)
==
4
&&
(
opcode
&
0xf0
)
<=
0x30
)
||
opcode
==
0x6a
||
opcode
==
0x6b
||
(
opcode
&
0xf0
)
==
0x70
||
opcode
==
0x80
||
opcode
==
0x82
||
opcode
==
0x83
||
opcode
==
0xa8
||
(
opcode
&
0xf8
)
==
0xb0
||
opcode
==
0xc0
||
opcode
==
0xc1
||
opcode
==
0xc6
||
opcode
==
0xcd
||
opcode
==
0xd4
||
opcode
==
0xd5
||
(
opcode
&
0xf8
)
==
0xe0
||
opcode
==
0xeb
||
(
opcode
==
0xf6
&&
(
modrm
&
0x30
)
==
0
))
len
+=
1
;
// imm16
if
(
opcode
==
0xc2
||
opcode
==
0xca
)
len
+=
2
;
// imm16/32
if
(((
opcode
&
7
)
==
5
&&
(
opcode
&
0xf0
)
<=
0x30
)
||
opcode
==
0x68
||
opcode
==
0x69
||
opcode
==
0x81
||
opcode
==
0xa9
||
opcode
==
0xc7
||
opcode
==
0xe8
||
opcode
==
0xe9
)
len
+=
operand_bits
==
__b16
?
2
:
4
;
// imm16/32/64
if
((
opcode
&
0xf8
)
==
0xb8
||
(
opcode
==
0xf7
&&
(
modrm
&
0x30
)
==
0
))
len
+=
operand_bits
==
__b16
?
2
:
operand_bits
==
__b32
?
4
:
8
;
// moffs
if
((
opcode
&
0xfc
)
==
0xa0
)
len
+=
addr_bits
==
__b16
?
2
:
addr_bits
==
__b32
?
4
:
8
;
// others
if
(
opcode
==
0xea
||
opcode
==
0x9a
)
len
+=
2
+
(
operand_bits
==
__b16
?
2
:
4
);
if
(
opcode
==
0xc8
)
len
+=
3
;
}
else
{
// 2bytes opcodes
// imm8
if
((
opcode
&
0xfc
)
==
0x70
||
opcode
==
0xa4
||
opcode
==
0xac
||
opcode
==
0xba
||
opcode
==
0xc2
||
(
opcode
>=
0xc4
&&
opcode
<=
0xc6
))
len
+=
1
;
// imm16/32
if
((
opcode
&
0xf0
)
==
0x80
)
len
+=
operand_bits
==
__b16
?
2
:
4
;
// 3bytes opcodes with 0x3a prefix
if
(
opcode
==
0x3a
)
len
+=
1
;
}
// wrong length
if
(
len
>
MAX_INSN_LEN_x86
)
len
=
1
;
return
len
;
}
static
int
insn_len_x86_32
(
void
*
insn
)
{
return
__insn_len_x86
(
insn
,
__b32
);
}
static
int
insn_len_x86_64
(
void
*
insn
)
{
return
__insn_len_x86
(
insn
,
__b64
);
}
#ifdef __cplusplus
}
#endif
230130-hookgamesendto/src/fkhook.cpp
浏览文件 @
98a7367f
...
...
@@ -3,17 +3,6 @@
#include "platform.h"
#include <vector>
#ifdef _CPU_X86
#define SENDTO_ENTRY_LEN 5
#define SELECT_ENTRY_LEN 7
#define RECVFROM_ENTRY_LEN 5
#endif
#ifdef _CPU_X64
#define SENDTO_ENTRY_LEN 7
#define SELECT_ENTRY_LEN 7
#define RECVFROM_ENTRY_LEN 7
#endif
typedef
int
WINAPI
(
*
sendto_func
)
(
SOCKET
,
const
char
*
,
int
,
int
,
const
sockaddr
*
,
int
);
typedef
int
WINAPI
(
*
select_func
)
(
int
,
fd_set
*
,
fd_set
*
,
fd_set
*
,
const
TIMEVAL
*
);
typedef
int
WINAPI
(
*
recvfrom_func
)
(
SOCKET
,
char
*
,
int
,
int
,
sockaddr
*
,
int
*
);
...
...
@@ -119,7 +108,7 @@ static int WINAPI fake_recvfrom(SOCKET s, char *buf, int len, int flags, sockadd
void
hook_sendto
()
{
if
(
!
sendto_hook
)
{
sendto_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"sendto"
,
(
void
*
)
fake_sendto
,
SENDTO_ENTRY_LEN
);
sendto_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"sendto"
,
(
void
*
)
fake_sendto
);
_sendto
=
(
sendto_func
)
sendto_hook
->
get_old_entry
();
sendto_hook
->
hook
();
}
...
...
@@ -137,7 +126,7 @@ void unhook_sendto()
void
hook_select
()
{
if
(
!
select_hook
)
{
select_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"select"
,
(
void
*
)
fake_select
,
SELECT_ENTRY_LEN
);
select_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"select"
,
(
void
*
)
fake_select
);
_select
=
(
select_func
)
select_hook
->
get_old_entry
();
select_hook
->
hook
();
}
...
...
@@ -154,7 +143,7 @@ void unhook_select()
void
hook_recvfrom
()
{
if
(
!
recvfrom_hook
)
{
recvfrom_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"recvfrom"
,
(
void
*
)
fake_recvfrom
,
RECVFROM_ENTRY_LEN
);
recvfrom_hook
=
new
InlineHook
(
GetModuleHandleA
(
"ws2_32.dll"
),
"recvfrom"
,
(
void
*
)
fake_recvfrom
);
_recvfrom
=
(
recvfrom_func
)
recvfrom_hook
->
get_old_entry
();
recvfrom_hook
->
hook
();
}
...
...
230130-hookgamesendto/src/inlinehook.cpp
浏览文件 @
98a7367f
#include <windows.h>
#include "inlinehook.h"
#include "platform.h"
#include "insn_len.h"
#ifdef _CPU_X64
#define HOOK_PATCH_MAX 18
...
...
@@ -32,14 +33,13 @@ static void *FindModuleTextBlankAlign(HMODULE hmodule)
}
#endif
InlineHook
::
InlineHook
(
HMODULE
hmodule
,
const
char
*
name
,
void
*
fake_func
,
int
entry_len
)
InlineHook
::
InlineHook
(
HMODULE
hmodule
,
const
char
*
name
,
void
*
fake_func
)
{
func_ptr
=
(
void
*
)
GetProcAddress
(
hmodule
,
name
);
// 范围检查
if
(
entry_len
<
HOOK_JUMP_LEN
)
entry_len
=
HOOK_JUMP_LEN
;
if
(
entry_len
>
HOOK_PATCH_MAX
)
entry_len
=
HOOK_PATCH_MAX
;
int
entry_len
=
0
;
do
{
entry_len
+=
insn_len
((
BYTE
*
)
func_ptr
+
entry_len
);
}
while
(
entry_len
<
HOOK_JUMP_LEN
);
// 允许func_ptr处最前面的5字节内存可读可写可执行
VirtualProtect
(
func_ptr
,
HOOK_JUMP_LEN
,
PAGE_EXECUTE_READWRITE
,
NULL
);
// 使用VirtualAlloc申请内存,使其可读可写可执行
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录