出处:http://hi.baidu.com/0soul/blog/item/b62f8f08c2c3c42c6b60fbbe.html
先声明下:这个和脱壳没关系,不是找壳里面的程序入口哦,只是程序本身的入口,个别朋友不要误会哈。
其实这个应该是基础,但我经常找入口的时候翻半天......所以还是记录下来,万一时间久了又犯迷糊的时候可以查阅,呵呵。
一般用OllyDBG打开程序的时候,并不是直接定位到程序入口,而是还要先进行一系列的初始化工作,但做这些工作的反汇编代码我们是不需要的,所以我们要快速跳过,直接到程序入口。
我先把方法写出来,然后再简单分析一下初始化的时候都干了什么。
1.一路F8下去,分别步过下列两个函数:
call dword ptr ds:[<&KERNEL32.GetVersion>] ; kernel32.GetVersion
call dword ptr ds:[<&KERNEL32.GetCommandLineA>] ; kernel32.GetCommandLineA
2.GetCommandLineA下面会有好几个Call,第1个Call完了后隔一行以后会有连续的3个Call,连续的3个Call完了后再往下遇到的一个Call就是程序入口的Call了。
也就是,从GetCommandLineA往下数(不包括GetCommandLineA本身),第5个Call一般就是程序入口点的Call,F7进去就可以了。
PS:如果是用IDA5反汇编的话,我们点一下“_main proc near”处,然后 Run to cursor(F4)一下基本会直接定位到入口处。
方法很简单,那来看看在进入程序入口之前,都干了些什么吧。
下面这个是刚用OllyDBG打开程序的截图。
可以看到,第一个Call就是GetVersion,很好理解,就是获得Windows版本号。
继续往下。
看看我选定的部分,其中有5个Call,最后一个就是我们前面所找的入口处,前面的四个Call的函数分别是:
__crtGetEnvironmentStringsA
_setargv()
_setenvp()
_cinit()
需要注意的是,很多反汇编代码里面,后面的这三个函数名都不会被直接显示出来,而是显示的函数地址。
__crtGetEnvironmentStringsA我猜是GetEnvironmentStringsA()的宏定义名称(如果有错还请指出)。
GetEnvironmentStringsA()的作用是返回环境变量。
http://msdn.microsoft.com/en-us/library/ms683187(VS.85).aspx
_setargv()通过函数名就可以看出,是用来处理命令行参数的。
_setenvp()同样是处理环境变量的。
这两个函数的作用效果是把参数和环境变量保存到附近的可用“堆(heap)”里面,方便使用。
_cinit()的作用就是当检测到我们的参数覆盖了返回地址,能造成缓冲区溢出的时候报错并退出程序。平时我们遇到的讨厌的“遇到问题需要关闭”貌似就是这玩意搞的。
http://msdn.microsoft.com/en-us/library/ms924298.aspx
下面这个是用的微软官方测试代码的效果截图。
Author:zerosoul(零魂)