• 1593阅读
  • 4回复

对付DNF硬件断点的NtGetContextThread的写法 [复制链接]

上一主题 下一主题
离线天道酬勤
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-04
— 本帖被 天道酬勤 从 驱动保护 移动到本区(2016-05-19) —
初始化部分
//NtGetContextThread(对付硬件断点)
// HookAddr_NtGetContextThread = FindHookNtGetContextThread();
// dprintf("[ByPassTp] HookAddr_NtGetContextThread = %08X\r\n",HookAddr_NtGetContextThread);
// JmpHookInitialFun(NtGetContextThread);


挂钩部分
//NtGetContextThreadStart();

恢复部分
//NtGetContextThreadStop();

//*****************H部分******************************************************************************************


[cpp] view plain copy

  1. #pragma once   
  2.   
  3. #include "struct.h"   
  4. #include "Common.h"   
  5.   
  6. typedef struct _THREADCONTEXTLINK  
  7. {  
  8. LIST_ENTRY ListEntry; //主要是为了把数据连接到一起   
  9. DWORD ThreadHandle;  
  10. DWORD Dr0Seg;  
  11. DWORD Dr1Seg;  
  12. DWORD Dr2Seg;  
  13. DWORD Dr3Seg;  
  14. DWORD Dr6Seg;  
  15. DWORD Dr7Seg;  
  16. }THREADCONTEXTLINK,*PTHREADCONTEXTLINK;  
  17.   
  18. VOID ShowDrRegInfo(PCONTEXT pThreadContext);  
  19. VOID ClearDrReg(PCONTEXT pThreadContext);  
  20. VOID AddLinkTable(DWORD ThreadHandle, PCONTEXT pThreadContext);  
  21. VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext);  
  22. DWORD ExsitsLinkTable(DWORD ThreadHandle);  
  23.   
  24. extern DWORD HookAddr_NtGetContextThread;  
  25. DWORD FindHookNtGetContextThread();  
  26. VOID __stdcall HookFunc_NtGetContextThread();  


//******************CPP部分***************************************************************************************



