初始化部分
//NtGetContextThread(对付硬件断点)
// HookAddr_NtGetContextThread = FindHookNtGetContextThread();
// dprintf("[ByPassTp] HookAddr_NtGetContextThread = %08X\r\n",HookAddr_NtGetContextThread);
// JmpHookInitialFun(NtGetContextThread);
挂钩部分
//NtGetContextThreadStart();
恢复部分
//NtGetContextThreadStop();
//******************CPP部分***************************************************************************************
//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");
}