|
||
共
条评分
回复
举报
|
在线 那个谁
UID:23
总版主
|
只看该作者 沙发
发表于: 10-11
最后,处理一下硬件断点就可以了
这里我们使用到了SSDT HOOK 分别HOOK了 SSDT 表中索引为 0xD5和0x55的函数。由于这里比较简单 我想10个人有9个人懂得SSDT HOOK的。所以直接给出源码,不做原理分析了 代码: 复制代码 //处理硬件断点时 ULONG uNtSetContextThreadAddress; ULONG uNtGetContextThreadAddress; ULONG TenNtSetContextThread, TenNtGetContextThread; // // 名称: _MyNtGetThreadContext // 功能: 两个SSDT HOOK伪造函数的中继函数 // 参数: // 返回: // static NAKED NTSTATUS Nakd_NtGetThreadContext(HANDLE hThread, PCONTEXT pContext) { __asm { jmp dword ptr[TenNtGetContextThread] } } static NAKED NTSTATUS Nakd_NtSetThreadContext(HANDLE hThread, PCONTEXT pContext) { __asm { jmp dword ptr[TenNtSetContextThread] } } // // 名称: MyNtGetThreadContext && MyNtSetThreadContext // 功能: NtGetThreadContext与NtSetThreadContext函数被SSDT HOOK的伪造函数 // 参数: // 返回: // NTSTATUS MyNtGetThreadContext(HANDLE hThread, PCONTEXT pContext) { if ( _stricmp((const char*)PsGetProcessImageFileName(PsGetCurrentProcess()),DNF_EXE) ) { return Nakd_NtGetThreadContext(hThread, pContext); } return STATUS_UNSUCCESSFUL; } NTSTATUS MyNtSetThreadContext(HANDLE hThread, PCONTEXT pContext) { if ( _stricmp((const char*)PsGetProcessImageFileName(PsGetCurrentProcess()),DNF_EXE) ) { return Nakd_NtSetThreadContext(hThread, pContext); } //DbgPrint("Dr7:%08X\n", pContext->Dr7); if ( pContext->Dr7 == 0x101 ) { return Nakd_NtSetThreadContext(hThread, pContext); } return STATUS_UNSUCCESSFUL; } // // 名称: My_Recovery_HardwareBreakpoint // 功能: 通过对set与get进行SSDT HOOK来恢复硬件断点 // 参数: // 返回: // NTSTATUS My_Recovery_HardwareBreakpoint() { KIRQL Irql; //获取地址 uNtSetContextThreadAddress = (ULONG)KeServiceDescriptorTable->ServiceTableBase+0xD5 * 4; uNtGetContextThreadAddress = (ULONG)KeServiceDescriptorTable->ServiceTableBase+0x55 * 4; TenNtSetContextThread = *(ULONG*)uNtSetContextThreadAddress; TenNtGetContextThread = *(ULONG*)uNtGetContextThreadAddress; KdPrint(("Set地址:%0X\n",TenNtSetContextThread)); KdPrint(("Get地址:%0X\n",TenNtGetContextThread)); KdPrint(("Process:%0X \n",(ULONG)p_MyHookAddress)); KdPrint(("Thread:%0X \n",(ULONG)t_MyHookAddress)); WPOFF(); //清除CR0 //提升IRQL中断级 Irql=KeRaiseIrqlToDpcLevel(); //完成SSDT HOOK *(ULONG*)uNtGetContextThreadAddress = (ULONG)MyNtGetThreadContext; *(ULONG*)uNtSetContextThreadAddress = (ULONG)MyNtSetThreadContext; //恢复Irql KeLowerIrql(Irql); WPON(); //恢复CR0 return STATUS_UNSUCCESSFUL; } 另外还有一些功能型的函数一并给出,省的大家迷糊 我也算服务到位了,再看上面代码迷糊的时候。看这里找找 看看有没有能用到的,或者翻一下我以往的帖子。里面应该有 代码: 复制代码 //保存5字节代码的结构 #pragma pack(1) typedef struct _TOP5CODE { UCHAR instruction; //指令 ULONG address; //地址 }TOP5CODE,*PTOP5CODE; #pragma pack( ) //ssdt表结构 typedef struct _ServiceDescriptorTable { PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 }*PServiceDescriptorTable; //由SSDT索引号获取当前函数地址 //NtOpenProcess [[KeServiceDescriptorTable]+0x7A*4] extern PServiceDescriptorTable KeServiceDescriptorTable; // // 名称: MyGetFunAddress // 功能: 获取函数地址 // 参数: 函数名称字符串指针 // 返回: 函数地址 // ULONG MyGetFunAddress( IN PCWSTR FunctionName) { UNICODE_STRING UniCodeFunctionName; RtlInitUnicodeString( &UniCodeFunctionName, FunctionName ); return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName ); } // // 名称: myGetCurrentAddress // 功能: 获取SSDT表中指定函数的当前地址 // 参数: index:指定函数在表中的索引号 // 返回: 地址 // ULONG myGetCurrentAddress(IN ULONG index) { ULONG SSDT_Cur_Addr; __asm { push ebx push eax mov ebx,KeServiceDescriptorTable mov ebx,[ebx] mov eax,index shl eax,2 add ebx,eax mov ebx,[ebx] mov SSDT_Cur_Addr,ebx pop eax pop ebx } return SSDT_Cur_Addr; } VOID WPOFF() { __asm { cli mov eax,cr0 and eax,not 10000h mov cr0,eax } } VOID WPON() { __asm { mov eax,cr0 or eax,10000h mov cr0,eax sti } } 记在最后面的话:大家要善用搜索引擎(建议学习google hacking技巧),勤做笔记 |