使用windbg查找可执行文件的main()函数

逆向工程 风袋
2021-06-21 21:46:43

我有一个没有调试符号的可执行文件,我想了解它的main()功能。

我所做的是在$exentry地址处放置断点,但是这个地址是一些 CRT 初始化的地址。要到达main()我需要单步执行,直到我看到工作应用程序发生了一些变化。

有没有其他程序可以跳过 CRT 代码?

1个回答

没有快捷方式加载器只知道 $exentry 因为它是 PeHeader 中
从那里到 main的嵌入指针主要通过单步或通过实践和经验观察和识别已知函数来遍历
crt 代码相当普遍,并且crt 的源可在任何 Visual Studio 安装的 crt 文件夹中找到(如果您有带有调试信息的二进制文件,这将有所帮助

如果二进制文件在发布模式下没有 debuginfo 被剥离或构建,crt src 将无法帮助您查明 main()

在这种情况下,您应该能够识别 crt 将要进行的某些标准调用,例如它通常会调用kernel32!GetCommandLineXXXX settig 该函数上的 bp 使您更接近 main() 另一个可以设置断点的函数是 kernel32!GetEnvironemStringXXXX ,然后在达到这些断点后在结果上设置硬件中断,您可以使用 main int main (int argc , char **argv , char* envp) 构造的标准原型来识别您的主要

:\>cdb -c "bp $exentry;g;bp kernel32!GetCommandlineA;g;g poi(@esp)" hell.exe

0:000> cdb: Reading initial command 'bp $exentry;g;bp kernel32!GetCommandlineA;g;g poi(@esp)'
Breakpoint 0 hit
Breakpoint 1 hit
eax=002b36d8 ebx=7ffdf000 ecx=002b47e8 edx=002b4813 esi=00000000 edi=00000000
eip=01314082 esp=0024f9b0 ebp=0024f9e4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image01310000+0x4082:
01314082 a3c4933201      mov     dword ptr [image01310000+0x193c4 (013293c4)],ea
x ds:0023:013293c4=00000000

exec_main 和 getcommandline 函数的面积和距离与 ollydbg 调试同一个可执行文件的镜像相同

在此处输入图片说明

使用 debuginfo /Zi msvc 编译器构建的相同 src和快照 在此处输入图片说明

为了更接近,您可以使用 int argc 执行二进制文件,这样您就知道如果没有向二进制文件传递参数,则传递了多少个参数,如果传递了 8 个参数,则 int argc 将等于 1 int argc 将等于 9

考虑到这一点,一旦到达上面枚举的断点,您就可以运行一个循环来枚举堆栈中的 int argc

bp $exentry
bp kernel32!GetCommandLineA
g
g
g poi(@esp)
.while(@$t0= 0) {
pc 
.if ( poi(@esp) == 1) {r $t0 = 1} .else { r $t0 = 0}
}  

运行脚本的结果请注意上面屏幕截图中的地址,您只需一次调用即可跳转到 main() 的包装器

cdb -c "$$>a< findwmain.txt" hell.exe

0:000> cdb: Reading initial command '$$>a< findwmain.txt'
Breakpoint 0 hit
Breakpoint 1 hit

eax=00000000 ebx=7ffd3000 ecx=00461228 edx=00461228 esi=00000000 edi=00000000
eip=000a40b5 esp=0034fb5c ebp=0034fb94 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
image000a0000+0x40b5:
000a40b5 e8e4420000      call    image000a0000+0x839e (000a839e)