对付DNF硬件断点的NtGetContextThread的写法
2014-03-03 17:37
267 查看
初始化部分
//NtGetContextThread(对付硬件断点)
// HookAddr_NtGetContextThread = FindHookNtGetContextThread();
// dprintf("[ByPassTp] HookAddr_NtGetContextThread = %08X\r\n",HookAddr_NtGetContextThread);
// JmpHookInitialFun(NtGetContextThread);
挂钩部分
//NtGetContextThreadStart();
恢复部分
//NtGetContextThreadStop();
//*****************H部分******************************************************************************************
//******************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"); }
相关文章推荐
- 对付DNF硬件断点的NtGetContextThread的写法
- GetThreadContext找到程序占用CPU的技巧
- 区别:Thread.currentThread().getContextClassLoader() and Class.getClassLoader()
- Class.getResourceAsStream(path)与Thread.currentThread().getContextClassLoader().getResourceAsStream
- Thread.currentThread().getContextClassLoader() 与 ObjectInstance.class.getClassLoader() 的区别
- Thread.currentThread().getContextClassLoader()与Test.class.getClassLoader()区别
- Thread.currentThread().getContextClassLoader() and Class.getClassLoader()
- Class.forName() 初始化、Thread.currentThread().getContextClassLoader().getResourceAsStream
- getthreadcontext.cpp
- 实验:Thread.currentThread().getContextClassLoader() and Class.getClassLoader()
- Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()区别
- Thread.currentThread().getContextClassLoader() 和 Class.getClassLoader()区别
- 问题:何时使用Thread.getContextClassLoader()?
- Thread.getContextClassLoader() is null
- Thread.getContextClassLoader() 祥解
- 关于GetThreadContext
- Thread.currentThread().getContextClassLoader().getResourceAsStream
- Thread.currentThread().getContextClassLoader().getResourceAsStream
- Thread.currentThread().getContextClassLoader()和Class.getClassLoader的区别
- 读取配置文件Properties的一种方案(Thread.currentThread().getContextClassLoader() .getResourceAsStream()