-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvtblhook.h
102 lines (89 loc) · 1.78 KB
/
vtblhook.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
#ifndef MEMY_VTBL_HOOK_H
#define MEMY_VTBL_HOOK_H
#ifdef _WIN32
#pragma once
#endif
#include "memytools.h"
/* ======== SourceHook ========
* Copyright (C) 2004-2010 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
template<typename FUNC_TYPE>
int GetFunctionOffset( FUNC_TYPE func )
{
#if defined(GNUC)
union
{
FUNC_TYPE ptr;
int delta;
};
ptr = func;
if ( delta & 1 )
return ( delta - 1 ) / sizeof( void * );
return delta / sizeof( void * );
#elif defined(_MSC_VER)
union
{
FUNC_TYPE ptr;
byte *addr;
};
ptr = func;
if ( *addr == 0xE9 )
{
addr += 5 + *(ulong *)( addr + 1 );
}
bool ok = false;
if ( addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 &&
addr[4] == 0x8B && addr[5] == 0x00 )
{
addr += 6;
ok = true;
}
else if ( addr[0] == 0x8B && addr[1] == 0x01 )
{
addr += 2;
ok = true;
}
else if ( addr[0] == 0x48 && addr[1] == 0x8B && addr[2] == 0x01 )
{
addr += 3;
ok = true;
}
if ( !ok )
return -1;
if ( *addr++ == 0xFF )
{
if ( *addr == 0x60 )
{
return *++addr / sizeof( void * );
}
else if ( *addr == 0xA0 )
{
return *( (uint *)++addr ) / sizeof( void * );
}
else if ( *addr == 0x20 )
return 0;
else
return -1;
}
return -1;
#endif
}
template<typename F, typename H>
F HookVTable( void *pObject, F pFunc, H hook )
{
void **vtbl = *(void ***)pObject;
int index = GetFunctionOffset( pFunc );
void **vtbl_func = (void **)vtbl[index];
memy::SetMemoryProtection( vtbl_func, sizeof( void * ), MEM_READ|MEM_WRITE|MEM_EXEC );
F original = *(F *)vtbl_func;
*vtbl_func = *(void **)&hook;
memy::SetMemoryProtection( vtbl_func, sizeof( void * ), MEM_READ|MEM_EXEC );
return original;
}
#endif