载入HelloWorld.exe之后我们看看加载了哪些模块:
查看一下堆栈:
都是ntdll中的函数,我们想要运行到HelloWorld.exe的main函数中停下。
这么办:
使用!dh命令。
帮助文档中给出!dh的解释如下:
The !dh extension displays the headers for the specified image.
Parameters
-
Options
-
Any one of the following options:
-
-f
-
Displays file headers.
-s
-
Displays section headers.
-a
-
Displays all header information.
Address
-
-
Specifies the hexadecimal address of the image.
执行命令:
可以看到入口点地址为112C6,这个是RVA,即相对虚拟地址。什么是相对虚拟地址呢?我们往下看。
我们使用lm命令查看到start下的地址,就是HelloWorld.exe模块加载到内存之后的一个虚拟地址的起始位置,之所以称之为虚拟地址,就是因为它是在4G内存(32位)中的一个相对位置。
这里是0x1180000:
而相对虚拟地址就是相对于1180000的位置再偏移112C6,即112C6+1180000 = 11912C6,得到的就是入口点的虚拟地址。再不明白就如下图所示:
这时我们得到入口点的地址为11912C6,下断点:
运行,命中0号断点:
此时Disassembly窗口显示如下:
再单步运行一步就跳到了main:
对应的Disassembly窗口显示如下:
顺便提一下:
push ebp
mov ebp,esp
是典型的进入一个函数的头两个指令。他们的作用是将上一个函数的基址先进栈,而后将当前esp所指位置设为当前函数的基址。
这里的”___security_init_cookie“是设置一个security cookie,防止堆栈溢出,以后可以跟进这个call,查看具体实现的细节,相关内容可以参考:
http://blog.sina.com.cn/s/blog_4e0987310101ie77.html
跟入
__tmainCRTStartu
可以看到该main函数中具体细节。