郁金香外挂技术-郁金香灬老师

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

郁金香终身VIP管理员QQ150330575项目合作(有实力的+)视频教程+每月更新+QQ群
飞郁视频分享(每周更新)
查看: 377|回复: 0

对付DNF硬件断点的NtGetContextThread的写法 转

[复制链接]
发表于 2019-10-25 22:10:12 | 显示全部楼层 |阅读模式
  1. 对付DNF硬件断点的NtGetContextThread的写法
  2. 2014-03-03 17:37:26 sgzwiz 阅读数 3681
  3. 初始化部分
  4. //NtGetContextThread(对付硬件断点)
  5. // HookAddr_NtGetContextThread = FindHookNtGetContextThread();
  6. // dprintf("[ByPassTp] HookAddr_NtGetContextThread = %08X\r\n",HookAddr_NtGetContextThread);
  7. // JmpHookInitialFun(NtGetContextThread);


  8. 挂钩部分
  9. //NtGetContextThreadStart();

  10. 恢复部分
  11. //NtGetContextThreadStop();

  12. //*****************H部分******************************************************************************************


  13. #pragma once

  14. #include "struct.h"
  15. #include "Common.h"

  16. typedef struct _THREADCONTEXTLINK
  17. {
  18. LIST_ENTRY ListEntry; //主要是为了把数据连接到一起
  19. DWORD ThreadHandle;
  20. DWORD Dr0Seg;
  21. DWORD Dr1Seg;
  22. DWORD Dr2Seg;
  23. DWORD Dr3Seg;
  24. DWORD Dr6Seg;
  25. DWORD Dr7Seg;
  26. }THREADCONTEXTLINK,*PTHREADCONTEXTLINK;

  27. VOID ShowDrRegInfo(PCONTEXT pThreadContext);
  28. VOID ClearDrReg(PCONTEXT pThreadContext);
  29. VOID AddLinkTable(DWORD ThreadHandle, PCONTEXT pThreadContext);
  30. VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext);
  31. DWORD ExsitsLinkTable(DWORD ThreadHandle);

  32. extern DWORD HookAddr_NtGetContextThread;
  33. DWORD FindHookNtGetContextThread();
  34. VOID __stdcall HookFunc_NtGetContextThread();

  35. //******************CPP部分***************************************************************************************

  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. #include <ntddk.h>
  40. #include <string.h>
  41. #ifdef __cplusplus
  42. }; // extern "C"
  43. #endif

  44. #include "_NtGetContextThread.h"

  45. DWORD ThreadHandle=0;
  46. PCONTEXT pThreadContext =0;
  47. LIST_ENTRY linkListHead; // 链表
  48. KSPIN_LOCK spin_lock; // 自旋锁


  49. //-----------------
  50. // 后继
  51. //-----------------
  52. // 前驱
  53. //-----------------
  54. // 数据域
  55. // ThreadHandle
  56. // Dr0
  57. // Dr1
  58. // .....
  59. // Dr7
  60. //-----------------
  61. DWORD HookAddr_NtGetContextThread = 0;
  62. //NtGetContextThread(Thread+0x8,ThreadContext+0xC)
  63. //获得调用者的EPROCESS
  64. PEPROCESS ProcessEPROCESSForGetContextThread = NULL; //保存访问者的EPROCESS
  65. ANSI_STRING CurrentProcessNameForGetContextThread,GameProcessNameForGetContextThread; //保存进程名称
  66. __declspec(naked) VOID __stdcall HookFunc_NtGetContextThread()
  67. {
  68. __asm
  69. {
  70. pushad
  71. mov edx,DWORD ptr[ebp+0x8] //线程句柄
  72. mov ThreadHandle,edx
  73. mov ebx,DWORD ptr[ebp+0xC] //CONTEXT指针
  74. mov pThreadContext,ebx
  75. popad
  76. }

  77. ProcessEPROCESSForGetContextThread = IoGetCurrentProcess(); //-->EPROCESS
  78. //将调用者的进程名保存到CurrentProcessName中
  79. //dprintf("[ByPassTp] 调用进程:%s\r\n",(char *)((DWORD)ProcessEPROCESSForOpenProcess+0x174));
  80. RtlInitAnsiString(&CurrentProcessNameForGetContextThread,(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174));
  81. //将我们要比对的进程名放入GameProcessName
  82. RtlInitAnsiString(&GameProcessNameForGetContextThread,"DNF.exe");
  83. if (RtlCompareString(&CurrentProcessNameForGetContextThread, &GameProcessNameForGetContextThread,TRUE) == 0)
  84. {

  85. dprintf("[ByPassTp] DnfThreadHandle = %08X\n",ThreadHandle);
  86. dprintf("[ByPassTp] DnfpThreadContext = %08X\n",pThreadContext);
  87. ShowDrRegInfo(pThreadContext);
  88. AddLinkTable(ThreadHandle,pThreadContext);
  89. ClearDrReg(pThreadContext);
  90. dprintf("\n==============================================\n");
  91. }else
  92. {
  93. dprintf("[ByPassTp] %s 访问NtGetContextThread \n",(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174));
  94. //RecoveryDrReg(ThreadHandle,pThreadContext);
  95. }
  96. //执行被覆盖的代码
  97. __asm
  98. {
  99. mov eax, esi
  100. pop esi
  101. leave
  102. retn 8
  103. }

  104. }

  105. //恢复被隐藏的Dr寄存器
  106. VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext)
  107. {
  108. if (IsListEmpty(&linkListHead))
  109. {
  110. //链表为空
  111. dprintf("[ByPassTp] 链表为空!\n");
  112. return;
  113. }
  114. PTHREADCONTEXTLINK pTarget = NULL; // 节点数据
  115. PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址
  116. pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址
  117. THREADCONTEXTLINK,
  118. ListEntry);
  119. dprintf("链表头 = %08X\n",pTarget);
  120. dprintf("线程句柄 = %08X\n",ThreadHandle);
  121. while(pTarget !=NULL)
  122. {
  123. pListWalker = pListWalker->Blink;
  124. pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着
  125. if (pTarget->ThreadHandle == ThreadHandle)
  126. {
  127. pTarget->Dr0Seg = pThreadContext->Dr0;
  128. pTarget->Dr1Seg = pThreadContext->Dr1;
  129. pTarget->Dr2Seg = pThreadContext->Dr2;
  130. pTarget->Dr3Seg = pThreadContext->Dr3;
  131. pTarget->Dr6Seg = pThreadContext->Dr6;
  132. pTarget->Dr7Seg = pThreadContext->Dr7;
  133. break;
  134. }
  135. }
  136. return;
  137. }

  138. VOID AddLinkTable(DWORD ThreadHandle, PCONTEXT pThreadContext)
  139. {
  140. PTHREADCONTEXTLINK pData = NULL; // 节点数据
  141. KIRQL irql; // 中断级别

  142. if (IsListEmpty(&linkListHead))
  143. {
  144. //如果链表为空
  145. KeInitializeSpinLock(&spin_lock);
  146. // 锁定,注意这里的irql是个指针
  147. KeAcquireSpinLock(&spin_lock, &irql);
  148. pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK));
  149. if (NULL == pData) return;
  150. //拷贝第一个元素
  151. pData->ThreadHandle = ThreadHandle;
  152. //拷贝Dr寄存器的值
  153. pData->Dr0Seg = pThreadContext->Dr0;
  154. pData->Dr1Seg = pThreadContext->Dr1;
  155. pData->Dr2Seg = pThreadContext->Dr2;
  156. pData->Dr3Seg = pThreadContext->Dr3;
  157. pData->Dr6Seg = pThreadContext->Dr6;
  158. pData->Dr7Seg = pThreadContext->Dr7;
  159. //如果为空就插到头
  160. InsertHeadList(&linkListHead,&pData->ListEntry);
  161. // 解锁,注意这里的irql不是指针
  162. KeReleaseSpinLock(&spin_lock, irql);
  163. return;
  164. }else
  165. {
  166. //如果不为空,先判断是不是存在了
  167. DWORD Value = ExsitsLinkTable(ThreadHandle);
  168. if (Value > 1)
  169. {
  170. dprintf("存在了,不用插入了!");
  171. KeInitializeSpinLock(&spin_lock);
  172. // 锁定,注意这里的irql是个指针
  173. KeAcquireSpinLock(&spin_lock, &irql);
  174. //拷贝Dr寄存器的值到链表元素里(更新Dr数据)
  175. ((PTHREADCONTEXTLINK)Value)->Dr0Seg = pThreadContext->Dr0;
  176. ((PTHREADCONTEXTLINK)Value)->Dr1Seg = pThreadContext->Dr1;
  177. ((PTHREADCONTEXTLINK)Value)->Dr2Seg = pThreadContext->Dr2;
  178. ((PTHREADCONTEXTLINK)Value)->Dr3Seg = pThreadContext->Dr3;
  179. ((PTHREADCONTEXTLINK)Value)->Dr6Seg = pThreadContext->Dr6;
  180. ((PTHREADCONTEXTLINK)Value)->Dr7Seg = pThreadContext->Dr7;
  181. KeReleaseSpinLock(&spin_lock, irql);
  182. return;
  183. }else
  184. {
  185. KeInitializeSpinLock(&spin_lock);
  186. // 锁定,注意这里的irql是个指针
  187. KeAcquireSpinLock(&spin_lock, &irql);
  188. pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK));
  189. if (NULL == pData) return;
  190. //拷贝第一个元素
  191. pData->ThreadHandle = ThreadHandle;
  192. //拷贝Dr寄存器的值
  193. pData->Dr0Seg = pThreadContext->Dr0;
  194. pData->Dr1Seg = pThreadContext->Dr1;
  195. pData->Dr2Seg = pThreadContext->Dr2;
  196. pData->Dr3Seg = pThreadContext->Dr3;
  197. pData->Dr6Seg = pThreadContext->Dr6;
  198. pData->Dr7Seg = pThreadContext->Dr7;
  199. //如果不为空就插到尾
  200. InsertTailList(&linkListHead,&pData->ListEntry);
  201. // 解锁,注意这里的irql不是指针
  202. KeReleaseSpinLock(&spin_lock, irql);
  203. return;
  204. }
  205. }
  206. }


  207. DWORD ExsitsLinkTable(DWORD ThreadHandle)
  208. {
  209. if (IsListEmpty(&linkListHead))
  210. {
  211. //链表为空
  212. dprintf("[ByPassTp] 链表为空!\n");
  213. return 1;
  214. }

  215. PTHREADCONTEXTLINK pTarget = NULL; // 节点数据
  216. PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址
  217. pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址
  218. THREADCONTEXTLINK,
  219. ListEntry);
  220. dprintf("链表头 = %08X\n",pTarget);
  221. while(pTarget !=NULL)
  222. {
  223. pListWalker = pListWalker->Blink;
  224. pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着
  225. if (pTarget->ThreadHandle == ThreadHandle)
  226. {
  227. //存在了
  228. dprintf("元素地址 = %08X\n",pTarget);
  229. return (DWORD)pTarget;
  230. }
  231. }
  232. return 0;
  233. }

  234. VOID ShowDrRegInfo(PCONTEXT pThreadContext)
  235. {
  236. dprintf("[ByPassTp] Dr0 = %08X\n",pThreadContext->Dr0);
  237. dprintf("[ByPassTp] Dr1 = %08X\n",pThreadContext->Dr1);
  238. dprintf("[ByPassTp] Dr2 = %08X\n",pThreadContext->Dr2);
  239. dprintf("[ByPassTp] Dr3 = %08X\n",pThreadContext->Dr3);
  240. dprintf("[ByPassTp] Dr6 = %08X\n",pThreadContext->Dr6);
  241. dprintf("[ByPassTp] Dr7 = %08X\n",pThreadContext->Dr7);
  242. }

  243. DWORD FindHookNtGetContextThread()
  244. {
  245. // 初始化
  246. InitializeListHead(&linkListHead);
  247. dprintf("[ByPassTp] 链表头 = %08X\r\n",linkListHead);
  248. dprintf("[ByPassTp] 链表初始化完成!\r\n");
  249. //-----------------------------------
  250. BYTE Characteristic0 = 0x8B,
  251. Characteristic1 = 0xC6, //+1
  252. Characteristic2 = 0x5E, //+2
  253. Characteristic3 = 0xC9, //+3
  254. Characteristic4 = 0xC2, //+4
  255. Characteristic5 = 0x08, //+5
  256. Characteristic6 = 0x00, //+6
  257. Characteristic7 = 0xCC; //+7
  258. //-----------------------------------
  259. BYTE *FindPointer = NULL;
  260. DWORD HookNtGetContextThreadAddress=0;
  261. __try
  262. {
  263. //将FindPointer指向NtOpenProcess函数开始处
  264. FindPointer = (PBYTE)FindInKeServiceDescriptorTable(0x55);
  265. dprintf("[ByPassTp] NtGetContextThread = %08X\n",FindPointer);
  266. //遍历找特征码
  267. for (DWORD i=0;i<0x100;i++)
  268. {
  269. if((*(FindPointer)==Characteristic0)&&
  270. (*(FindPointer+1)==Characteristic1)&&
  271. (*(FindPointer+2)==Characteristic2)&&
  272. (*(FindPointer+3)==Characteristic3)&&
  273. (*(FindPointer+4)==Characteristic4)&&
  274. (*(FindPointer+5)==Characteristic5)&&
  275. (*(FindPointer+6)==Characteristic6)&&
  276. (*(FindPointer+7)==Characteristic7))
  277. {
  278. HookNtGetContextThreadAddress = (DWORD)FindPointer;
  279. dprintf("[ByPassTp] HookNtGetContextThreadAddress = %08X\r\n",HookNtGetContextThreadAddress);
  280. break;
  281. }
  282. FindPointer++;//推进指针
  283. }
  284. }
  285. __except(EXCEPTION_EXECUTE_HANDLER)
  286. {
  287. dprintf("[ByPassTp] FindHookNtGetContextThread中发生异常!\r\n");
  288. dprintf("[ByPassTp] 程序将继续运行\r\n");
  289. }
  290. return HookNtGetContextThreadAddress;
  291. }

  292. VOID ClearDrReg(PCONTEXT pThreadContext)
  293. {
  294. dprintf("\n-------------ClearDrRegBegin-------------\n");
  295. pThreadContext->Dr0 = 0;
  296. pThreadContext->Dr1 = 0;
  297. pThreadContext->Dr2 = 0;
  298. pThreadContext->Dr3 = 0;
  299. pThreadContext->Dr6 = 0;
  300. pThreadContext->Dr7 = 0;
  301. ShowDrRegInfo(pThreadContext);
  302. dprintf("\n-------------ClearDrRegEnd-------------\n");
  303. }
复制代码





郁金香外挂教程,学习中...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

限时限量优惠

QQ|小黑屋|手机版|郁金香外挂技术-郁金香灬老师 ( 苏ICP备10059359号 )

GMT+8, 2019-12-10 09:46 , Processed in 0.047913 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表