Dependency Walker使用說明

 

在Windows世界中,有無數塊活動的大陸,它們都有一個共同的名字——動態連接庫。如今就讓咱們走進這些神奇的活動大陸,找出它們隱藏已久的祕密吧! 


初窺門徑:Windows的基石

隨便打開一個系統目錄,一眼望去就能看到不少擴展名DLL的文件,這些就是常常說的「動態連接庫」,DLL是Dynamic Link Library(即「動態連接庫」)的縮寫。從Microsoft公司推出首個版本的Windows以來,動態連接庫就一直是這個操做系統的基礎。

1.看看DLL裏有什麼

與其用晦澀的專業術語來解決DLL是什麼,不如先來看看DLL裏有什麼。DLL和EXE文件同樣,其中包含的也是程序的二進制執行代碼和程序所需的資源(好比圖標、對話框、字符串等),但是爲何要把代碼放在DLL裏面,而不是作成EXE呢?其實DLL中的代碼是以API函數形式出現的,通俗地說,DLL中包含的程序代碼都被作成了一個個小模塊,應用程序經過按下所需DLL中特定的按鈕,來調用DLL中這個按鈕所表明的功能。在使用「記事本」等程序時,若是要保存文件或打開文件,就會彈出通用文件對話框,讓咱們選擇文件位置。你可知道,這就是調用了系統底層DLL中的通用對話框界面。

2.系統中幾個重要的DLL

Windows中有3個很是重要的底層DLL:Kernel32.dll、User32.dll、GDI32.dll。其中Kernel32.dll顧名思義就是內核相關的功能,主要包含用於管理內存、進程和線程的函數;而User32.dll中包含的則是用於執行用戶界面任務的函數,好比把用戶的鼠標點擊操做傳遞給窗口,以便窗口根據用戶的點擊來執行預約的事件;GDI32.dll的名稱用了縮寫,全稱是Graphical Device Interface(圖形設備接口),包含用於畫圖和顯示文本的函數,好比要顯示一個程序窗口,就調用了其中的函數來畫這個窗口。

3.爲何要用DLL

剛纔在談到這個問題的時候,咱們只是解釋了DLL將程序代碼封裝成函數的原理。爲何封裝成函數,就能成爲系統中大量使用DLL的理由呢?

①擴展應用程序

因爲DLL能被應用程序動態載入內存。因此,應用程序能夠在須要時纔將DLL載入到內存中,這讓程序的可維護性變得很高。好比QQ的視頻功能須要升級,那麼負責編寫QQ的程序員沒必要將QQ全部代碼都重寫,只需將視頻功能相關的DLL文件重寫便可。

②便於程序員合做

這個和咱們最終用戶關係不大,僅供瞭解。咱們都知道編程工具備不少,好比VB、VC、Delphi等,若是好幾我的合做來編寫一個大的程序,那麼可能有的人用VB,有的人用VC,每人負責的部分所使用的編程語言都不一樣,究竟放在哪一個編譯器中進行編譯呢?這就比如一羣來自各個國家的人在共同編寫一篇文章,若是他們所使用的語言都不一樣,寫出來的文章怎麼可能湊到一塊兒呢?而有了DLL後,可讓VC程序員寫一個DLL,而後VB程序員在程序中調用,無需爲怎麼將它們都編譯爲一個單獨的EXE而發愁了。

③節省內存

若是多個應用程序調用的是同一個動態連接庫,那麼這個DLL文件不會被重複屢次裝入內存中,而是由這些應用程序共享同一個已載入內存的DLL。就比如一個辦公室中,不多會爲每個員工配置一臺飲水機的,而是在一個公共位置放上一個飲水機,全部須要喝水的職員均可以共用這臺飲水機,下降了成本又節約了空間。

④共享程序資源

包括剛纔提到過的通用文件對話框在內,DLL文件提供了應用程序間共享資源的可能。資源能夠是程序對話框、字符串、圖標,或者聲音文件等。

⑤解決應用程序本地化問題

在下載了某個程序的漢化包後,打開漢化說明,常常能夠看到用下載包中的DLL文件覆蓋掉程序原來的DLL,漢化就完成了。這些程序都是將執行代碼和應用程序界面分開編寫了,因此漢化者只需簡單地將其中和程序界面相關的DLL漢化併發布便可。

