取材于rootkit.com的一篇文章,因为简单就不按照原文严格翻译了。原文链接http://rootkit.com/newsread.php?newsid=669
第2dh
号中断处理函数是KiDebugService
,执行Int 2dh
指令时,进程如果没有处于被调试状态,将会抛出异常,如果在被调试状态则能够正常执行。我们可以利用这一点检测调试器的存在。
; Besides
this
,
int
2Dh can also be used
as
code obfuscation method.
; With attached debugger, after executing int 2Dh, system skips one byte
; after int 2Dh:
;
; int 2dh
; nop ; never executed
; ...
;
; With attached debugger, after executing int 2Dh, system skips one byte
; after int 2Dh:
;
; int 2dh
; nop ; never executed
; ...
;
说执行完
int 2dh指令后会跳过一字节指令的描述貌似有问题。实际测试了下,还是照常执行的。
OllyDbg
的行为比较特别。被OllyDbg
调试时如果Int 2dh
指令之后的下一条指令长于一字节,那么会引起异常,下一指令自然不执行。如果等于一字节长度那么不会引起异常,下一指令被跳过不执行。
顺便贴下我测试用的例子。
#include
<
Windows.h
>
#include < stdio.h >
DWORD dwTest = 0 ;
DWORD test()
... {
printf("正常 Test = %d ",dwTest);
return EXCEPTION_EXECUTE_HANDLER;
}
void main()
... {
__try
...{
__asm mov eax,dwTest
__asm int 2dh
__asm inc eax;被OD 调试时这句被跳过。
__asm mov dwTest,eax
printf("检测到调试器 Test = %d ",dwTest);
}
__except(test())
...{
}
system("pause");
}
#include < stdio.h >
DWORD dwTest = 0 ;
DWORD test()
... {
printf("正常 Test = %d ",dwTest);
return EXCEPTION_EXECUTE_HANDLER;
}
void main()
... {
__try
...{
__asm mov eax,dwTest
__asm int 2dh
__asm inc eax;被OD 调试时这句被跳过。
__asm mov dwTest,eax
printf("检测到调试器 Test = %d ",dwTest);
}
__except(test())
...{
}
system("pause");
}