1 |
#ifndef _YEBISOCKS_HOOKER_H_ |
2 |
#define _YEBISOCKS_HOOKER_H_ |
3 |
|
4 |
#include <YCL/Hashtable.h> |
5 |
using namespace yebisuya; |
6 |
|
7 |
class Hooker { |
8 |
private: |
9 |
template<class TYPE> |
10 |
class Ptr { |
11 |
public: |
12 |
static TYPE* cast(void* p, int offset) { |
13 |
return (TYPE*) ((LPBYTE) p + offset); |
14 |
} |
15 |
}; |
16 |
static bool modifyModuleProc(HMODULE module, FARPROC oldproc, FARPROC newproc) { |
17 |
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*) module; |
18 |
if (::IsBadReadPtr(dos, sizeof *dos) || dos->e_magic != IMAGE_DOS_SIGNATURE) { |
19 |
return false; |
20 |
} |
21 |
|
22 |
IMAGE_NT_HEADERS* nt = Ptr<IMAGE_NT_HEADERS>::cast(dos, dos->e_lfanew); |
23 |
if (::IsBadReadPtr(nt, sizeof *nt) || nt->Signature != IMAGE_NT_SIGNATURE) { |
24 |
return false; |
25 |
} |
26 |
|
27 |
IMAGE_IMPORT_DESCRIPTOR* desc = Ptr<IMAGE_IMPORT_DESCRIPTOR>::cast(module, nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); |
28 |
if (desc == (IMAGE_IMPORT_DESCRIPTOR*) nt) { |
29 |
return false; |
30 |
} |
31 |
|
32 |
DWORD o; |
33 |
for (; desc->Name; desc++){ |
34 |
for (IMAGE_THUNK_DATA* thunk = Ptr<IMAGE_THUNK_DATA>::cast(module, desc->FirstThunk); thunk->u1.Function; thunk++){ |
35 |
if ((LPDWORD) thunk->u1.Function == (LPDWORD) oldproc) { |
36 |
if (::VirtualProtect(&thunk->u1.Function, sizeof thunk->u1.Function, PAGE_READWRITE, &o)){ |
37 |
(LPDWORD&) thunk->u1.Function = (LPDWORD) newproc; |
38 |
::VirtualProtect(&thunk->u1.Function, sizeof thunk->u1.Function, o, &o); |
39 |
return true; |
40 |
} |
41 |
} |
42 |
} |
43 |
} |
44 |
return false; |
45 |
} |
46 |
|
47 |
static Hooker& instance() { |
48 |
static Hooker instance; |
49 |
return instance; |
50 |
} |
51 |
|
52 |
Hashtable<FARPROC, FARPROC> proctable; |
53 |
|
54 |
Hooker() { |
55 |
} |
56 |
public: |
57 |
static void hook(HMODULE module, FARPROC oldproc, FARPROC newproc) { |
58 |
modifyModuleProc(module, oldproc, newproc); |
59 |
} |
60 |
static void setup(FARPROC oldproc, FARPROC newproc) { |
61 |
instance().proctable.put(oldproc, newproc); |
62 |
} |
63 |
static void hookAll(HMODULE module) { |
64 |
Pointer< Enumeration<FARPROC> > oldprocs = instance().proctable.keys(); |
65 |
while (oldprocs->hasMoreElements()) { |
66 |
FARPROC oldproc = oldprocs->nextElement(); |
67 |
FARPROC newproc = instance().proctable.get(oldproc); |
68 |
modifyModuleProc(module, oldproc, newproc); |
69 |
} |
70 |
} |
71 |
static void unhookAll(HMODULE module) { |
72 |
Pointer< Enumeration<FARPROC> > oldprocs = instance().proctable.keys(); |
73 |
while (oldprocs->hasMoreElements()) { |
74 |
FARPROC oldproc = oldprocs->nextElement(); |
75 |
FARPROC newproc = instance().proctable.get(oldproc); |
76 |
modifyModuleProc(module, newproc, oldproc); |
77 |
} |
78 |
} |
79 |
static FARPROC find(FARPROC original) { |
80 |
return instance().proctable.get(original); |
81 |
} |
82 |
}; |
83 |
|
84 |
#endif//_YEBISOCKS_HOOKER_H_ |