-
-
[原创]抛砖引玉—硬件断点的检测和反检测
-
发表于:
2013-11-22 00:04
39615
-
硬件断点的检测和反检测
1、硬件断点设置的方法
有矛必有盾,有盾必有矛,说硬件断点的检测和反检测之前我们先来谈谈硬件断点设置的常规方法
方法1:
采用SetThreadContext直接设置指定线程的调试寄存器,由于这种方法简单实用,深受广大人民群众喜爱,具体怎么搞,附件代码中的SetHwBreakPoint函数有详细的code。
方法2:
采用SEH或者VEH等异常处理技术设置硬件断点,原理是自己搞个SEH或者VEH,然后自己触发一个异常(比如除0),跳到自己的异常处理函数中,这里只说SEH的异常处理函数结构:SEHHandler proc C _pstExceptionRecord:DWORD, _pstSEH:DWORD, _pstContext:DWORD, _pDispatcherContext:DWORD。第3个参数_pstContext就是异常线程的所有调试器结构指针,聪明的朋友肯定就知道该怎么搞了。不清楚的朋友可以去看看SEH实现的过程。
2、硬件断点的检测方法
方法1的检测方法:
GetThreadContext就是SetThreadContext的盾,把调试寄存器取过来送纪委检查检查就知道有没有人在干坏事了。
方法2的检测方法:
其实同样是用方法2设置硬件断点的手段,只不过在SEH的异常处理函数中用_pstContext取调试寄存器送纪委就是了,当然用SEH只能检测当前线程的,要检测整个程序的还是用VEH好,方法类似。我附件里的SEHCheckHardPoint和SEHHandler就是一个简单的例子。
;名称:SEHCheckHardPoint
;功能:构建一个SEH,检测硬件断点
;参数:无
;返回:无
SEHCheckHardPoint proc
assume fs:nothing
push offset SEHTest_Ret ;压入安全代码的地址
push ebp ;保存ebp
push SEHHandler ;压入SEH回调函数
push fs:[0] ;保存原SEH
mov fs:[0], esp ;设置当前SEH
xor eax, eax
mov DWORD ptr [eax], 1 ;人为的产生一个异常
SEHTest_Ret:
pop fs:[0] ;恢复原SEH
add esp, 12 ;平衡堆栈
ret
SEHCheckHardPoint endp
;名称:SEHHandler
;功能:SEH的异常处理函数,为cdecl调用
;参数:_pstExceptionRecord = 异常信息结构指针
;参数:_pstSEH = SEH结构指针
;参数:_pstContext = 发生异常线程的寄存器结构指针
;参数:_pDispatcherContext
;返回:无
SEHHandler proc C _pstExceptionRecord:DWORD, _pstSEH:DWORD, _pstContext:DWORD, _pDispatcherContext:DWORD
pushad
mov ebx, _pstSEH
mov eax, [ebx + 8]
mov esi, _pstContext
assume esi:ptr CONTEXT
mov [esi].regEbp, eax ;恢复ebp
mov eax, [ebx + 12]
mov [esi].regEip, eax
invoke VK_PrintfMsg, CTXT("Dr0 = 0x%X"), [esi].iDr0 ;显示Dr0的值,如果不是0,说明被设硬件断点了
assume esi:nothing
popad
mov eax, ExceptionContinueExecution
ret
SEHHandler endp
7C92EAEC > 8B4C24 04 mov ecx,dword ptr ss:[esp+0x4]
7C92EAF0 8B1C24 mov ebx,dword ptr ss:[esp]
7C92EAF3 51 push ecx ; pContext
7C92EAF4 53 push ebx ; 压入pExceptionRecord
7C92EAF5 E8 C78C0200 call ntdll.7C9577C1 ; 调用RtlDispatchException
7C92EAFA 0AC0 or al,al ; 判断返回是否为0,即是否调用成功
7C92EAFC 74 0C je short ntdll.7C92EB0A ;失败则跳
7C92EAFE 5B pop ebx
7C92EAFF 59 pop ecx
7C92EB00 6A 00 push 0x0
7C92EB02 51 push ecx
7C92EB03 E8 11EBFFFF call ntdll.ZwContinue ; 调用RtlDispatchException成功则继续ZwContinue执行异常原来的代码
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课