求知若渴:探究DLL的真相
誰知道DLL裏究竟有多少函數,又有誰知道EXE調用了哪一個DLL的哪些函數?其實,這個問題並不難解決。還記不記得本刊2004年第6期的《無間盜IV——盜亦有盜》中介紹的分析EXE文件的工具Dependency Walker(如下簡稱Depends)今天咱們要用它當探險工具,把DLL真相探個統統透透。
1.看看DLL裏有多少函數
第一步:下載並解壓Depends,運行其中的depends.exe,而後選擇菜單「File→Open」(文件→打開),在文件選擇框中選中須要分析的DLL文件並打開,此處選擇QQ目錄下的QQZip.dll。
第二步:在程序左側的樹狀欄中就列出了這個DLL使用了哪些其餘DLL的功能函數(原來DLL中還能夠調用其餘DLL^O^),而右側的兩個分欄列表分別顯示了函數輸入及輸出表,函數輸出表即爲該DLL提供給其餘EXE或者DLL調用的函數的總列表。
第三步:函數輸出表的Function欄中即爲輸出函數的名稱(見圖1),在QQZip.dll中共發現了2個函數:Unzip、Zip。所以能夠判斷該DLL在QQ程序中負責壓縮和解壓縮的任務。

2.審審EXE究竟用了哪一個DLL
仍是拿QQ來做爲例子,在Depends中打開QQ.exe,這時界面左側的樹狀列表中顯示的就是QQ.exe調用的DLL列表(見圖2),若是展開這些DLL分支,還會發現其餘的DLL,這就說明QQ調用的這些DLL文件還有可能(幾乎是確定)再調用別的DLL。這就比如買了一臺新的DVD機,可能其中用的機芯是SONY的,而這個機芯裏的一個小電容又有多是別的公司的,這是一樣的道理。


