-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHookV2.h
229 lines (152 loc) · 7.38 KB
/
HookV2.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
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
#pragma once
#ifndef __HookV2__
#define __HookV2__
#define MASK_N_BITS(N) ( ( 1 << ( N ) ) - 1 )
#define POWERPC_HI(X) ( ( X >> 16 ) & 0xFFFF )
#define POWERPC_LO(X) ( X & 0xFFFF )
//
// PowerPC most significant bit is addressed as bit 0 in documentation.
//
#define POWERPC_BIT32(N) ( 31 - N )
//
// Opcode is bits 0-5.
// Allowing for op codes ranging from 0-63.
//
#define POWERPC_OPCODE(OP) ( OP << 26 )
#define POWERPC_OPCODE_ADDI POWERPC_OPCODE( 14 )
#define POWERPC_OPCODE_ADDIS POWERPC_OPCODE( 15 )
#define POWERPC_OPCODE_BC POWERPC_OPCODE( 16 )
#define POWERPC_OPCODE_B POWERPC_OPCODE( 18 )
#define POWERPC_OPCODE_BCCTR POWERPC_OPCODE( 19 )
#define POWERPC_OPCODE_ORI POWERPC_OPCODE( 24 )
#define POWERPC_OPCODE_ORIS POWERPC_OPCODE( 25 ) //mb
#define POWERPC_OPCODE_EXTENDED POWERPC_OPCODE( 31 ) // Use extended opcodes.
#define POWERPC_OPCODE_STW POWERPC_OPCODE( 36 )
#define POWERPC_OPCODE_LWZ POWERPC_OPCODE( 32 )
#define POWERPC_OPCODE_LD POWERPC_OPCODE( 58 )
#define POWERPC_OPCODE_STD POWERPC_OPCODE( 62 )
#define POWERPC_OPCODE_MASK POWERPC_OPCODE( 63 )
#define POWERPC_EXOPCODE(OP) ( OP << 1 )
#define POWERPC_EXOPCODE_BCCTR POWERPC_EXOPCODE( 528 )
#define POWERPC_EXOPCODE_MTSPR POWERPC_EXOPCODE( 467 )
//
// SPR field is encoded as two 5 bit bitfields.
//
#define POWERPC_SPR(SPR) (UINT32)( ( ( SPR & 0x1F ) << 5 ) | ( ( SPR >> 5 ) & 0x1F ) )
//
// Instruction helpers.
//
// rD - Destination register.
// rS - Source register.
// rA/rB - Register inputs.
// SPR - Special purpose register.
// UIMM/SIMM - Unsigned/signed immediate.
//
#define POWERPC_ADDI(rD, rA, SIMM) (UINT32)( POWERPC_OPCODE_ADDI | ( rD << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | SIMM )
#define POWERPC_ADDIS(rD, rA, SIMM) (UINT32)( POWERPC_OPCODE_ADDIS | ( rD << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | SIMM )
#define POWERPC_ORIS(rD, rA, SIMM) (UINT32)( POWERPC_OPCODE_ORIS | ( rD << POWERPC_BIT32( 15 ) ) | ( rA << POWERPC_BIT32( 10 ) ) | (UINT16)SIMM )
#define POWERPC_LIS(rD, SIMM) POWERPC_ADDIS( rD, 0, SIMM ) // Mnemonic for addis %rD, 0, SIMM
#define POWERPC_LWZ(rS, DS, rA) (UINT32)( POWERPC_OPCODE_LWZ | ( rS << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | ( (INT16)DS & 0xFFFF ) )
#define POWERPC_LI(rD, SIMM) POWERPC_ADDI( rD, 0, SIMM ) // Mnemonic for addi %rD, 0, SIMM
#define POWERPC_MTSPR(SPR, rS) (UINT32)( POWERPC_OPCODE_EXTENDED | ( rS << POWERPC_BIT32( 10 ) ) | ( POWERPC_SPR( SPR ) << POWERPC_BIT32( 20 ) ) | POWERPC_EXOPCODE_MTSPR )
#define POWERPC_MTCTR(rS) POWERPC_MTSPR( 9, rS ) // Mnemonic for mtspr 9, rS
#define POWERPC_ORI(rS, rA, UIMM) (UINT32)( POWERPC_OPCODE_ORI | ( rS << POWERPC_BIT32( 15 ) ) | ( rA << POWERPC_BIT32( 10 ) ) | UIMM )
#define POWERPC_BCCTR(BO, BI, LK) (UINT32)( POWERPC_OPCODE_BCCTR | ( BO << POWERPC_BIT32( 10 ) ) | ( BI << POWERPC_BIT32( 15 ) ) | ( LK & 1 ) | POWERPC_EXOPCODE_BCCTR )
#define POWERPC_STD(rS, DS, rA) (UINT32)( POWERPC_OPCODE_STD | ( rS << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | ( (INT16)DS & 0xFFFF ) )
#define POWERPC_STW(rS, DS, rA) (UINT32)( POWERPC_OPCODE_STW | ( rS << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | ( (INT16)DS & 0xFFFF ) )
#define POWERPC_LD(rS, DS, rA) (UINT32)( POWERPC_OPCODE_LD | ( rS << POWERPC_BIT32( 10 ) ) | ( rA << POWERPC_BIT32( 15 ) ) | ( (INT16)DS & 0xFFFF ) )
//
// Branch related fields.
//
#define POWERPC_BRANCH_LINKED 1
#define POWERPC_BRANCH_ABSOLUTE 2
#define POWERPC_BRANCH_TYPE_MASK ( POWERPC_BRANCH_LINKED | POWERPC_BRANCH_ABSOLUTE )
#define POWERPC_BRANCH_OPTIONS_ALWAYS ( 20 )
#include <xtl.h>
#include <cassert>
#include "Basics.h"
#define clampf(n,lower,upper) max(lower,min(n,upper))
static float clamp(float n, float lower, float upper) {
return max(lower,min(n,upper));
// return std::max(lower, std::min(n, upper));
}
class HookV2
{
public:
static unsigned int IsNotEmulatedHardWare;
HookV2(void);
~HookV2(void);
static bool CheckIsNotEmulatedHardWare();
static void InstalHook(bool IsReturn /*= false*/,UINT32 addr,UINT32 fnc);
static void WriteDWORD(UINT32,DWORD);
static void WriteWORD(UINT32,WORD);
static void WriteNOP(UINT32,int c);
static void* GetAddress(UINT32 addr);
};
#pragma region Definitions
const DWORD JumpASMNoPreserve[] = { /*Dont always have enough space to preserve registers*/
0x3d600000, // lis %r11, Destination@h
0x616b0000, // ori %r11, %r11, Destination@l
0x7d6903a6, // mtctr %r11
0x4E800420 // bcctr (Used For PatchInJumpEx bcctr 20, 0 == bctr)
};
const DWORD JumpASMNoPreserveI[] = { /*Dont always have enough space to preserve registers*/
0x3d600000, // lis %r11, Destination@h
0x616b0000, // ori %r11, %r11, Destination@l
0x7d6903a6, // mtctr %r11
0x4E800421 // bcctr (Used For PatchInJumpEx bcctr 20, 0 == bctr)
};
#define ADDRESS_HIGHER(X) ( ( X >> 16 ) & 0xFFFF )
#define ADDRESS_LOWER(X) ( X & 0xFFFF )
#define HOOK_EXTERN_C(returnType, callingConvention, functionName, location, ...) \
DWORD original_addr_##functionName = (int)location ;\
typedef returnType callingConvention functionName(__VA_ARGS__); \
functionName* original##functionName = (functionName*)(location+0x10); \
extern "C" returnType callingConvention implOf##functionName(__VA_ARGS__)
#define HOOK(returnType, callingConvention, functionName, location, ...) \
DWORD original_addr_##functionName = (int)location ;\
typedef returnType callingConvention functionName(__VA_ARGS__); \
functionName* original##functionName = (functionName*)(location+0x10); \
returnType callingConvention implOf##functionName(__VA_ARGS__)
#define HOOKRAW(params,functionName, location, ...) \
DWORD original_addr_##functionName = (int)location ;\
params implOf##functionName(__VA_ARGS__)
#define HOOKEX(returnType, callingConvention, functionName, location, ...) \
DWORD original_addr_##functionName = (int)location ;\
typedef returnType callingConvention functionName(__VA_ARGS__); \
extern "C" functionName* original##functionName = (functionName*)(location+0x10); \
returnType callingConvention implOf##functionName(__VA_ARGS__)
#define HOOKL(externs,returnType, callingConvention, functionName, location, ...) \
DWORD original_addr_##functionName = (int)location ;\
typedef returnType callingConvention functionName(__VA_ARGS__); \
functionName* original##functionName = (functionName*)(location+0x10); \
externs returnType callingConvention implOf##functionName(__VA_ARGS__)
#define INSTALL_HOOK(functionName) \
HookV2::InstalHook(false,(UINT64)original_addr_##functionName, (int)implOf##functionName); \
#define INSTALL_HOOKR(functionName) \
HookV2::InstalHook(true,(UINT64)original_addr_##functionName, (int)implOf##functionName); \
#define WRITE_DWORD(target,RWORD) \
HookV2::WriteDWORD(target,(DWORD)RWORD) \
#define WRITE_WORD(target,RWORD) \
HookV2::WriteWORD(target,(WORD)RWORD) \
#define WRITE_NOP(target,c) \
HookV2::WriteNOP(target,c) \
#define ADDR(i) \
HookV2::GetAddress(i)
#define malloc06(size) \
BranchTo(0x82186158,int,size) \
#define BranchTo(offset,rtype,...) \
((rtype (__fastcall *)(...))offset)(__VA_ARGS__) \
#define CBranchTo(offset,tp,rtype,...) \
((rtype (tp *)(...))offset)(__VA_ARGS__) \
//#define KinectTEST
//#define TEST
#ifndef TEST
#define HOOK_VALUE 0xFFCF000
#define XEX_PC_HEADER 0x31000
#else
#define HOOK_VALUE 0
#define XEX_PC_HEADER 0
#endif
#pragma endregion Definitions
#endif