Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
FnHook.h
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #include <windows.h>
4 #include <map>
5 #include <string>
6 #include <DbgHelp.h>
7 #pragma comment(lib, "DbgHelp.lib")
8 
9 class FnHook
10 {
11 public:
12 
13  typedef struct FnEntry
14  {
15  HANDLE pModule;
16  PIMAGE_IMPORT_DESCRIPTOR pImageDsc;
17  PIMAGE_THUNK_DATA pThunkDat;
18  UINT uThunkIdx;
19  UINT uFnHint;
20  PVOID ppFnOld;
21  PVOID ppFnNew;
22  PVOID ppFnAdr;
23  }FnEntry;
24 
25  std::map<std::string,FnEntry> vFn;
26 
27 
28 
29  void HookFunction( CHAR *pSrc, CHAR *pDst, UINT uHint, PVOID pFnNew )
30  {
31  PSTR pName;
32  ULONG ulSize;
33  FnEntry fn;
34  memset(&fn,0,sizeof(fn));
35 
36  fn.ppFnNew = &pFnNew;
37  fn.uFnHint = uHint;
38  fn.pModule = GetModuleHandleA(pSrc);
39 
40  fn.pImageDsc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData( fn.pModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize );
41  while( fn.pImageDsc->Name )
42  {
43  pName = (PSTR) ( (PBYTE)fn.pModule + fn.pImageDsc->Name );
44  if( lstrcmpiA(pDst, pName) == 0 )
45  goto Hook0;
46  fn.pImageDsc++;
47  }
48  return;
49 
50  Hook0:
51 
52  fn.pThunkDat = (PIMAGE_THUNK_DATA) ( (PBYTE)fn.pModule + fn.pImageDsc->OriginalFirstThunk );
53  while( fn.pThunkDat )
54  {
55  IMAGE_IMPORT_BY_NAME* pImp = (IMAGE_IMPORT_BY_NAME*)((PBYTE)fn.pModule+fn.pThunkDat->u1.AddressOfData);
56  if( pImp->Hint == uHint )
57  {
58  fn.pThunkDat = (PIMAGE_THUNK_DATA) ( (PBYTE)fn.pModule + fn.pImageDsc->FirstThunk );
59  fn.ppFnAdr = &((fn.pThunkDat+fn.uThunkIdx)->u1.Function);
60  goto Hook1;
61  }
62  fn.uThunkIdx++;
63  fn.pThunkDat++;
64  }
65  return;
66 
67  Hook1:
68 
69  fn.ppFnOld = WriteFn( fn.ppFnAdr, fn.ppFnNew );
70 
71  CHAR Hint[5];
72  sprintf_s(Hint, "%4.4X", uHint);
73  std::string key = std::string(pSrc)+"|"
74  + std::string(pDst)+"|"
75  + std::string(Hint);
76 
77  auto fnIt = vFn.find(key);
78  if( fnIt == vFn.end() )
79  {
80  vFn.insert( std::make_pair(key, fn) );
81  }
82  }
83 
84  void UnHookFunction( CHAR *pSrc, CHAR *pDst, UINT uHint )
85  {
86  CHAR Hint[5];
87  sprintf_s(Hint, "%4.4X", uHint);
88  std::string key = std::string(pSrc)+"|"
89  + std::string(pDst)+"|"
90  + std::string(Hint);
91 
92  auto fnIt = vFn.find(key);
93  if( fnIt != vFn.end() )
94  {
95  WriteFn( fnIt->second.ppFnAdr, fnIt->second.ppFnOld );
96  vFn.erase( fnIt );
97  }
98 
99  return;
100  }
101 
102  void UnHookAll()
103  {
104  for( auto fnIt = vFn.begin(); fnIt != vFn.end(); fnIt++ )
105  {
106  WriteFn( fnIt->second.ppFnAdr, fnIt->second.ppFnOld );
107  }
108  vFn.clear();
109  }
110 
111  PVOID WriteFn( PVOID ppFnAdr, PVOID ppFnNew )
112  {
113  BOOL bProtectResult = FALSE;
114  DWORD dwOldProtect = 0;
115  SIZE_T sBytes;
116  PVOID ppFnOld=NULL;
117 
118  MEMORY_BASIC_INFORMATION memInfo;
119  if( VirtualQuery(ppFnAdr, &memInfo, sizeof( memInfo ) ) > 0 )
120  {
121  bProtectResult = VirtualProtect( memInfo.BaseAddress, memInfo.RegionSize, PAGE_READWRITE, &dwOldProtect );
122 
123  ReadProcessMemory( GetCurrentProcess(), ppFnAdr, &ppFnOld, sizeof(PROC*), &sBytes );
124  WriteProcessMemory( GetCurrentProcess(), ppFnAdr, ppFnNew, sizeof(PROC*), &sBytes );
125 
126  // restore the page to its old protect status
127  bProtectResult = VirtualProtect( memInfo.BaseAddress, memInfo.RegionSize, PAGE_READONLY, &dwOldProtect );
128  }
129 
130  return ppFnOld;
131  }
132 
133 };
HANDLE pModule
Definition: FnHook.h:15
PVOID WriteFn(PVOID ppFnAdr, PVOID ppFnNew)
Definition: FnHook.h:111
struct FnHook::FnEntry FnEntry
UINT uFnHint
Definition: FnHook.h:19
PIMAGE_IMPORT_DESCRIPTOR pImageDsc
Definition: FnHook.h:16
void UnHookAll()
Definition: FnHook.h:102
Definition: FnHook.h:9
std::map< std::string, FnEntry > vFn
Definition: FnHook.h:25
o fn
PIMAGE_THUNK_DATA pThunkDat
Definition: FnHook.h:17
PVOID ppFnOld
Definition: FnHook.h:20
PVOID ppFnAdr
Definition: FnHook.h:22
PVOID ppFnNew
Definition: FnHook.h:21
Definition: FnHook.h:13
void UnHookFunction(CHAR *pSrc, CHAR *pDst, UINT uHint)
Definition: FnHook.h:84
void HookFunction(CHAR *pSrc, CHAR *pDst, UINT uHint, PVOID pFnNew)
Definition: FnHook.h:29
UINT uThunkIdx
Definition: FnHook.h:18