Hook之前要干掉PG:http://www.m5home.com/bbs/thread-5893-1-1.html

上篇文章知道了寻找SSDT表的方法,这篇记录一下如何实现SSDT表的Hook。

下面以Hook NtOpenProcess为例,之前我查SSDT表发现NtOpenProcess函数的标号为35,用XT等工具也能查看。

废话不多说,上代码。

[cpp] view plaincopy
  1. 首先感谢老大(Tesla.Angela)对我的帮助
  2. //相关声明
  3. __int64 __readmsr(int register);
  4. unsigned __int64 __readcr0(void);
  5. void __writecr0(
  6. unsigned __int64 Data
  7. );
  8. void _disable(void);
  9. void _enable(void);
  10. //_SYSTEM_SERVICE_TABLE结构声明
  11. typedef struct _SYSTEM_SERVICE_TABLE{
  12. PVOID       ServiceTableBase;
  13. PVOID       ServiceCounterTableBase;
  14. ULONGLONG   NumberOfServices;
  15. PVOID       ParamTableBase;
  16. } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
  17. //_SERVICE_DESCRIPTOR_TABLE结构声明
  18. typedef struct _SERVICE_DESCRIPTOR_TABLE{
  19. SYSTEM_SERVICE_TABLE ntoskrnl;  // ntoskrnl.exe (native api)
  20. SYSTEM_SERVICE_TABLE win32k;    // win32k.sys   (gdi/user)
  21. SYSTEM_SERVICE_TABLE Table3;    // not used
  22. SYSTEM_SERVICE_TABLE Table4;    // not used
  23. }SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
  24. //声明要寻找进程名用的函数
  25. NTKERNELAPI UCHAR * PsGetProcessImageFileName(PEPROCESS Process);
  26. //定义NTOPENPROCESS
  27. typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE  ProcessHandle,
  28. IN ACCESS_MASK  DesiredAccess,
  29. IN POBJECT_ATTRIBUTES  ObjectAttributes,
  30. IN OPTIONAL PCLIENT_ID  ClientId);
  31. NTOPENPROCESS OldOpenProcess = NULL;
  32. ULONG OldTpVal;
  33. //定义自己的NtOpenProcess
  34. NTSTATUS __stdcall Fake_NtOpenProcess(OUT PHANDLE  ProcessHandle,
  35. IN ACCESS_MASK  DesiredAccess,
  36. IN POBJECT_ATTRIBUTES  ObjectAttributes,
  37. IN OPTIONAL PCLIENT_ID  ClientId)
  38. {
  39. PEPROCESS process = NULL;
  40. NTSTATUS st = ObReferenceObjectByHandle(<span style="font-family: Arial, Helvetica, sans-serif;">ClientId->processid</span>
  41. ,0,*PsProcessType,KernelMode,&process,NULL);
  42. DbgPrint("进入HOOK函数.\n");
  43. if (NT_SUCCESS(st))
  44. {
  45. if (!_stricmp((char*)PsGetProcessImageFileName(process),"CrackMe3.exe"))
  46. {
  47. return STATUS_ACCESS_DENIED;
  48. }
  49. else
  50. {
  51. return OldOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
  52. }
  53. }
  54. else
  55. {
  56. return STATUS_ACCESS_DENIED;
  57. }
  58. }
  59. //关闭页面保护
  60. KIRQL WPOFFx64()
  61. {
  62. KIRQL irql=KeRaiseIrqlToDpcLevel();
  63. UINT64 cr0=__readcr0();
  64. cr0 &= 0xfffffffffffeffff;
  65. __writecr0(cr0);
  66. _disable();
  67. return irql;
  68. }
  69. //开启页面保护
  70. void WPONx64(KIRQL irql)
  71. {
  72. UINT64 cr0=__readcr0();
  73. cr0 |= 0x10000;
  74. _enable();
  75. __writecr0(cr0);
  76. KeLowerIrql(irql);
  77. }
  78. //老外定位KeServiceDescriptorTable的方法
  79. ULONGLONG GetKeServiceDescriptorTable64()
  80. {
  81. char KiSystemServiceStart_pattern[] = "\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x25\xFF\x0F\x00\x00";   //特征码
  82. ULONGLONG CodeScanStart = (ULONGLONG)&_strnicmp;
  83. ULONGLONG CodeScanEnd = (ULONGLONG)&KdDebuggerNotPresent;
  84. UNICODE_STRING Symbol;
  85. ULONGLONG i, tbl_address, b;
  86. for (i = 0; i < CodeScanEnd - CodeScanStart; i++)
  87. {
  88. if (!memcmp((char*)(ULONGLONG)CodeScanStart +i, (char*)KiSystemServiceStart_pattern,13))
  89. {
  90. for (b = 0; b < 50; b++)
  91. {
  92. tbl_address = ((ULONGLONG)CodeScanStart+i+b);
  93. if (*(USHORT*) ((ULONGLONG)tbl_address ) == (USHORT)0x8d4c)
  94. return ((LONGLONG)tbl_address +7) + *(LONG*)(tbl_address +3);
  95. }
  96. }
  97. }
  98. return 0;
  99. }
  100. //根据KeServiceDescriptorTable找到SSDT基址
  101. PULONG GetSSDTBaseAddress()
  102. {
  103. PULONG addr = NULL;
  104. PSYSTEM_SERVICE_TABLE ssdt = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable64();
  105. addr = (PULONG)(ssdt->ServiceTableBase);
  106. return addr;
  107. }
  108. //根据标号找到SSDT表中函数的地址
  109. ULONGLONG GetFuncAddr(ULONG id)
  110. {
  111. LONG dwtmp = 0;
  112. ULONGLONG addr = 0;
  113. PULONG stb = NULL;
  114. stb = GetSSDTBaseAddress();
  115. dwtmp = stb[id];
  116. dwtmp = dwtmp >> 4;
  117. addr = (LONGLONG)dwtmp + (ULONGLONG)stb;
  118. DbgPrint("SSDT TABLE BASEADDRESS:%llx",addr);
  119. return addr;
  120. }
  121. //设置函数的偏移地址,注意其中参数的处理。低四位放了参数个数减4个参数。如果参数小于等于4的时候为0
  122. #define SETBIT(x,y) x|=(1<<y) //将X的第Y位置1
  123. #define CLRBIT(x,y) x&=~(1<<y) //将X的第Y位清0
  124. #define GETBIT(x,y) (x & (1 << y)) //取X的第Y位,返回0或非0
  125. ULONG GetOffsetAddress(ULONGLONG FuncAddr, CHAR paramCount)
  126. {
  127. LONG dwtmp = 0,i;
  128. CHAR b = 0, bits[4] = {0};
  129. PULONG stb = NULL;
  130. stb = GetSSDTBaseAddress();
  131. dwtmp = (LONG)(FuncAddr - (ULONGLONG)stb);
  132. dwtmp = dwtmp << 4;
  133. if (paramCount>4)
  134. {
  135. paramCount = paramCount - 4;
  136. }
  137. else
  138. {
  139. paramCount = 0;
  140. }
  141. memcpy(&b,&dwtmp,1);
  142. for (i=0;i<4;i++)
  143. {
  144. bits[i] = GETBIT(paramCount,i);
  145. if (bits[i])
  146. {
  147. SETBIT(b,i);
  148. }
  149. else
  150. {
  151. CLRBIT(b,i);
  152. }
  153. }
  154. memcpy(&dwtmp,&b,1);
  155. return dwtmp;
  156. }
  157. //内核中用不到的方法,二次跳转用(自己的NtOpenProcess跳到KeBugCheckEx函数,然后再KeBugCheckEx函数跳到要Hook的NtOpenProcess)
  158. VOID FuckKeBugCheckEx()
  159. {
  160. KIRQL irql;
  161. ULONGLONG myfun;
  162. UCHAR jmp_code[]="\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
  163. myfun=(ULONGLONG)Fake_NtOpenProcess;
  164. memcpy(jmp_code+6,&myfun,8);
  165. irql=WPOFFx64();
  166. memset(KeBugCheckEx,0x90,15);
  167. memcpy(KeBugCheckEx,jmp_code,14);
  168. WPONx64(irql);
  169. }
  170. //Hook ssdt
  171. VOID HookSSDT()
  172. {
  173. KIRQL irql;
  174. LONG dwtmp = 0;
  175. PULONG stb = NULL;
  176. //1.get old address
  177. OldOpenProcess = (NTOPENPROCESS)GetFuncAddr(35);
  178. DbgPrint("Old_NtOpenProcess:%llx",(ULONGLONG)OldOpenProcess);
  179. //2.show new address
  180. stb = GetSSDTBaseAddress();
  181. //3.get offset value
  182. dwtmp = GetOffsetAddress((ULONGLONG)KeBugCheckEx,4);
  183. //set kebugcheckex
  184. FuckKeBugCheckEx();
  185. //4.record  old offset  value
  186. OldTpVal = stb[35];
  187. irql = WPOFFx64();
  188. stb[35] = GetOffsetAddress((ULONGLONG)KeBugCheckEx,2);
  189. WPONx64(irql);
  190. DbgPrint("KeBugCheckEx:%llx",(ULONGLONG)KeBugCheckEx);
  191. DbgPrint("New_NtOpenProcess:%llx",GetFuncAddr(35));
  192. }
  193. //UN hook
  194. VOID UnhookSSDT()
  195. {
  196. KIRQL irql;
  197. PULONG stb=NULL;
  198. stb = GetSSDTBaseAddress();
  199. //老函数的地址复制回来
  200. irql=WPOFFx64();
  201. stb[35]=OldTpVal;
  202. WPONx64(irql);
  203. }

