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

转载 2014年03月03日 17:37:26
初始化部分 
//NtGetContextThread(对付硬件断点) 
// HookAddr_NtGetContextThread = FindHookNtGetContextThread(); 
// dprintf("[ByPassTp] HookAddr_NtGetContextThread = %08X\r\n",HookAddr_NtGetContextThread); 
// JmpHookInitialFun(NtGetContextThread); 


挂钩部分 
//NtGetContextThreadStart(); 

恢复部分 
//NtGetContextThreadStop(); 

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

#pragma once 

#include "struct.h" 
#include "Common.h" 

typedef struct _THREADCONTEXTLINK 
{ 
LIST_ENTRY ListEntry; //主要是为了把数据连接到一起 
DWORD ThreadHandle; 
DWORD Dr0Seg; 
DWORD Dr1Seg; 
DWORD Dr2Seg; 
DWORD Dr3Seg; 
DWORD Dr6Seg; 
DWORD Dr7Seg; 
}THREADCONTEXTLINK,*PTHREADCONTEXTLINK; 

VOID ShowDrRegInfo(PCONTEXT pThreadContext); 
VOID ClearDrReg(PCONTEXT pThreadContext); 
VOID AddLinkTable(DWORD ThreadHandle, PCONTEXT pThreadContext); 
VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext); 
DWORD ExsitsLinkTable(DWORD ThreadHandle); 

extern DWORD HookAddr_NtGetContextThread; 
DWORD FindHookNtGetContextThread(); 
VOID __stdcall HookFunc_NtGetContextThread();

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

#ifdef __cplusplus 
extern "C" { 
#endif 
#include <ntddk.h> 
#include <string.h> 
#ifdef __cplusplus 
}; // extern "C" 
#endif 

#include "_NtGetContextThread.h" 

DWORD ThreadHandle=0; 
PCONTEXT pThreadContext =0; 
LIST_ENTRY linkListHead; // 链表 
KSPIN_LOCK spin_lock; // 自旋锁 


//----------------- 
// 后继 
//----------------- 
// 前驱 
//----------------- 
// 数据域 
// ThreadHandle 
// Dr0 
// Dr1 
// ..... 
// Dr7 
//----------------- 
DWORD HookAddr_NtGetContextThread = 0; 
//NtGetContextThread(Thread+0x8,ThreadContext+0xC) 
//获得调用者的EPROCESS 
PEPROCESS ProcessEPROCESSForGetContextThread = NULL; //保存访问者的EPROCESS 
ANSI_STRING CurrentProcessNameForGetContextThread,GameProcessNameForGetContextThread; //保存进程名称 
__declspec(naked) VOID __stdcall HookFunc_NtGetContextThread() 
{ 
__asm 
{ 
pushad 
mov edx,DWORD ptr[ebp+0x8] //线程句柄 
mov ThreadHandle,edx 
mov ebx,DWORD ptr[ebp+0xC] //CONTEXT指针 
mov pThreadContext,ebx 
popad 
} 

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

dprintf("[ByPassTp] DnfThreadHandle = %08X\n",ThreadHandle); 
dprintf("[ByPassTp] DnfpThreadContext = %08X\n",pThreadContext); 
ShowDrRegInfo(pThreadContext); 
AddLinkTable(ThreadHandle,pThreadContext); 
ClearDrReg(pThreadContext); 
dprintf("\n==============================================\n"); 
}else 
{ 
dprintf("[ByPassTp] %s 访问NtGetContextThread \n",(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174)); 
//RecoveryDrReg(ThreadHandle,pThreadContext); 
} 
//执行被覆盖的代码 
__asm 
{ 
mov eax, esi 
pop esi 
leave 
retn 8 
} 

} 

