动态反调试技术

一、异常

1. SEH

2. SetUnhandledExceptionFilter()

  • 进程中发生异常,若SEH未处理或者注册的SEH不存在,此时会调用执行系统的kernel32!UnhandledExceptionFilter()API.该函数内部会运行系统的最后一个异常处理器(名为Top Level Exception Filter或Last Exception Filter).系统最后的异常处理器通常会弹出错误消息框,然后终止进程运行。
  • kernel32!UnhandledExceptionFilter()API内部调用了ntdll!NtQueryInformationProcess(ProcessDebugPort)这个API(静态反调试),来判断是否正在调试进程。若进程正常运行(非调试状态),则运行系统最后的异常处理器,否则将异常派送给调试器。通过kernel32!SetUnhandledExceptionFilter可以修改系统最后的异常处理器。
  • 基于异常的反调试技术中,通常先故意触发异常,然后在新注册的Last Exception Filter内部判断进程是正常运行还是调试运行,并根据判断结果修改EIP。

二、Timing Check

  • 在调试器中逐行跟踪代码比程序正常运行耗费的时间要长很多,Timing Check技术通过计算运行的时间差异来判断进程是否处于被调试状态。

1.时间间隔测量

测量时间间隔的方法有很多,例如
基于计数器

RDTSC (汇编指令)
kernel32!QueryPerformanceCounter() / ntdll!NtQueryPerformanceCounter()
kernel32!GetTickCount()

基于时间

timeGetTime()
__ftime()

计数器的精准程度从高到低:
RDTSC>NtQueryPerformanceCounter()>GetTickCount()

2.RDTSC

x64CPU中存在一个名为TSC(Time Stamp Counter时间戳计数器)的64位寄存器。RDTSC这个汇编指令将TSC值读入EDX:EAX寄存器(高32位被保存到EDX,低32位被保存到EAX)

三、陷阱标志

  • 陷阱标志指EFLAGS寄存器的第九个(Index 8)比特位, Trap Flag,(在x64dbg中表示为TF)
  • TF设置为1后,CPU将进入单步执行模式。单步执行模式中,CPU执行1条指令后即触发EXCEPTION_SINGLE_STEP异常,然后TF会自动清零(0)。

INT 2D

  • 在调试模式下执行完INT 2D后,下一条指令的第一个字节将被调试器忽略。(od的bug?)(若设置TF为1后再执行INT 2D,则不会忽略)

四、0xCC探测

API断点0xCC检测

五、比较校验和

推荐阅读更多精彩内容