相关解释:

1.为什么要二次跳转?

WIN64内核里的每个驱动都不在同一个4GB里,4字节的整数只能表示4GB的范围,所以不管怎么修改这个4字节都不会跳到你的代理函数,因为你的驱动不可能跟NTOSKRNL在同一个4GB里面。

2.参数的处理:

函数地址的低四位存放了函数参数个数减4的数字,如果参数为5,那么低四位的数字为1,如果参数个数小于等于4个,低四位的数位0,可以再WINDBG里面查看到。

Win7 64位的SSDTHOOK(2)---64位SSDT hook的实现相关推荐

  1. Win7 64位的SSDTHOOK(1)---SSDT表的寻找

    最近在学习64位驱动,涉及到了SSDT的知识,结果发现64位下的SSDT和32位下的SSDT有所不同. 开始发现64位下的KeServiceDescriptorTable是未导出的函数.首先要找到Ke ...

  2. 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)2014.05 系统下载

    最新 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)2014.05 系统下载系统下载,由系统下载吧率先分享: 雨林木风 GHOST WIN7 SP1 X64旗舰装机版(64位)20 ...

  3. 图解无约而来Win7 33in1 V1.3 32位与64位合一(版本齐全装机利器)

    图解无约而来Win7 33in1 V1.3 32位与64位合一(版本齐全装机利器) 2012-07-17 11:32:31|  分类: 默认分类 |  标签: |字号大中小 订阅 无约而来近日发布了将 ...

  4. 64位计算机不能运行32位游戏,我想玩个游戏,仅支援64位系统,我家电脑win7 32位的,怎么办求解决方法...

    我想玩个游戏,仅支援64位系统,我家电脑win7 32位的,怎么办求解决方法以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧 ...

  5. Win7可用的笔记本电池校正软件( 64、32位)

    Win7可用的笔记本电池校正软件( 64.32位) BatteryMon2.1-Win7可用.rar (258.7 KB)

  6. win7 64位系统连接xp 32位共享打印机办法

    局域网内有台server2003_32位系统的共享打印机,xp系统用\\ip地址 能直接连上 但win7_64位的用\\ip 连接是连不上的 会提示缺少驱动. 我们可以在共享打印机上添加64位的驱动让 ...

  7. 64位 pb12 win7 数据源_64位系统用32位powerbuilder9.0链接64位oracle12c

    64 位系统下用 32 位 power builder9.0 链接 64 位 oracle12c 1. 在 32 位的 power builder9.0 里链接 64 位 oracle12c 时, 会 ...

  8. 64 大小_电脑系统32位和64位有什么区别

    众所周知,windows系统有32位和64位,但这两者有什么不同呢?什么样的电脑装什么版本的呢?笔者就简单的来讲一下两者的区别. 一.支持的内存不同 32位的操作系统,最多支持4G的内存,实际内存为3 ...

  9. 64位计算机安装32位,64位电脑装32位系统,小编教你64位电脑怎么装32位系统

    对电脑有深入了解的用户就知道,64位电脑一般指的是CPU是64位处理器,64位机器要安装64位系统,发挥硬件最佳性能,当然了,64位电脑也可以装32位系统,因为64位电脑是向下兼容,支持64位系统也支 ...