//恢复被隐藏的Dr寄存器 
VOID RecoveryDrReg(DWORD ThreadHandle,PCONTEXT pThreadContext) 
{ 
if (IsListEmpty(&linkListHead)) 
{ 
//链表为空 
dprintf("[ByPassTp] 链表为空!\n"); 
return; 
} 
PTHREADCONTEXTLINK pTarget = NULL; // 节点数据 
PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址 
pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址 
THREADCONTEXTLINK, 
ListEntry); 
dprintf("链表头 = %08X\n",pTarget); 
dprintf("线程句柄 = %08X\n",ThreadHandle); 
while(pTarget !=NULL) 
{ 
pListWalker = pListWalker->Blink; 
pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着 
if (pTarget->ThreadHandle == ThreadHandle) 
{ 
pTarget->Dr0Seg = pThreadContext->Dr0; 
pTarget->Dr1Seg = pThreadContext->Dr1; 
pTarget->Dr2Seg = pThreadContext->Dr2; 
pTarget->Dr3Seg = pThreadContext->Dr3; 
pTarget->Dr6Seg = pThreadContext->Dr6; 
pTarget->Dr7Seg = pThreadContext->Dr7; 
break; 
} 
} 
return; 
} 

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

if (IsListEmpty(&linkListHead)) 
{ 
//如果链表为空 
KeInitializeSpinLock(&spin_lock); 
// 锁定,注意这里的irql是个指针 
KeAcquireSpinLock(&spin_lock, &irql); 
pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK)); 
if (NULL == pData) return; 
//拷贝第一个元素 
pData->ThreadHandle = ThreadHandle; 
//拷贝Dr寄存器的值 
pData->Dr0Seg = pThreadContext->Dr0; 
pData->Dr1Seg = pThreadContext->Dr1; 
pData->Dr2Seg = pThreadContext->Dr2; 
pData->Dr3Seg = pThreadContext->Dr3; 
pData->Dr6Seg = pThreadContext->Dr6; 
pData->Dr7Seg = pThreadContext->Dr7; 
//如果为空就插到头 
InsertHeadList(&linkListHead,&pData->ListEntry); 
// 解锁,注意这里的irql不是指针 
KeReleaseSpinLock(&spin_lock, irql); 
return; 
}else 
{ 
//如果不为空,先判断是不是存在了 
DWORD Value = ExsitsLinkTable(ThreadHandle); 
if (Value > 1) 
{ 
dprintf("存在了,不用插入了!"); 
KeInitializeSpinLock(&spin_lock); 
// 锁定,注意这里的irql是个指针 
KeAcquireSpinLock(&spin_lock, &irql); 
//拷贝Dr寄存器的值到链表元素里(更新Dr数据) 
((PTHREADCONTEXTLINK)Value)->Dr0Seg = pThreadContext->Dr0; 
((PTHREADCONTEXTLINK)Value)->Dr1Seg = pThreadContext->Dr1; 
((PTHREADCONTEXTLINK)Value)->Dr2Seg = pThreadContext->Dr2; 
((PTHREADCONTEXTLINK)Value)->Dr3Seg = pThreadContext->Dr3; 
((PTHREADCONTEXTLINK)Value)->Dr6Seg = pThreadContext->Dr6; 
((PTHREADCONTEXTLINK)Value)->Dr7Seg = pThreadContext->Dr7; 
KeReleaseSpinLock(&spin_lock, irql); 
return; 
}else 
{ 
KeInitializeSpinLock(&spin_lock); 
// 锁定,注意这里的irql是个指针 
KeAcquireSpinLock(&spin_lock, &irql); 
pData = (PTHREADCONTEXTLINK)ExAllocatePool(PagedPool,sizeof(THREADCONTEXTLINK)); 
if (NULL == pData) return; 
//拷贝第一个元素 
pData->ThreadHandle = ThreadHandle; 
//拷贝Dr寄存器的值 
pData->Dr0Seg = pThreadContext->Dr0; 
pData->Dr1Seg = pThreadContext->Dr1; 
pData->Dr2Seg = pThreadContext->Dr2; 
pData->Dr3Seg = pThreadContext->Dr3; 
pData->Dr6Seg = pThreadContext->Dr6; 
pData->Dr7Seg = pThreadContext->Dr7; 
//如果不为空就插到尾 
InsertTailList(&linkListHead,&pData->ListEntry); 
// 解锁,注意这里的irql不是指针 
KeReleaseSpinLock(&spin_lock, irql); 
return; 
} 
} 
} 


