Hookapi.c
上传用户:chzmdj
上传日期:2007-01-22
资源大小:135k
文件大小:6k
源码类别:

源码/资料

开发平台:

C/C++

  1. /**************************************************************************
  2.     HookApi.C
  3.     Hook and restore window api code in 32 BIT system code.
  4.     
  5.     Hook   : Let application call api function after run my code.
  6.     Restore: Let application call api function no run my code.
  7.     (c) 1996.11 Inventec (TianJin) Co., Ltd.
  8.     Author: FengShuen Lu / ZhenYu Hou / Gang Yan
  9.     Comments:  1. 97.10.08 is version 1.0.
  10. ***************************************************************************/
  11. #include <windows.h>
  12. #include "string.h"
  13. #include "hookapi.h"
  14. #include "dbgfunc.h"
  15. #pragma comment(lib, "k32lib.lib")
  16. DWORD WINAPI VxDCall4(DWORD service_number, DWORD, DWORD, DWORD, DWORD);
  17. #define PC_WRITEABLE 0x00020000
  18. #define PC_USER 0x00040000
  19. #define PC_STATIC 0x20000000
  20. #define BUFFERLEN 7 // 用於定义一个长跳转的字节数·
  21. BOOL g_bCanWrite = FALSE;
  22. //////////////////
  23. WORD callgate1 = 0;
  24. /////////////////
  25. // 用於取得指定模块中指定输出函数的地址·
  26. FARPROC WINAPI getFunctionAddress(HINSTANCE hInst, LPCSTR lpMod, LPCSTR lpFun)
  27. {
  28. HMODULE hMod;
  29. FARPROC procFun;
  30. if (lpMod != NULL)
  31. {
  32. hMod=GetModuleHandle(lpMod);
  33. procFun = GetProcAddress(hMod,lpFun);
  34. }
  35. else
  36. {
  37. procFun = GetProcAddress(hInst,lpFun);
  38. }
  39. return  procFun;
  40. // 用於形成一个32BIT中的长跳转·
  41. void MakeJMPCode(LPBYTE lpJMPCode, LPVOID lpCodePoint)
  42. {
  43. BYTE temp;
  44. WORD wHiWord = HIWORD(lpCodePoint);
  45. WORD wLoWord = LOWORD(lpCodePoint);
  46. WORD wCS;
  47. _asm // 取当前选择符·
  48. {
  49. push ax;
  50. push cs;
  51. pop  ax;
  52. mov  wCS, ax;
  53. pop  ax;
  54. };
  55. lpJMPCode[0] = 0xea; // 填入 JMP 指令的机器码·
  56. temp = LOBYTE(wLoWord); // -------------------------
  57. lpJMPCode[1] = temp;
  58. temp = HIBYTE(wLoWord);
  59. lpJMPCode[2] = temp; // 填入地址·在内存中的顺序为;
  60. temp = LOBYTE(wHiWord); // Point: 0x1234
  61. lpJMPCode[3] = temp; // 内存: 4321
  62. temp = HIBYTE(wHiWord);
  63. lpJMPCode[4] = temp; // -------------------------
  64. temp = LOBYTE(wCS); // 填入选择符·
  65. lpJMPCode[5] = temp;
  66. temp = HIBYTE(wCS);
  67. lpJMPCode[6] = temp;
  68. return;
  69. }
  70. // 使指定指针处的内存可写/不可写·
  71. void MakeMemCanWrite(LPVOID lpMemPoint, BOOL bCanWrite, int nSysMemStatus)
  72. {
  73. switch (nSysMemStatus)
  74. {
  75. case HOOK_NEED_CHECK:
  76.  if (!g_bCanWrite)
  77.  {
  78. SetPageAttributes((DWORD)lpMemPoint, 0x0, 0x2);
  79. g_bCanWrite = TRUE;
  80.  }
  81.  break;
  82. case HOOK_CAN_WRITE:
  83.  SetPageAttributes((DWORD)lpMemPoint, 0x0, 0x2);
  84.  g_bCanWrite = TRUE;
  85.  break;
  86. case HOOK_ONLY_READ:
  87.  SetPageAttributes((DWORD)lpMemPoint, 0x42, 0x0);
  88.  g_bCanWrite = FALSE;
  89.  break;
  90. }
  91. }
  92. void HookWin32Api(LPAPIHOOKSTRUCT lpApiHook, int nSysMemStatus)
  93. { // nSysMemStatus = 0  说明需要检查可写标志·
  94. // nSysMemStatus = 1  说明需要设置状态为可写·
  95. // nSysMemStatus = 2  说明需要设置状态为只读·
  96. BYTE   bWin32Api[5];
  97. bWin32Api[0] = 0x00; 
  98. // 取得被拦截函数地址·
  99. if(lpApiHook->lpWinApiProc == NULL)
  100. {
  101. lpApiHook->lpWinApiProc = (LPVOID)getFunctionAddress(lpApiHook->hInst, lpApiHook->lpszApiModuleName,lpApiHook->lpszApiName);
  102. if (lpApiHook->dwApiOffset != 0)
  103. lpApiHook->lpWinApiProc = (LPVOID)((DWORD)lpApiHook->lpWinApiProc + lpApiHook->dwApiOffset);
  104. }
  105. // 取得替代函数地址·
  106. if(lpApiHook->lpHookApiProc == NULL)
  107. {
  108. lpApiHook->lpHookApiProc = (LPVOID)getFunctionAddress(lpApiHook->hInst, lpApiHook->lpszHookApiModuleName,lpApiHook->lpszHookApiName);
  109. }
  110. // 形成 JMP 指令·
  111. if (lpApiHook->HookApiFiveByte[0] == 0x00)
  112. {
  113. MakeJMPCode(lpApiHook->HookApiFiveByte,lpApiHook->lpHookApiProc);
  114. }
  115. MakeMemCanWrite(lpApiHook->lpWinApiProc, TRUE, HOOK_CAN_WRITE); // 令指定函数指针可写·
  116. if (nSysMemStatus == HOOK_NEED_CHECK)
  117. {
  118. memcpy(lpApiHook->lpWinApiProc, (LPVOID)lpApiHook->HookApiFiveByte,BUFFERLEN);
  119. }
  120. else
  121. {
  122. if (lpApiHook->WinApiFiveByte[0] == 0x00) // 判断是否已经拦截·
  123. {
  124. // 否·
  125. // 备份 API 函数头五个字节·
  126. memcpy(lpApiHook->WinApiFiveByte,(LPVOID)lpApiHook->lpWinApiProc,BUFFERLEN);
  127. // 判断是否重复拦截·(即判断备份的头五个字节是否为形成的JMP指令)
  128. if (strncmp(lpApiHook->WinApiFiveByte, lpApiHook->HookApiFiveByte, BUFFERLEN) == 0)
  129. {
  130. // 恢复备份的字节·
  131. memcpy(lpApiHook->WinApiFiveByte,(LPVOID)lpApiHook->WinApiBakByte,BUFFERLEN);
  132. }
  133. }
  134. else
  135. {
  136. // 是·
  137. memcpy(bWin32Api,(LPVOID)lpApiHook->lpWinApiProc,BUFFERLEN);
  138. }
  139. if (strncmp(bWin32Api, lpApiHook->HookApiFiveByte, BUFFERLEN) != 0)
  140. {
  141. // 将 JMP 指定填入 API 函数的头·
  142. memcpy(lpApiHook->lpWinApiProc, (LPVOID)lpApiHook->HookApiFiveByte,BUFFERLEN);
  143. }
  144. }
  145. MakeMemCanWrite(lpApiHook->lpWinApiProc, FALSE, HOOK_ONLY_READ); // 
  146. }
  147. void RestoreWin32Api(LPAPIHOOKSTRUCT lpApiHook, int nSysMemStatus)
  148. { // nSysMemStatus = 0  说明需要检查可写标志·
  149. // nSysMemStatus = 1  说明需要设置状态为可写·
  150. // nSysMemStatus = 2  说明需要设置状态为只读·
  151. if (lpApiHook->lpWinApiProc == NULL)
  152. return;
  153. MakeMemCanWrite(lpApiHook->lpWinApiProc, TRUE, HOOK_CAN_WRITE); // 令指定函数指针可写·
  154. memcpy(lpApiHook->lpWinApiProc,(LPVOID)lpApiHook->WinApiFiveByte,BUFFERLEN);
  155. MakeMemCanWrite(lpApiHook->lpWinApiProc, FALSE, HOOK_ONLY_READ);
  156. }
  157. ////////////////////////////////////////////////////////////////////////////////
  158. //==================================
  159. // PHYS - Matt Pietrek 1995
  160. // FILE: PHYS.C
  161. //==================================
  162. DWORD SetPageAttributes(DWORD linear, DWORD dwAndParam, DWORD dwOrParam )
  163. {
  164.     WORD myFwordPtr[3];
  165.     //if ( !callgate1 )
  166.         callgate1 = GetRing0Callgate( (DWORD)_SetPageAttributes, 3 );
  167.     
  168.     if ( callgate1 )
  169.     {
  170.         WORD myFwordPtr[3];
  171.         
  172.         myFwordPtr[2] = callgate1;
  173.         __asm   push    [linear]
  174. __asm   push    [dwOrParam]
  175. __asm   push    [dwAndParam]
  176.         __asm   cli
  177.         __asm   call    fword ptr [myFwordPtr]
  178.         __asm   sti
  179.         // The return value is in EAX.  The compiler will complain, but...
  180.     }
  181.     else
  182.         return 0xFFFFFFFF;
  183. FreeRing0Callgate( callgate1 );
  184. }