看流星社区

 找回密码
 注册账号
查看: 2215|回复: 0

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

[复制链接]

该用户从未签到

发表于 2017-6-1 17:20:55 | 显示全部楼层 |阅读模式
初始化部分
//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();[/code]
//******************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(&amp;CurrentProcessNameForGetContextThread,(char *)((DWORD)ProcessEPROCESSForGetContextThread+0x174));
//将我们要比对的进程名放入GameProcessName
RtlInitAnsiString(&amp;GameProcessNameForGetContextThread,"DNF.exe");
if (RtlCompareString(&amp;CurrentProcessNameForGetContextThread, &amp;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(&amp;linkListHead))
{
//链表为空
dprintf("[ByPassTp] 链表为空!\n");
return;
}
PTHREADCONTEXTLINK pTarget = NULL; // 节点数据
PLIST_ENTRY pListWalker = &amp;linkListHead; //pListWalker 的节点的头部地址
pTarget = CONTAINING_RECORD(&amp;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(&amp;linkListHead))
{
//如果链表为空
KeInitializeSpinLock(&amp;spin_lock);
// 锁定,注意这里的irql是个指针
KeAcquireSpinLock(&amp;spin_lock, &amp;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(&amp;linkListHead,&amp;pData->ListEntry);
// 解锁,注意这里的irql不是指针
KeReleaseSpinLock(&amp;spin_lock, irql);
return;
}else
{
//如果不为空,先判断是不是存在了
DWORD Value = ExsitsLinkTable(ThreadHandle);
if (Value > 1)
{
dprintf("存在了,不用插入了!");
KeInitializeSpinLock(&amp;spin_lock);
// 锁定,注意这里的irql是个指针
KeAcquireSpinLock(&amp;spin_lock, &amp;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(&amp;spin_lock, irql);
return;
}else
{
KeInitializeSpinLock(&amp;spin_lock);
// 锁定,注意这里的irql是个指针
KeAcquireSpinLock(&amp;spin_lock, &amp;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(&amp;linkListHead,&amp;pData->ListEntry);
// 解锁,注意这里的irql不是指针
KeReleaseSpinLock(&amp;spin_lock, irql);
return;
}
}
}


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

PTHREADCONTEXTLINK pTarget = NULL; // 节点数据
PLIST_ENTRY pListWalker = &amp;linkListHead; //pListWalker 的节点的头部地址
pTarget = CONTAINING_RECORD(&amp;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(&amp;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)&amp;&amp;
(*(FindPointer+1)==Characteristic1)&amp;&amp;
(*(FindPointer+2)==Characteristic2)&amp;&amp;
(*(FindPointer+3)==Characteristic3)&amp;&amp;
(*(FindPointer+4)==Characteristic4)&amp;&amp;
(*(FindPointer+5)==Characteristic5)&amp;&amp;
(*(FindPointer+6)==Characteristic6)&amp;&amp;
(*(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");
}[/code]
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-28 20:33

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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