最新文章

  1. javascript 通过键获取值
  2. win7 重启 IIS.
  3. python正则表达式模块_Python正则表达式函数模块
  4. helm离线安装helm-push插件
  5. cacti+nagios 整合遇到的问题
  6. java vector实现的接口_java的List接口的实现类 ArrayList,LinkedList,Vector 的区别
  7. php root权限执行命令,如何使用PHP执行需要root权限的系统命令
  8. 演义群侠传(五)【素材方式MC or SpriteSheet】
  9. linux moxa 多串口卡_MOXA多串口卡C32030TCPU模块双RISC-based处理器架构大幅提升I/O数据传输的效能达到8口或以上...
  10. 【Java项目实战】黄金矿工小游戏项目介绍
  11. Localhost到底是干什么用的?
  12. BZOJ 2429: [HAOI2006]聪明的猴子
  13. 2008年8月27号,星期三,晴。锲而舍之,朽木不折;锲而不舍,金石可镂。 ——《荀子•劝学》2008年8月27号,星期三,晴。
  14. 超声的pacs系统和dicom服务器,基于DICOM的PACS系统设计与实现
  15. 软件架构设计---软件架构风格
  16. 【对比分析】vipkid和51talk哪个好?说说我的亲身经历!
  17. axure转化成代码_​教大家如何查看Axure页面的代码
  18. IntelliJ idea (最新版)激活方法
  19. webstorm配置和使用
  20. Day19(可变参数,增强for循环遍历,泛型通配符<?>,TreeSet,LinkedHashSet,集合的嵌套遍历,Set集合,静态导入,)

热门文章

  1. 【Python】 linecache模块读取文件
  2. 搜索suggest实现 动态的查询建议
  3. Android开发者指南(5) —— monkeyrunner
  4. 滴滴高管今年集体不拿年终奖 员工奖励力度缩减一半
  5. RedHat已更改其开源许可规则
  6. 多层AOP 解决AOP执行顺序
  7. 企业 SOA 设计(1)–ESB 设计
  8. [转]Android最佳实践之:StrictMode介绍
  9. Javascript MVC架构之旅
  10. 也谈淘点点60s短信订单的架构设计