-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhook_new.c
138 lines (117 loc) · 3.53 KB
/
hook_new.c
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
#include "hook_new.h"
pBitBlt origBitBlt = NULL;
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
{
BOOL result = FALSE;
// get handle of gdi32.dll
HANDLE hGdi = GetModuleHandleA("gdi32.dll");
if (hGdi)
{
// get BitBlt base address
pBitBlt BitBlt_base = (pBitBlt) GetProcAddress(hGdi, "BitBlt");
if (BitBlt_base)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
// install hook
result = HotPatch((void*) BitBlt_base,
(void*) fake_BitBlt,
(void**) &origBitBlt);
break;
case DLL_PROCESS_DETACH:
// uninstall hook
result = HotUnpatch((void*) BitBlt_base);
break;
}
}
CloseHandle(hGdi);
}
return result;
}
BOOL WINAPI fake_BitBlt(HDC hdcDest,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
HDC hdcSrc,
int nXSrc,
int nYSrc,
DWORD dwRop)
{
if (SRCCOPY == dwRop)
{
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
else if (origBitBlt)
{
return origBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop);
}
}
BOOL HotPatch(void * procBase, void * hookBase, void ** ppOrigFn)
{
BOOL result = FALSE;
// get patch address
BYTE * patchBase = (BYTE*) procBase - LONG_JMP_SIZE;
// check if function hotpatchable
if (LONG_NOP != *((WORD*) procBase)
|| PATTERN1 != *((DWORD*) patchBase)
&& PATTERN2 != *((DWORD*) patchBase))
{
// not hotpachable function
SetLastError(ERROR_INVALID_FUNCTION);
}
else
{
DWORD oldProtect;
// get write access
if (VirtualProtect(patchBase, PATCH_SIZE,
PAGE_EXECUTE_WRITECOPY, &oldProtect))
{
// write long jump opcode
*patchBase = LONG_JMP;
// write long jump offset
*((DWORD*) procBase - 1) = (DWORD) hookBase - (DWORD) procBase;
// write short jump
*((WORD*) procBase) = SHORT_JMP;
result = TRUE;
// restore protection
VirtualProtect(patchBase, PATCH_SIZE, oldProtect, &oldProtect);
// store address of original function code
if (ppOrigFn)
{
*ppOrigFn = (BYTE*) procBase + SHORT_JMP_SIZE;
}
}
}
return result;
}
BOOL HotUnpatch(void * procBase)
{
BOOL result = FALSE;
if (SHORT_JMP != *((WORD*) procBase))
{
// not hotpatched function
SetLastError(ERROR_INVALID_FUNCTION);
}
else
{
DWORD oldProtect;
// get patch address
BYTE * patchBase = (BYTE*) procBase - LONG_JMP_SIZE;
// get write access
if (VirtualProtect(patchBase, PATCH_SIZE,
PAGE_EXECUTE_WRITECOPY, &oldProtect))
{
// remove short jump
*((WORD*) procBase) = LONG_NOP;
// remove long jump
memset(patchBase, NOP, LONG_JMP_SIZE);
result = TRUE;
// restore protection
VirtualProtect(patchBase, PATCH_SIZE, oldProtect, &oldProtect);
}
}
return result;
}