为什么这段代码能让我检测调试器?

0x9*_*x90 16 windows debugging x86 assembly reverse-engineering

为什么以下汇编代码是反调试工具?

l1:
call l3
l2:
;some code
l3:
mov al, 0c3h
mov edi, offset l3
or ecx, -1
rep stosb
Run Code Online (Sandbox Code Playgroud)

我知道C3hRETN,我知道根据偏移量stobs将值al作为操作码写入,edi并且ecx因为时间而完成rep.

我也知道的事实,stobsstosw会如果他们是基于英特尔架构的预取为原来的形式进行.

如果我们以调试模式运行程序,预取是无关紧要的,并且l2标签将运行(因为它是单步)否则如果没有调试器它将在l1和l3之间打乒乓我对吗?

Paw*_*pak 14

当调试程序时(即单步),在每一步(当发生中断时)刷新预取队列.但是,正常执行时不会发生rep stosb.即使存在对缓存区域的内存写入,较旧的处理器也没有刷新它,以便支持除了rep movs和之外已更改的自修改代码rep stosb.(IIRC最终修复了i7处理器.)

这就是为什么如果有一个调试器(单步)代码将正确执行,何时rep stosb被替换ret l2将被执行.当没有调试器rep stosb将继续时,因为ecx它是最大可能的,它最终会写在某个地方它不应该写,并且会发生异常.

本文描述了这种反调试技术.