ApiHook.h
上传用户:jstlsd
上传日期:2007-01-13
资源大小:186k
文件大小:9k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. //---------------------------------------------------------------------------
  2. //
  3. // ApiHook.h
  4. //
  5. // SUBSYSTEM: 
  6. // API Hooking system
  7. // MODULE:    
  8. // ApiHook is the main module of the hooking system
  9. //
  10. // DESCRIPTION:
  11. //
  12. // AUTHOR: Ivo Ivanov (ivopi@hotmail.com)
  13. //              Some part of ReplaceInOneModule() implementation is based 
  14. //              on code published by Jeffrey Richter and John Robbins.
  15. //
  16. // DATE: 2000 May 05,  version 1.0 
  17. //              2001 June 29, version 2.0
  18. //              2002 November 30. version 2.1
  19. //
  20. // FIXES:
  21. //              - 2002 May 08
  22. //                Fixed bug that used to cause an access violation 
  23. //                if a hooked application calls GetProcAddress() API with an 
  24. //                ordinal value rather than string function name. For more 
  25. //                details see the implementation of 
  26. //                CHookedFunction* CHookedFunctions::GetHookedFunction( 
  27. //                    PCSTR pszCalleeModName, PCSTR pszFuncName )
  28. //              - 2002 July 25
  29. //                A newly created object CHookedFunction must be always inserted 
  30. //                in the collection, even the HookImport() method returns FALSE. 
  31. //                This solve the problem with dynamically imported functions that 
  32. //                haven't been found in the IAT during the initial call to AddHook() 
  33. //              - 2002 August 27
  34. //                Fixed bug related to storing incorrect values of the full path 
  35. //                name of the DLL in the map. In fact we need to get only the name 
  36. //                and extension parts of the full file name.
  37. //              - 2002 November 30
  38. //                Added two methods of class CHookedFunctions 
  39. //                (GetFunctionNameFromExportSection() and GetFunctionNameByOrdinal()) 
  40. //                for handling scenarios where the function for spying is imported by 
  41. //                number. This should allow a user of the library to easily intercept 
  42. //                Windows socket APIs that are usually imported by ordinal value. 
  43. //                Added critical section in CApiHookMgr::MyGetProcAddress() method 
  44. //                                                                         
  45. //---------------------------------------------------------------------------
  46. #if !defined(_APIHOOK_H_)
  47. #define _APIHOOK_H_
  48. #if _MSC_VER > 1000
  49. #pragma once
  50. #endif // _MSC_VER > 1000
  51. //---------------------------------------------------------------------------
  52. //
  53. // Includes
  54. //
  55. //---------------------------------------------------------------------------
  56. #include <map>
  57. #include <string>
  58. using namespace std;
  59. #include "..CommonModuleInstance.h"
  60. #include "..CommonLockMgr.h"
  61. //---------------------------------------------------------------------------
  62. //
  63. // Forward declarations
  64. //
  65. //---------------------------------------------------------------------------
  66. class CModuleScope;
  67. class CHookedFunctions;
  68. //---------------------------------------------------------------------------
  69. //
  70. // class CApiHookMgr
  71. //  
  72. //---------------------------------------------------------------------------
  73. class CApiHookMgr  
  74. {
  75. public:
  76. CApiHookMgr(CModuleScope* pModuleScope);
  77. virtual ~CApiHookMgr();
  78. public:
  79. //
  80. // Hook up an API 
  81. //
  82. BOOL HookImport(
  83. PCSTR pszCalleeModName, 
  84. PCSTR pszFuncName, 
  85. PROC  pfnHook
  86. );
  87. //
  88. // Restore hooked up API function
  89. //
  90. BOOL UnHookImport(
  91. PCSTR pszCalleeModName, 
  92. PCSTR pszFuncName
  93. );
  94. // 
  95. // Hook all needed system functions in order to trap loading libraries
  96. //
  97. BOOL HookSystemFuncs();
  98. // 
  99. // Unhook all functions and restore original ones
  100. //
  101. void UnHookAllFuncs();
  102. //
  103. // Indicates whether there is hooked function
  104. //
  105. BOOL AreThereHookedFunctions();
  106. private:
  107. //
  108. // Let's allow CApiHookMgr to access private methods of CHookedFunction    
  109. //
  110. friend class CHookedFunction;
  111. //
  112. // A pointer to the main engine object
  113. //
  114. static CModuleScope* sm_pModuleScope;
  115. //
  116. // Create a critical section on the stack
  117. //
  118. static CCSWrapper sm_CritSec;
  119. //
  120. // Handle to current module
  121. //
  122. HMODULE m_hmodThisInstance;
  123. //
  124. // Container keeps track of all hacked functions
  125. // 
  126. static CHookedFunctions* sm_pHookedFunctions;
  127. //
  128. // Determines whether all system functions has been successfuly hacked
  129. //
  130. BOOL m_bSystemFuncsHooked;
  131. //
  132. // Used when a DLL is newly loaded after hooking a function
  133. //
  134. static void WINAPI HackModuleOnLoad(
  135. HMODULE hmod, 
  136. DWORD   dwFlags
  137. );
  138. //
  139. // Used to trap events when DLLs are loaded 
  140. //
  141. static HMODULE WINAPI MyLoadLibraryA(
  142. PCSTR  pszModuleName
  143. );
  144. static HMODULE WINAPI MyLoadLibraryW(
  145. PCWSTR pszModuleName
  146. );
  147. static HMODULE WINAPI MyLoadLibraryExA(
  148. PCSTR  pszModuleName, 
  149. HANDLE hFile, 
  150. DWORD  dwFlags
  151. );
  152. static HMODULE WINAPI MyLoadLibraryExW(
  153. PCWSTR pszModuleName, 
  154. HANDLE hFile, 
  155. DWORD  dwFlags
  156. );
  157. //
  158. // Returns address of replacement function if hooked function is requested
  159. //
  160. static FARPROC WINAPI MyGetProcAddress(
  161. HMODULE hmod, 
  162. PCSTR   pszProcName
  163. );
  164. //
  165. // Returns original address of the API function
  166. //
  167. static FARPROC WINAPI GetProcAddressWindows(
  168. HMODULE hmod, 
  169. PCSTR   pszProcName
  170. );
  171. //
  172. // Add a newly intercepted function to the container
  173. //
  174. BOOL AddHook(
  175. PCSTR  pszCalleeModName, 
  176. PCSTR  pszFuncName, 
  177. PROC   pfnOrig,
  178. PROC   pfnHook
  179. );
  180. //
  181. // Remove intercepted function from the container
  182. //
  183. BOOL RemoveHook(
  184. PCSTR pszCalleeModName, 
  185. PCSTR pszFuncName
  186. );
  187. };
  188. //---------------------------------------------------------------------------
  189. //
  190. // class CHookedFunction
  191. //  
  192. //---------------------------------------------------------------------------
  193. class CHookedFunction  
  194. {
  195. public:
  196. CHookedFunction(
  197. CHookedFunctions* pHookedFunctions,
  198. PCSTR             pszCalleeModName, 
  199. PCSTR             pszFuncName, 
  200. PROC              pfnOrig,
  201. PROC              pfnHook
  202. );
  203. virtual ~CHookedFunction();
  204.     PCSTR Get_CalleeModName() const;
  205. PCSTR Get_FuncName() const;
  206. PROC Get_pfnHook() const;
  207. PROC Get_pfnOrig() const;
  208. //
  209. // Set up a new hook function
  210. //
  211. BOOL HookImport();
  212. //
  213. // Restore the original API handler
  214. //
  215. BOOL UnHookImport();
  216. //
  217. // Replace the address of the function in the IAT of a specific module
  218. //
  219. BOOL ReplaceInOneModule(
  220. PCSTR   pszCalleeModName, 
  221. PROC    pfnCurrent, 
  222. PROC    pfnNew, 
  223. HMODULE hmodCaller
  224. );
  225. //
  226. // Indicates whether the hooked function is mandatory one
  227. //
  228. BOOL IsMandatory();
  229. private:
  230. CHookedFunctions* m_pHookedFunctions;
  231. BOOL              m_bHooked;
  232. char              m_szCalleeModName[MAX_PATH];
  233. char              m_szFuncName[MAX_PATH];
  234. PROC              m_pfnOrig;
  235. PROC              m_pfnHook;
  236. //
  237. // Maximum private memory address
  238. //
  239. static  PVOID   sm_pvMaxAppAddr;    
  240. //
  241. // Perform actual replacing of function pointers
  242. // 
  243. BOOL DoHook(
  244. BOOL bHookOrRestore,
  245. PROC pfnCurrent, 
  246. PROC pfnNew
  247. );
  248. //
  249. // Replace the address of a imported function entry  in all modules
  250. //
  251. BOOL ReplaceInAllModules(
  252. BOOL   bHookOrRestore,
  253. PCSTR  pszCalleeModName, 
  254. PROC   pfnCurrent, 
  255. PROC   pfnNew
  256. );
  257. };
  258. //---------------------------------------------------------------------------
  259. //
  260. // class CNocaseCmp
  261. //
  262. // Implements case-insensitive string compare
  263. //
  264. //---------------------------------------------------------------------------
  265. class CNocaseCmp
  266. {
  267. public:
  268. //
  269. // A built-in highly efficient method for case-insensitive string compare.
  270. // Returns true, when string x is less than string y
  271. //
  272. bool operator()(const string& x, const string& y) const
  273. {
  274. return ( stricmp(x.c_str(), y.c_str()) < 0 );
  275. }
  276. };
  277. //---------------------------------------------------------------------------
  278. //
  279. // class CHookedFunctions
  280. //
  281. //---------------------------------------------------------------------------
  282. class CHookedFunctions: public map<string, CHookedFunction*, CNocaseCmp>
  283. {
  284. public:
  285. CHookedFunctions(CApiHookMgr* pApiHookMgr);
  286. virtual ~CHookedFunctions();
  287. public:
  288. // 
  289. // Return the address of an CHookedFunction object
  290. //
  291. CHookedFunction* GetHookedFunction( 
  292. PCSTR pszCalleeModName, 
  293. PCSTR pszFuncName
  294. );
  295. //
  296. // Return the address of an CHookedFunction object
  297. //
  298. CHookedFunction* GetHookedFunction( 
  299. HMODULE hmod, 
  300. PCSTR   pszFuncName
  301. );
  302. //
  303. // Add a new object to the container
  304. //
  305. BOOL AddHook(CHookedFunction* pHook);
  306. //
  307. // Remove exising object pointer from the container
  308. //
  309. BOOL RemoveHook(CHookedFunction* pHook);
  310. private:
  311. //  
  312. // Return the name of the function from EAT by its ordinal value
  313. //
  314. BOOL GetFunctionNameFromExportSection(
  315. HMODULE hmodOriginal,
  316. DWORD   dwFuncOrdinalNum,
  317. PSTR    pszFuncName
  318. ); 
  319. //  
  320. // Return the name of the function by its ordinal value
  321. //
  322. void GetFunctionNameByOrdinal(
  323. PCSTR   pszCalleeModName, 
  324. DWORD   dwFuncOrdinalNum,
  325. PSTR    pszFuncName
  326. );
  327. CApiHookMgr* m_pApiHookMgr;
  328. };
  329. #endif // !defined(_APIHOOK_H_)
  330. //----------------------End of file -----------------------------------------------------