首页 > 程序开发 > 软件开发 > C语言 >

c程序的启动过程的反汇编分析

2014-07-20

0x01 工具准备 1 最简c代码一只, int main(){ return 0;} 2 ollydbg 3 VC& 43;& 43;6 0 4 GCC(mingw) 0x02 代码分析 int main() { return 0; } 在gcc下,添加-nostdlib编译选项,即链接器不链接标准

0x01 工具准备

1.最简c代码一只,

int main(){

return 0;}

2.ollydbg

3.VC++6.0

4.GCC(mingw)

0x02 代码分析

int main()

{

return 0;

}

在gcc下,添加-nostdlib编译选项,即链接器不链接标准库,会提示以下错误信息:

D:\Backup\我的文档\src>gcc main.c -nostdlib-o main.exe

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccmSU3wr.o:main.c:(.text+0x9): undefined re

ference to `__main'

collect2.exe: error: ld returned 1 exit status

关于-nostdlib编译选项,只有命令行指定的项才传递给链接器。标准启动文件和库都不会传递给链接器。该选项隐式打开选项-nostartfiles 和-nodefaultlibs。该选项也可以写作--no-standard-libraries。

在gcc执行汇编之后,在链接部分,当只打开选项-nostartfiles时,结果正常,未出现错误信息。而在-nodefaultlibs选项中,提示很多错误信息。

vcHL0rvQqbqvyv2jrMD9yOdwcmVfY3BwX2luaXShomNoZWNrX21hbmFnZWRfYXBwoaJwcmVfY19pbml0oaJfdG1haW5DUlRTdGFydHVwoaJfSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2VQb2ludGVyoaJkdXBsaWNhdGVfcHBzdHJpbmdzoaJXaW5NYWluQ1JUU3RhcnR1cKGibWFpbkNSVFN0YXJ0dXChol9taW5nd19wcmVwYXJlX2V4Y2VwdF9mcl9tc3ZjcjgwX2FuZF9oaWdoZXKhrS48L3A+CjxwPrvjseDA78PmtcRfbWFpbr7NysdD0+/R1MDvw+a1xG1haW6jrMrH0vLOqrvjseDG97rNQ7Hg0uvG97bUt/u6xbXEw/zD+7Lu0ru49s/Cu67P36GjPC9wPgo8cD7BtL3Txve74dTaz7XNs7Hq17y/4s7EvP6jrMDgJiMyMDI4NDvT2i9saWIvY3J0Mi5vtcTOxLz+1tCjrNGw1dJfc3RhcnS3+7rFo6zIu7rz1Npfc3RhcnTW0Na00NC0tL2ottG21M/zo6zVu6OstPK/qs+1zbPUpM/IzOG5qbXEyeixuKOsvathcmd2LGFyZ2Oyzsr9tKvI621haW66r8r9o6zIu7rztffTw21haW66r8r9oaM8L3A+CjxoMT4KPHA+MHgwMyAgdmMgbWFpbrqvyv23tLvjseC31s72PC9wPgo8L2gxPgo8cD48L3A+CjxwPjE6ICAgIGludCBtYWluKCk8L3A+CjxwPjI6ICAgIHs8L3A+CjxwPjAwNDAxMDEwICAgcHVzaCAgICAgICAgZWJwICAgLy/U2rbR1bvJz7GjtOZFQlA8L3A+CjxwPjAwNDAxMDExICAgbW92ICAgICAgICAgZWJwLGVzcCAvL72rttHVu7Wxx7DOu9bDuPhFQlCjrNLU1Nq20dW7veG5udbQtOa0oiYjMjA1NDA7yrG1xLLOv7y14zwvcD4KPHA+MDA0MDEwMTMgICBzdWIgICAgICAgICBlc3AsNDBoIC8vt9bF5L/VvOQ8L3A+CjxwPjAwNDAxMDE2ICAgcHVzaCAgICAgICAgZWJ4ICAvL7GjtObK/b7dts4mIzIwNTQwOzwvcD4KPHA+MDA0MDEwMTcgICBwdXNoICAgICAgICBlc2kgLy/UtLXY1rfWuNXrPC9wPgo8cD4wMDQwMTAxOCAgIHB1c2ggICAgICAgIGVkaSAvL8S/tcS12Na31rjV6zwvcD4KPHA+MDA0MDEwMTkgICBsZWEgICAgICAgICBlZGksW2VicC00MGhdIC8v17DI69PQ0Ke12Na3o6zTw8C0tcO1vb7Wsr+x5MG/us26r8r9ss7K/bXE1rjV66Gj1eLA71tlYnAtNDBoXb7Nyse7+bXY1rfU2c/yz8LGq9LGNDBoo6y+zcrHx7DD5su1tcTOqrG+tdix5MG/wfSz9rXEv9W85LXExvDKvLXY1reju72r1eK49iYjMjA1NDA717DU2MjrZWRpvMS05sb3o6y007b4tcO1vb7Wsr+x5MG/tcS12Na3PC9wPgo8cD4wMDQwMTAxQyAgIG1vdiAgICAgICAgIGVjeCwxMGggLy/U2mVjeLzEtObG97TmtKIxMGg8L3A+CjxwPjAwNDAxMDIxICAgbW92ICAgICAgICAgZWF4LDBDQ0NDQ0NDQ2g8L3A+CjxwPjAwNDAxMDI2ICAgcmVwIHN0b3MgICAgZHdvcmQgcHRyIFtlZGldIC8vs/XKvLuvvtayv7Hkwb+/1bzkLGRzOltlZGldPC9wPgo8cD4zOiAgICAgICAgcmV0dXJuIDA7PC9wPgo8cD4wMDQwMTAyOCAgIHhvciAgICAgICAgIGVheCxlYXg8L3A+CjxwPjQ6ICAgIH08L3A+CjxwPjAwNDAxMDJBICAgcG9wICAgICAgICAgZWRpIC8vu9a4tMv509C8xLTmxve1xCYjMjA1NDA7PC9wPgo8cD4wMDQwMTAyQiAgIHBvcCAgICAgICAgIGVzaTwvcD4KPHA+MDA0MDEwMkMgICBwb3AgICAgICAgICBlYng8L3A+CjxwPjAwNDAxMDJEICAgbW92ICAgICAgICAgZXNwLGVicCAvL7vWuLS20dW7PC9wPgo8cD4wMDQwMTAyRiAgIHBvcCAgICAgICAgIGVicDwvcD4KPHA+MDA0MDEwMzAgICByZXQgLy+3tbvYtb3UtEVJULXY1rc8L3A+CjxwPiA8L3A+CjxwPlZjsum/tLX308PVu6Osv8nS1L+0tb3U2m1haW66r8r91q7HsKOsz7XNs7u5xvS2r8HLbWFpbkNSVFN0YXJ0dXC6r8r9o6zV4rj2uq/K/crHv9jWxsyou7e+s8/CtuDX1r3aseDC67XExvS2r7qvyv2ho9Taa2VybmVsMzIuZGxs1tC12Na3N2M4MTZmZDe0prX308PBy21haW5DUlRTdGFydHVwuq/K/aGjPC9wPgo8cD5tYWluKCkgbGluZSAyPC9wPgo8cD5tYWluQ1JUU3RhcnR1cCgpIGxpbmUgMjA2ICYjNDM7IDI1IGJ5dGVzPC9wPgo8cD5LRVJORUwzMiEgN2M4MTZmZDcoKTwvcD4KPGgxPgo8cD4weDA0IG9sbHlkYme3tLvjseC31s72PC9wPgo8L2gxPgo8cD48YnI+CjwvcD4KPHA+T2TU2Mjro6zI5828y/nKvqGjPC9wPgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140720/20140720085845402.png" alt="\">


堆栈窗口如图所示。

\


通过堆栈,可以看到kelnel32调用了入口函数(mainCRTStartup),对于od来说,main函数并不是Entry point,而是mainCRTStartup函数。

一直单步,单步到00401146处,od分析为调用GetVersion函数,获取当前运行平台的版本号,因为是控制台程序,所以获取版本号为ms-dos的版本信息。

继续单步,单步到0040119E处,单步进入,可以看到有HeapCreate申请堆空间函数,大小由传递的参数决定,并且该call里有HeapDestroy销毁堆函数。因此0040119E为初始化堆空间,如图所示。

\


在004011C0处,od分析为GetCommandLineA函数,获取命令行参数信息的首地址。

进入下面的那个call后,可以看到GetEnvironmentStringsW和GetEnvironmentStrings函数,获取环境变量的首地址,如图所示。以Unicode编码形式返回到寄存器和堆栈中,最后采用WideCharToMultiByte函数将Unicode字符串到一个多字节字符串,

M8觍ff鷌9䴕Z喎阅读《c++反汇编与逆向分析技术揭秘》,在阅读到第三章认识启动函数,找到用户入口时,得知main函数之前系统要做一些准备工作,再加上上学期学的C语言程序入口函数不是main函数,而是_start函数,这不禁引发了一些思考,到底编译器在编译和系统执行程序的时候发生了什么,因此想以实例进行一定的分析。在思考的过程中,有些涉及到了编译器的知识,包括它如何工作的,汇编之后又是如何链接的,这一部分内容不太熟悉,这一方面得掌握编译原理的知识,还得学习编译器的相关内容。那些东西还没学,因此不免有一些缺憾。了解反汇编的一些内容,可以更深层次的理解相对底层的一些东西,包括栈,堆和寄存器的数据交换。另外并未使用到神器IDA,利用IDA会更好地静态分析一些函数。


相关文章
最新文章
热点推荐