;...more instructions
;compute delta between RDTSC instructions
rdtsc
;Check high order bits
cmp edx,ebx
ja .debugger_found
;Check low order bits
sub eax,ecx
cmp eax,0x200
ja .debugger_found
其它的时间检查手段包括使用 kernel32!GetTickCount() API, 或者手工检查位于
0x7FFE0000 地址的 SharedUserData
7
数据结构的 TickCountLow 及 TickCountMultiplier 成
员。
使用垃圾代码或者其它混淆技术进行隐藏以后,这些时间检查手段尤其是使用 RDTSC
将会变得难于识别。
对策
一种方法就是找出时间检查代码的确切位置,避免步过这些代码。逆向分析人员可以在
增量比较代码之前下断然后用 运行 代替 步过 直到断点断下来。另外也可以下
GetTickCount()断点以确定这个 API 在什么地方被调用或者用来修改其返回值。
Olly Advanced 采用另一种方法——它安装了一个内核模式驱动程序做以下工作:
1 设置控制寄存器 CR4
8
中的时间戳禁止位(TSD),当这个位被设置后如果 RDTSC
指令在非 Ring0 下执行将会触发一个通用保护异常(GP)。
2 中断描述表(IDT)被设置以挂钩 GP 异常并且 RTDSC 的执行被过滤。如果是由
于 RDTSC 指令引发的 GP,那么仅仅将前次调用返回的时间戳加 1。
值得注意的是上面讨论的驱动可能会导致系统不稳定,应该始终在非生产机器或虚拟机
中进行尝试。
2.6 SeDebugPrivilege
默认情况下进程是没有 SeDebugPrivilege 权限的。然而进程通过 OllyDbg 和 WinDbg 之
类的调试器载入的时候,SeDebugPrivilege 权限被启用了。这种情况是由于调试器本身会调
整并启用 SeDebugPrivilege 权限,当被调试进程加载时 SeDebugPrivilege 权限也被继承了。
一些壳通过打开 CSRSS.EXE 进程间接地使用 SeDebugPrivilege 确定进程是否被调试。
如果能够打开 CSRSS.EXE 意味着进程启用了 SeDebugPrivilege 权限,由此可以推断进程正
在被调试。这个检查能起作用是因为 CSRSS.EXE 进程安全描述符只允许 SYSTEM 访问,
但是一旦进程拥有了 SeDebugPrivilege 权限,就可以忽视安全描述符
9
而访问其它进程。注
意默认情况下这一权限仅仅授予了 Administrators 组的成员。
示例