DWORD ExsitsLinkTable(DWORD ThreadHandle) 
{ 
if (IsListEmpty(&linkListHead)) 
{ 
//链表为空 
dprintf("[ByPassTp] 链表为空!\n"); 
return 1; 
} 

PTHREADCONTEXTLINK pTarget = NULL; // 节点数据 
PLIST_ENTRY pListWalker = &linkListHead; //pListWalker 的节点的头部地址 
pTarget = CONTAINING_RECORD(&linkListHead, //用这个宏,可以得到节点的头部地址 
THREADCONTEXTLINK, 
ListEntry); 
dprintf("链表头 = %08X\n",pTarget); 
while(pTarget !=NULL) 
{ 
pListWalker = pListWalker->Blink; 
pTarget = CONTAINING_RECORD(pListWalker,THREADCONTEXTLINK,ListEntry); //用这个宏,可以得到包含着 
if (pTarget->ThreadHandle == ThreadHandle) 
{ 
//存在了 
dprintf("元素地址 = %08X\n",pTarget); 
return (DWORD)pTarget; 
} 
} 
return 0; 
} 

VOID ShowDrRegInfo(PCONTEXT pThreadContext) 
{ 
dprintf("[ByPassTp] Dr0 = %08X\n",pThreadContext->Dr0); 
dprintf("[ByPassTp] Dr1 = %08X\n",pThreadContext->Dr1); 
dprintf("[ByPassTp] Dr2 = %08X\n",pThreadContext->Dr2); 
dprintf("[ByPassTp] Dr3 = %08X\n",pThreadContext->Dr3); 
dprintf("[ByPassTp] Dr6 = %08X\n",pThreadContext->Dr6); 
dprintf("[ByPassTp] Dr7 = %08X\n",pThreadContext->Dr7); 
} 

DWORD FindHookNtGetContextThread() 
{ 
// 初始化 
InitializeListHead(&linkListHead); 
dprintf("[ByPassTp] 链表头 = %08X\r\n",linkListHead); 
dprintf("[ByPassTp] 链表初始化完成!\r\n"); 
//----------------------------------- 
BYTE Characteristic0 = 0x8B, 
Characteristic1 = 0xC6, //+1 
Characteristic2 = 0x5E, //+2 
Characteristic3 = 0xC9, //+3 
Characteristic4 = 0xC2, //+4 
Characteristic5 = 0x08, //+5 
Characteristic6 = 0x00, //+6 
Characteristic7 = 0xCC; //+7 
//----------------------------------- 
BYTE *FindPointer = NULL; 
DWORD HookNtGetContextThreadAddress=0; 
__try 
{ 
//将FindPointer指向NtOpenProcess函数开始处 
FindPointer = (PBYTE)FindInKeServiceDescriptorTable(0x55); 
dprintf("[ByPassTp] NtGetContextThread = %08X\n",FindPointer); 
//遍历找特征码 
for (DWORD i=0;i<0x100;i++) 
{ 
if((*(FindPointer)==Characteristic0)&& 
(*(FindPointer+1)==Characteristic1)&& 
(*(FindPointer+2)==Characteristic2)&& 
(*(FindPointer+3)==Characteristic3)&& 
(*(FindPointer+4)==Characteristic4)&& 
(*(FindPointer+5)==Characteristic5)&& 
(*(FindPointer+6)==Characteristic6)&& 
(*(FindPointer+7)==Characteristic7)) 
{ 
HookNtGetContextThreadAddress = (DWORD)FindPointer; 
dprintf("[ByPassTp] HookNtGetContextThreadAddress = %08X\r\n",HookNtGetContextThreadAddress); 
break; 
} 
FindPointer++;//推进指针 
} 
} 
__except(EXCEPTION_EXECUTE_HANDLER) 
{ 
dprintf("[ByPassTp] FindHookNtGetContextThread中发生异常!\r\n"); 
dprintf("[ByPassTp] 程序将继续运行\r\n"); 
} 
return HookNtGetContextThreadAddress; 
} 

