时间:
2008
年
2
月
20
日星期三,
9
时
47
分
26
秒
IsDebuggerPresent
检测调试器
新建
vc++ console
项目,采用
Windbg
调试:
(1)
启动
windbg
用户级调试
(2)
设置调试符号路径
(3)
bp main
,
main
函数处下断
(4)
F5
,断点命中
(6)
在
windbg
中输入
dt -v ntdll!_TEB,
得到
_TEB
结构的详细信息
0:000> dt -v ntdll!_TEB
struct _TEB, 66 elements, 0xfb8 bytes
+0x000 NtTib : struct _NT_TIB, 8 elements, 0x1c bytes
+0x01c EnvironmentPointer : Ptr32 to Void
+0x020 ClientId : struct _CLIENT_ID, 2 elements, 0x8 bytes
+0x028 ActiveRpcHandle : Ptr32 to Void
+0x02c ThreadLocalStoragePointer : Ptr32 to Void
+0x030 ProcessEnvironmentBlock : Ptr32 to struct _PEB, 65 elements, 0x210 bytes
+0x034 LastErrorValue : Uint4B
+0x038 CountOfOwnedCriticalSections : Uint4B
+0x03c CsrClientThread : Ptr32 to Void
+0x040 Win32ThreadInfo : Ptr32 to Void
......
省略
(7)
输入
dt -v ntdll!_PEB
得到
PEB
的结构信息
0:000> dt -v ntdll!_PEB
struct _PEB, 65 elements, 0x210 bytes
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
+0x003 SpareBool : UChar
+0x004 Mutant : Ptr32 to Void
+0x008 ImageBaseAddress : Ptr32 to Void
+0x00c Ldr : Ptr32 to struct _PEB_LDR_DATA, 7 elements, 0x28 bytes
......
省略
(8)
准备工作完成,下面查找
IsDebuggerPresent
的实现
当前项目中调用
IsDebuggerPresent
的汇编代码:
00415095 8bf4
mov esi,esp
00415097 ff15ac934200 call dword ptr [IsDebuggerPresent!_imp__IsDebuggerPresent
(004293ac)]
0041509d 3bf4
cmp esi,esp
_imp__IsDebuggerPresent
处反汇编信息:
_imp__IsDebuggerPresent:
004293ac
032e
add ebp,dword ptr [esi]
004293ae
817cad97807cab14 cmp dword ptr [ebp+ebp*4-69h],14AB7C80h
004293b6 817c7f5d877c66aa cmp
dword ptr [edi+edi*2+5Dh],0AA667C87h
004293be 807c59b880
cmp byte ptr [ecx+ebx*2-48h],80h
IsDebuggerPresent
实现的汇编代码
kernel32!IsDebuggerPresent:
7c
812e03 64a118000000
mov eax,dword ptr fs:[00000018h]
7c812e09 8b4030
mov eax,dword ptr [eax+30h]
7c812e0c 0fb64002
movzx eax,byte ptr [eax+2]
7c812e10 c3
ret
分析
IsDebuggerPresent
实现代码
:
mov eax,dword ptr fs:[00000018h] //
得到当前
TEB
mov eax,dword ptr [eax+30h] //
得到
TEB
结构中的
PEB
结构
movzx eax,byte ptr [eax+2] //
得到
PEB
结构中的
BeingDebugged
标记
Ret
在
VC
中测试下面手动调用
IsDebuggerPresent
代码有误
《脱壳艺术》中给出的代码
:
call [IsDebuggerPresent]
test eax,eax
jnz .debugger_found
上述代码在
VC Debug
模式汇编代码是:
00415095 8B F4 mov esi,esp
00415097 FF 15 AC 93 42 00 call __imp__IsDebuggerPresent@0 //
这个调用明显出错
0041509D 3B F4 cmp esi,esp
更正后的代码:
mov eax , IsDebuggerPresent
call eax
test
eax,eax
jnz
.debugger_found
更正后代码在
VC Debug
模式的汇编代码是:
004120FC A1 AC 93 42 00 mov eax,dword ptr [__imp__IsDebuggerPresent@0 (4293ACh)]
00412101 FF D0 call eax // OK
VC
中直接
IsDebuggerPresent
API
调用的汇编代码是:
004120E5 8B F4 mov esi,esp
004120E7 FF 15 AC 93 42 00 call dword ptr [__imp__IsDebuggerPresent@0 (4293ACh)]
004120ED 3B F4 cmp esi,esp
由此可以看出
《脱壳艺术》中给出的代码
是错误的
.