3.用DLL看穿EXE真面目
剛纔獲得了QQ.exe所使用的DLL列表,其實經過這個列表,還能分析出不少別的信息。好比其中包含MFC42.dll,因此能夠判斷QQ.exe是採用VC(即Visual C++)編寫的,而包含WSOCK32.dll則說明這個程序帶有網絡通信功能(廢話!QQ若是不能網絡通信還有什麼用……)。如下是一個簡表,你們在分析別的EXE時能夠根據其所使用的DLL來對其功能進行初步判斷。
DLL文件名 能夠判斷出的EXE信息
MFC42.dll 使用VC5.0/6.0編寫。
VBRun*.dll 「*」表明數字版本號,使用VB3.0/4.0編寫。
MSVBVM50.dll 使用VB5.0編寫,在Windows 98(SE)上自帶該DLL。
MSVBVM60.dll 使用VB6.0編寫,在Windows Me/2000/XP等系統上自帶該DLL。
ADVAPI32.dll 可能會進行註冊表操做。
WSOCK32.dll 具有網絡通信功能。
WS2_32.dll 具有網絡通信功能。
WININET.dll 具有HTTP瀏覽、下載等功能,典型的例子是瀏覽器、下載工具。
WINMM.dll 具有多媒體播放能力。
DDRAW.dll 遊戲、高級圖像處理工具。
D3D*.dll 3D遊戲,或者動畫處理工具。
4.DLL是個大寶庫
除供應用程序調用函數的DLL外,還有另外一種用來保存資源的DLL,好比QQ目錄下的QQRes.dll,用Depends打開後發現沒有任何輸出函數,難道是一個雞肋DLL?但是改用資源工具Resource Hacker(下載地址:http://www.mydown.com/soft/42/42058.html)打開這個DLL後,就發現原來其中保存了這麼多QQ的資源,包括圖標、音樂、圖片、字符串、對話框……(見圖3)


刨根問底:DLL的寓言
DLL引發的故障是很常見的,爲何會引發故障?遇到故障怎麼解決?噓~偷聽一下DLL的對話,你就會明白了。
1.從搬運工談接口兼容性
在Windows工地上,有一個名叫EXE的包工頭,他手下有不少稱爲DLL的建築工人。其中有一個專門負責搬運的DLL(暫且稱爲「搬運工A」),每次須要搬運水泥時,包工頭EXE都只要對他喊一聲:「來!搬。」
過了一段時間,搬運工A以爲本身的效率過低,因而從原來的每次搬1袋水泥改爲了每次搬3袋水泥。改進了搬運方法後,EXE包工頭仍然每次只是喊一聲:「來!搬。」殊不知搬運工A已經改變了搬運的方法。
但又過了一段時間,包工頭EXE把搬運工A給辭退了,從別的工地上找來了另外一個DLL(暫且稱爲「搬運工B」)。這個搬運工在別的工地的時候,搬運東西特別快,因此包工頭EXE決定把搬運工做給「升級」一下。但真正開始工做時,包工頭才發現出了問題……如今無論叫幾遍「來!搬。」這個新來的搬運工B都不知道究竟應該搬什麼。
上面的例子中,搬運工A改進搬運方法,但EXE調用它的方法仍不變,這就是DLL升級的原理,改進了內部的實現方法,但調用接口不變,這樣EXE文件不用跟着升級,就能調用新版本的DLL了。而搬運工B的故事告訴咱們,無論新版本的DLL效率多高,若是接口(能夠理解爲DLL中輸出的函數名)與原來的不一致,那麼EXE就不知道也沒法調用它了。
2.登記×××的DLL
在系統故障中,有不少都是因爲DLL文件沒有註冊形成的,好比Windows XP的壓縮文件夾功能出現故障就頗有多是系統目錄中的zipfldr.dll沒有註冊形成的,這類故障的解決方法也大可能是運行以下命令:
regsvr32 DLL文件名
不少人不理解爲何要這麼作,是否是全部的DLL都能這樣作呢?
其實系統中有兩種DLL,一種是不需註冊便可使用的,另外一種則是必須通過系統登陸(即註冊)才能使用的。就好像一個臨時工,和一個記錄在員工名單上的長期合同工的區別同樣。如何才能區分這兩種DLL呢?方法很簡單,用剛纔的Depends打開這個DLL,一樣是看函數輸出表,若是其中包含如下兩個函數(前者是註冊DLL,後者是反註冊DLL),那麼就必定是須要註冊才能使用的DLL了。
DllRegisterServer
DllUnregisterServer
而regsvr32這個命令,實際上就是調用DLL中的這兩個函數(「regsvr32 /u DLL文件名」調用的即爲DllUnregisterServer反註冊函數)。
3.插件DLL的祕密
Winamp、Foobar 2000等不少軟件都具備插件功能,從網上下載一個DLL放在插件目錄下就能讓程序支持新的功能,這是怎麼作到的呢?就拿時下流行的播放軟件「千千靜聽」來舉例吧。
「千千靜聽」的插件目錄在該軟件安裝目錄下的Addin子目錄下,程序的插件目錄通常都會以「Plugins」、「Addin」來命名。在「千千靜聽」的插件目錄中有許多DLL文件,好比tt_asf.dll、tt_rm.dll等,從文件名中就能看出這些DLL是用來讓這個播放器支持各類不一樣類型的音頻文件的。一樣,用Depends打開這些文件,你就會發現這些文件的輸出函數表中都包括一個一樣的函數:ttpGetSoundAddIn(見圖4)。

這就是插件的祕密,各類支持插件功能的程序在發佈時,都會同時發佈一份插件協議,協議中規定了該程序將要調用的插件DLL中必須包含的函數名稱及相關的參數規則,而後第三方的插件程序員在編寫這個程序的插件時就根據這個插件的標準來編寫DLL的輸出函數。
①對於插件tt_asf.dll
ttplayer.exe(「千千靜聽」主程序)對tt_asf.dll說:「我要調用你的ttpGetSoundAddIn函數!」
tt_asf.dll回答:「OK。」
②若是把不相關的DLL放進AddIn目錄
ttplayer.exe對未知DLL說:「我要調用你的ttpGetSoundAddIn函數!」
tt_asf.dll回答:「那是什麼函數?歷來沒據說過!」html

相關文章
相關標籤/搜索