脱壳的艺术2
2 调试器检测技术本节列出了壳用来确定进程是否被调试或者系统内是否有调试器正在运行的技术。这些调试器检测技术既有非常简单(明显)的检查,也有涉及到native APIs和内核对象的。
2.1 PEB.BeingDebugged Flag : IsDebuggerPresent()
最基本的调试器检测技术就是检测进程环境块(PEB)1中的BeingDebugged标志。kernel32!IsDebuggerPresent() API检查这个标志以确定进程是否正在被用户模式的调试器调试。
下面显示了IsDebuggerPresent() API的实现代码。首先访问线程环境块(TEB)2得到PEB的地址,然后检查PEB偏移0x02位置的BeingDebugged标志。
mov eax, large fs: 18h
mov eax,
movzx eax, byte ptr
retn
除了直接调用IsDebuggerPresent(),有些壳会手工检查PEB中的BeingDebugged标志以防逆向分析人员在这个API上设置断点或打补丁。
示例
下面是调用IsDebuggerPresent() API和使用PEB.BeingDebugged标志确定调试器是否存在的示例代码。
;call kernel32!IsDebuggerPresent()
call
test eax,eax
jnz .debugger_found
;check PEB.BeingDebugged directly
Mov eax,dword ;EAX =TEB.ProcessEnvironmentBlock
movzx eax,byte ;AL=PEB.BeingDebugged
test eax,eax
jnz .debugger_found
由于这些检查很明显,壳一般都会用后面章节将会讨论的垃圾代码或者反—反编译技术进行混淆。
对策
人工将PEB.BeingDebugged标志置0可轻易躲过这个检测。在数据窗口中Ctrl+G(前往表达式)输入fs:,可以在OllyDbg中查看PEB数据。
另外Ollyscript命令"dbh"可以补丁这个标志。
dbh
最后,Olly Advanced3 插件有置BeingDebugged标志为0的选项。 本帖最后由 whypro 于 2010-5-27 20:27 编辑
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data
szText db "嘿嘿,这是一个aitdbug程序……", 0
szCaption db "debugger_found", 0
szCaptionone db "no_found",0
.code
include testw.Inc
main:
jmp Do_It
debugger_found:
invoke MessageBox, NULL, addr szText, addr szCaption, MB_OK
invoke ExitProcess, 0
Do_It:
;invoke IsDebuggerPresent
assume fs:nothing
mov eax,fs:
movzx eax,byte ptr
test eax,eax
jnz debugger_found
invoke MessageBox, NULL, addr szText, addr szCaptionone, MB_OK
invoke ExitProcess, 0
end main 谢谢了,学习了
页:
[1]