[cpp] view plain copy

  1. #ifdef __cplusplus   
  2. extern "C" {  
  3. #endif   
  4. #include <ntddk.h>   
  5. #include <string.h>   
  6. #ifdef __cplusplus   
  7. }; // extern "C"   
  8. #endif   
  9.   
  10. #include "_NtGetContextThread.h"   
  11.   
  12. DWORD ThreadHandle=0;  
  13. PCONTEXT pThreadContext =0;  
  14. LIST_ENTRY linkListHead; // 链表   
  15. KSPIN_LOCK spin_lock; // 自旋锁   
  16.   
  17.   
  18. //-----------------   
  19. // 后继   
  20. //-----------------   
  21. // 前驱   
  22. //-----------------   
  23. // 数据域   
  24. // ThreadHandle   
  25. // Dr0   
  26. // Dr1   
  27. // .....   
  28. // Dr7   
  29. //-----------------   
  30. DWORD HookAddr_NtGetContextThread = 0;  
  31. //NtGetContextThread(Thread+0x8,ThreadContext+0xC)   
  32. //获得调用者的EPROCESS   
  33. PEPROCESS ProcessEPROCESSForGetContextThread = NULL; //保存访问者的EPROCESS   
  34. ANSI_STRING CurrentProcessNameForGetContextThread,GameProcessNameForGetContextThread; //保存进程名称   
  35. __declspec(naked) VOID __stdcall HookFunc_NtGetContextThread()  
  36. {  
  37. __asm  
  38. {  
  39. pushad  
  40. mov edx,DWORD ptr[ebp+0x8] //线程句柄   
  41. mov ThreadHandle,edx  
  42. mov ebx,DWORD ptr[ebp+0xC] //CONTEXT指针   
  43. mov pThreadContext,ebx  
  44. popad  
  45. }  
  46.   
  47. ProcessEPROCESSForGetContextThread = IoGetCurrentProcess(); //-->EPROCESS   
  48. //将调用者的进程名保存到CurrentProcessName中   
  49. //dprintf("[ByPassTp] 调用进程:%s\r\n",(char *)((DWORD)ProcessEPROCESSForOpenProcess+0x174));   
  50. RtlInitAnsiString(&CurrentProcessNameForGetContextThread,(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174));  
  51. //将我们要比对的进程名放入GameProcessName   
  52. RtlInitAnsiString(&GameProcessNameForGetContextThread,"DNF.exe");  
  53. if (RtlCompareString(&CurrentProcessNameForGetContextThread, &GameProcessNameForGetContextThread,TRUE) == 0)  
  54. {  
  55.   
  56. dprintf("[ByPassTp] DnfThreadHandle = %08X\n",ThreadHandle);  
  57. dprintf("[ByPassTp] DnfpThreadContext = %08X\n",pThreadContext);  
  58. ShowDrRegInfo(pThreadContext);  
  59. AddLinkTable(ThreadHandle,pThreadContext);  
  60. ClearDrReg(pThreadContext);  
  61. dprintf("\n==============================================\n");  
  62. }else  
  63. {  
  64. dprintf("[ByPassTp] %s 访问NtGetContextThread \n",(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174));  
  65. //RecoveryDrReg(ThreadHandle,pThreadContext);   
  66. }  
  67. //执行被覆盖的代码   
  68. __asm  
  69. {  
  70. mov eax, esi  
  71. pop esi  
  72. leave  
  73. retn 8  
  74. }  
  75.   
  76. }  
  77.   
  78. //恢复被隐藏的Dr寄存器   
  79. VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext)  
  80. {  
  81. if (IsListEmpty(&linkListHead))  
  82. {  
  83. //链表为空   
  84. dprintf("[ByPassTp] 链表为空!\n");  
  85. return;  
  86. }  
  87. PTHREADCONTEXTLINK pTarget = NULL; // 节点数据   
  88. PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址   
  89. pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址   
  90. THREADCONTEXTLINK,  
  91. ListEntry);  
  92. dprintf("链表头 = %08X\n",pTarget);  
  93. dprintf("线程句柄 = %08X\n",ThreadHandle);  
  94. while(pTarget !=NULL)  
  95. {  
  96. pListWalker = pListWalker->Blink;  
  97. pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着   
  98. if (pTarget->ThreadHandle == ThreadHandle)  
  99. {  
  100. pTarget->Dr0Seg = pThreadContext->Dr0;  
  101. pTarget->Dr1Seg = pThreadContext->Dr1;  
  102. pTarget->Dr2Seg = pThreadContext->Dr2;  
  103. pTarget->Dr3Seg = pThreadContext->Dr3;  
  104. pTarget->Dr6Seg = pThreadContext->Dr6;  
  105. pTarget->Dr7Seg = pThreadContext->Dr7;  
  106. break;  
  107. }  
  108. }  
  109. return;  
  110. }  
  111.   
  112. VOID AddLinkTable(DWORD ThreadHandle, PCONTEXT pThreadContext)  
  113. {  
  114. PTHREADCONTEXTLINK pData = NULL; // 节点数据   
  115. KIRQL irql; // 中断级别   
  116.   
  117. if (IsListEmpty(&linkListHead))  
  118. {  
  119. //如果链表为空   
  120. KeInitializeSpinLock(&spin_lock);  
  121. // 锁定,注意这里的irql是个指针   
  122. KeAcquireSpinLock(&spin_lock, &irql);  
  123. pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK));  
  124. if (NULL == pData) return;  
  125. //拷贝第一个元素   
  126. pData->ThreadHandle = ThreadHandle;  
  127. //拷贝Dr寄存器的值   
  128. pData->Dr0Seg = pThreadContext->Dr0;  
  129. pData->Dr1Seg = pThreadContext->Dr1;  
  130. pData->Dr2Seg = pThreadContext->Dr2;  
  131. pData->Dr3Seg = pThreadContext->Dr3;  
  132. pData->Dr6Seg = pThreadContext->Dr6;  
  133. pData->Dr7Seg = pThreadContext->Dr7;  
  134. //如果为空就插到头   
  135. InsertHeadList(&linkListHead,&pData->ListEntry);  
  136. // 解锁,注意这里的irql不是指针   
  137. KeReleaseSpinLock(&spin_lock, irql);  
  138. return;  
  139. }else  
  140. {  
  141. //如果不为空,先判断是不是存在了   
  142. DWORD Value = ExsitsLinkTable(ThreadHandle);  
  143. if (Value > 1)  
  144. {  
  145. dprintf("存在了,不用插入了!");  
  146. KeInitializeSpinLock(&spin_lock);  
  147. // 锁定,注意这里的irql是个指针   
  148. KeAcquireSpinLock(&spin_lock, &irql);  
  149. //拷贝Dr寄存器的值到链表元素里(更新Dr数据)   
  150. ((PTHREADCONTEXTLINK)Value)->Dr0Seg = pThreadContext->Dr0;  
  151. ((PTHREADCONTEXTLINK)Value)->Dr1Seg = pThreadContext->Dr1;  
  152. ((PTHREADCONTEXTLINK)Value)->Dr2Seg = pThreadContext->Dr2;  
  153. ((PTHREADCONTEXTLINK)Value)->Dr3Seg = pThreadContext->Dr3;  
  154. ((PTHREADCONTEXTLINK)Value)->Dr6Seg = pThreadContext->Dr6;  
  155. ((PTHREADCONTEXTLINK)Value)->Dr7Seg = pThreadContext->Dr7;  
  156. KeReleaseSpinLock(&spin_lock, irql);  
  157. return;  
  158. }else  
  159. {  
  160. KeInitializeSpinLock(&spin_lock);  
  161. // 锁定,注意这里的irql是个指针   
  162. KeAcquireSpinLock(&spin_lock, &irql);  
  163. pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK));  
  164. if (NULL == pData) return;  
  165. //拷贝第一个元素   
  166. pData->ThreadHandle = ThreadHandle;  
  167. //拷贝Dr寄存器的值   
  168. pData->Dr0Seg = pThreadContext->Dr0;  
  169. pData->Dr1Seg = pThreadContext->Dr1;  
  170. pData->Dr2Seg = pThreadContext->Dr2;  
  171. pData->Dr3Seg = pThreadContext->Dr3;  
  172. pData->Dr6Seg = pThreadContext->Dr6;  
  173. pData->Dr7Seg = pThreadContext->Dr7;  
  174. //如果不为空就插到尾   
  175. InsertTailList(&linkListHead,&pData->ListEntry);  
  176. // 解锁,注意这里的irql不是指针   
  177. KeReleaseSpinLock(&spin_lock, irql);  
  178. return;  
  179. }  
  180. }  
  181. }  
  182.   
  183.   
  184. DWORD ExsitsLinkTable(DWORD ThreadHandle)  
  185. {  
  186. if (IsListEmpty(&linkListHead))  
  187. {  
  188. //链表为空   
  189. dprintf("[ByPassTp] 链表为空!\n");  
  190. return 1;  
  191. }  
  192.   
  193. PTHREADCONTEXTLINK pTarget = NULL; // 节点数据   
  194. PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址   
  195. pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址   
  196. THREADCONTEXTLINK,  
  197. ListEntry);  
  198. dprintf("链表头 = %08X\n",pTarget);  
  199. while(pTarget !=NULL)  
  200. {  
  201. pListWalker = pListWalker->Blink;  
  202. pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着   
  203. if (pTarget->ThreadHandle == ThreadHandle)  
  204. {  
  205. //存在了   
  206. dprintf("元素地址 = %08X\n",pTarget);  
  207. return (DWORD)pTarget;  
  208. }  
  209. }  
  210. return 0;  
  211. }  
  212.   
  213. VOID ShowDrRegInfo(PCONTEXT pThreadContext)  
  214. {  
  215. dprintf("[ByPassTp] Dr0 = %08X\n",pThreadContext->Dr0);  
  216. dprintf("[ByPassTp] Dr1 = %08X\n",pThreadContext->Dr1);  
  217. dprintf("[ByPassTp] Dr2 = %08X\n",pThreadContext->Dr2);  
  218. dprintf("[ByPassTp] Dr3 = %08X\n",pThreadContext->Dr3);  
  219. dprintf("[ByPassTp] Dr6 = %08X\n",pThreadContext->Dr6);  
  220. dprintf("[ByPassTp] Dr7 = %08X\n",pThreadContext->Dr7);  
  221. }  
  222.   
  223. DWORD FindHookNtGetContextThread()  
  224. {  
  225. // 初始化   
  226. InitializeListHead(&linkListHead);  
  227. dprintf("[ByPassTp] 链表头 = %08X\r\n",linkListHead);  
  228. dprintf("[ByPassTp] 链表初始化完成!\r\n");  
  229. //-----------------------------------   
  230. BYTE Characteristic0 = 0x8B,  
  231. Characteristic1 = 0xC6, //+1   
  232. Characteristic2 = 0x5E, //+2   
  233. Characteristic3 = 0xC9, //+3   
  234. Characteristic4 = 0xC2, //+4   
  235. Characteristic5 = 0x08, //+5   
  236. Characteristic6 = 0x00, //+6   
  237. Characteristic7 = 0xCC; //+7   
  238. //-----------------------------------   
  239. BYTE *FindPointer = NULL;  
  240. DWORD HookNtGetContextThreadAddress=0;  
  241. __try  
  242. {  
  243. //将FindPointer指向NtOpenProcess函数开始处   
  244. FindPointer = (PBYTE)FindInKeServiceDescriptorTable(0x55);  
  245. dprintf("[ByPassTp] NtGetContextThread = %08X\n",FindPointer);  
  246. //遍历找特征码   
  247. for (DWORD i=0;i<0x100;i++)  
  248. {  
  249. if((*(FindPointer)==Characteristic0)&&  
  250. (*(FindPointer+1)==Characteristic1)&&  
  251. (*(FindPointer+2)==Characteristic2)&&  
  252. (*(FindPointer+3)==Characteristic3)&&  
  253. (*(FindPointer+4)==Characteristic4)&&  
  254. (*(FindPointer+5)==Characteristic5)&&  
  255. (*(FindPointer+6)==Characteristic6)&&  
  256. (*(FindPointer+7)==Characteristic7))  
  257. {  
  258. HookNtGetContextThreadAddress = (DWORD)FindPointer;  
  259. dprintf("[ByPassTp] HookNtGetContextThreadAddress = %08X\r\n",HookNtGetContextThreadAddress);  
  260. break;  
  261. }  
  262. FindPointer++;//推进指针   
  263. }  
  264. }  
  265. __except(EXCEPTION_EXECUTE_HANDLER)  
  266. {  
  267. dprintf("[ByPassTp] FindHookNtGetContextThread中发生异常!\r\n");  
  268. dprintf("[ByPassTp] 程序将继续运行\r\n");  
  269. }  
  270. return HookNtGetContextThreadAddress;  
  271. }  
  272.   
  273. VOID ClearDrReg(PCONTEXT pThreadContext)  
  274. {  
  275. dprintf("\n-------------ClearDrRegBegin-------------\n");  
  276. pThreadContext->Dr0 = 0;  
  277. pThreadContext->Dr1 = 0;  
  278. pThreadContext->Dr2 = 0;  
  279. pThreadContext->Dr3 = 0;  
  280. pThreadContext->Dr6 = 0;  
  281. pThreadContext->Dr7 = 0;  
  282. ShowDrRegInfo(pThreadContext);  
  283. dprintf("\n-------------ClearDrRegEnd-------------\n");  
  284. }  

离线j90141355

只看该作者 沙发  发表于: 2016-02-05
     大神好厉害,能问问怎么搞掉DNF TP的双机调试保护吗?
离线v2680267313

只看该作者 板凳  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
离线a168747

只看该作者 地板  发表于: 08-01
ddddddddddddddd
离线shicongmeng

只看该作者 4楼 发表于: 11-10
滴答滴答滴答滴答滴答滴答滴答滴答滴答滴答滴答
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个