VOID ClearDrReg(PCONTEXT pThreadContext) 
{ 
dprintf("\n-------------ClearDrRegBegin-------------\n"); 
pThreadContext->Dr0 = 0; 
pThreadContext->Dr1 = 0; 
pThreadContext->Dr2 = 0; 
pThreadContext->Dr3 = 0; 
pThreadContext->Dr6 = 0; 
pThreadContext->Dr7 = 0; 
ShowDrRegInfo(pThreadContext); 
dprintf("\n-------------ClearDrRegEnd-------------\n"); 
}


在对话框中使用网页输入数据

作者的话:使用DHTMLEdit控件在应用程序中显示HTML是一个学习简单但是不很有效的方法,可以用于浏览器编程入门。此对话框使用了IE5附带的DHTMLEdit控件。头文件//{{AFX_INCLU...
  • jiangsheng
  • jiangsheng
  • 2001-08-02 21:45:00
  • 2854

游戏修改器 带内核 过HS

  • 2011年10月06日 07:46
  • 1.4MB
  • 下载

外部断点的使用

在PRD系统,运用外部断点调试一些东西的时候,以前都是登录默认的应用服务器,这次设置的断点,却没有起作用,断点为激活状态。在QAS系统测试,外部断点是可以起作用。后来分析得知,PRD系统有多个应用服务...
  • szq_zhengzhou
  • szq_zhengzhou
  • 2011-04-13 13:08:00
  • 669

NT 函数原型

NTSYSAPI NTSTATUS NTAPI NtAcceptConnectPort( OUT PHANDLE PortHandle, IN PVOID PortIdentifier, ...
  • lei35151
  • lei35151
  • 2013-11-15 21:33:26
  • 2559

过HS硬断也就是NtGetContextThread

  • 2013年04月15日 18:46
  • 2KB
  • 下载

对OD硬件断点的几点思考

前几天转了一片这样的文章 http://blog.csdn.net/nightsay/article/details/42063081 这几天在分析硬件断点的时候恍然明白了好多,打开OD在我们下硬件断...
  • Nightsay
  • Nightsay
  • 2014-12-24 13:17:56
  • 1917

Win7 od下send断点

参考文章:http://laokaddk.blog.51cto.com/368606/283702 -----------------------------------------------...
  • liujiayu2
  • liujiayu2
  • 2016-06-30 11:52:29
  • 934

过TP驱动4(硬件断点部分)

NtGetThreadContext NtSetThreadContext 需要处理一下    概念性代码:   NTSTATUS MyNtGetThreadContext(HANDLE ...
  • guoyi987
  • guoyi987
  • 2012-03-17 23:58:57
  • 1125

检测当前进程是否存在硬件断点

当前一些外挂为了躲避检测,不会去patch游戏内存代码,而使用硬断的方式来间接修改。 以下代码片段为了检测当前进程是否存在硬件断点而写: char buff[MAX_PATH] = {0}; DWO...
  • chence19871
  • chence19871
  • 2015-09-18 17:44:55
  • 1316

如何对抗硬件断点之一

原文出处:http://www.popbase.net/bbs/dispbbs.asp?boardID=5&ID=2377&page=1如何对抗硬件断点之一 --- 调试寄存器Author:Lenus...
  • better0332
  • better0332
  • 2008-05-22 17:26:00
  • 2091
收藏助手
不良信息举报
您举报文章:对付DNF硬件断点的NtGetContextThread的写法
举报原因:
原因补充:

(最多只允许输入30个字)