bp $exentry
或bu @$exentry
。但是,这些都不起作用。一旦执行g
可执行文件,它就会在ntdll32!LdrpDoDebuggerBreak+0x2c
上中断。调用堆栈中没有任何内容可提供任何有用的信息。如果再次发出g
,可执行文件将终止运行。有关如何在不手动执行所有启动代码的情况下到达
main()
的任何建议?#1 楼
确保您具有正确的断点地址发出
lm
,没有符号的exe将显示为0:000> lm
start end module name
00400000 0040f000 image00400000 (no symbols)
比较
NtHeader->AddresssOfEntrypoint
与@$exentry
0:000> r $t0 = image00400000
0:000> ?? ((ntdll!_IMAGE_NT_HEADERS *) @@( poi( @$t0 + 0x3c ) + @$t0 ))->OptionalHeader.AddressOfEntryPoint + @$t0
unsigned int64 0x401280
0:000> ? @$exentry
Evaluate expression: 4199040 = 00401280
如果它们相同,则设置
bp @$exentry
或bp 401280
的断点仅在二进制文件中没有调试器检测的情况下都应在该地址正确地中断。如果您的二进制文件具有调试器检测功能,那么您可能需要检查DllInitRoutines Tls回调和其他可爱的技巧
输出示例exe文件,而在下面的$$ exentry处没有任何反调试技巧会正确破解
0:000> .lastevent
Last event: bc.a70: Break instruction exception - code 80000003 (first chance)
debugger time: Sun Sep 21 01:10:42.015 2014 (UTC + 5:30)
0:000> lm M *im*
start end module name
00400000 0040f000 image00400000 (no symbols)
0:000> $ binary without symbols whose module name is normally shown as imageXXXXXX
0:000> r $t0 = image00400000 ; $ set Pseudo Register to start
0:000> r $t1 = poi(@$t0+3c) ; $ find pointer to Ntheader
0:000> r? $t2 = (ntdll!_IMAGE_NT_HEADERS *) (@$t0 + @$t1) ; set c++ pseudo Register
0:000> ?? @$t2->OptionalHeader.AddressOfEntryPoint + @$t0 ; Find AddressofEntryPoint
unsigned int64 0x401280
0:000> ? @$exentry
Evaluate expression: 4199040 = 00401280
0:000> bp @$exentry
0:000> bl
0 e 00401280 0001 (0001) 0:**** image00400000+0x1280
0:000> g
Breakpoint 0 hit
image00400000+0x1280:
00401280 55 push ebp
0:000>
这是
not main()
的开始,通常称为c runtime init code
。如果您知道编译器通常可以发现初始化,则可能需要检查二进制文件以找到Main()。代码,这将是常见的代码