出處: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(零魂)