程中安全提取動(dòng)態(tài)鏈接庫)
在CSDN上刷到這個(gè)問題時(shí)我第一反應(yīng)是有點(diǎn)復(fù)雜——求CSDN的技術(shù)大佬幫忙提取一下軟件里面的dll文件發(fā)帖人通常是把某個(gè)軟件裝在電腦里想從里面拿幾個(gè)dll文件出來。可能是為了備份、為了分析、為了修復(fù)另一個(gè)軟件的報(bào)錯(cuò)也可能是想看看別人是怎么寫的。這類需求在論壇里隔三差五就會(huì)出現(xiàn)但真正能把提取dll這件事講清楚、講透、講得不踩坑的帖子卻很少。我自己早期搞逆向分析、軟件封裝、系統(tǒng)遷移時(shí)也反復(fù)跟dll文件打交道踩過文件被占用、提取出來缺依賴、32位和64位搞混等各種坑。今天就把這套東西系統(tǒng)整理一遍從dll文件是什么、什么時(shí)候需要提取到具體的提取方案、工具選型、常見問題排查盡量用大白話加實(shí)操記錄的方式講明白。不管你是剛接觸dll的新手還是已經(jīng)會(huì)復(fù)制粘貼但不太理解原理的進(jìn)階用戶這篇文章都能讓你少走不少彎路。1. 先搞清楚dll文件到底是什么為什么有人要提取它1.1 dll文件的本質(zhì)動(dòng)態(tài)鏈接庫不是加密包dll的全稱是Dynamic Link Library也就是動(dòng)態(tài)鏈接庫。你可以把它理解成一個(gè)軟件運(yùn)行時(shí)需要調(diào)用的零件倉庫。軟件主程序exe本身只負(fù)責(zé)管流程真正干活的功能模塊——比如彈窗繪制、網(wǎng)絡(luò)請求解碼、圖片格式解析、加密算法運(yùn)算——都放在一堆dll文件里。主程序在啟動(dòng)或運(yùn)行到某個(gè)功能時(shí)才動(dòng)態(tài)把對應(yīng)的dll加載進(jìn)內(nèi)存調(diào)用里面的函數(shù)。這種設(shè)計(jì)的直接好處就是多個(gè)軟件可以共用同一個(gè)dll不必每個(gè)exe里都塞一份相同代碼省磁盤、省內(nèi)存也方便廠商單獨(dú)更新某個(gè)模塊。比如很多軟件都會(huì)復(fù)制一份msvcp140.dll到自己的目錄里而這個(gè)文件其實(shí)來自微軟的Visual C運(yùn)行庫。也正因?yàn)閐ll是零件倉庫當(dāng)你看到某個(gè)軟件目錄下躺著幾十上百個(gè)dll時(shí)根本不需要驚訝。像工業(yè)軟件、游戲、大型工具套件自帶幾十個(gè)甚至幾百個(gè)dll是很常見的事。1.2 常見需求場景不只是破解這一條路很多人一聽到提取dll就往破解方向想但實(shí)際工作中合法的、正經(jīng)的需求占了大頭。我自己歸納了一下最常見的場景有以下幾類系統(tǒng)修復(fù)某個(gè)軟件報(bào)錯(cuò)找不到xxx.dll但你又不想重裝整個(gè)軟件于是從原安裝包、從另一臺(tái)同配置電腦里把這個(gè)dll提取出來補(bǔ)上。版本備份與遷移老版本軟件升級前先把它依賴的dll備份下來防止新版本不兼容導(dǎo)致功能回退。學(xué)習(xí)與研究想看看某個(gè)軟件調(diào)用了哪些系統(tǒng)API、做了什么邏輯從dll里導(dǎo)出函數(shù)、看導(dǎo)入表、分析數(shù)據(jù)段這是很多安全研究者和技術(shù)愛好者的入門功課。封裝便攜版把軟件綠色化把所有依賴的dll和資源文件提取出來放到一起做到免安裝運(yùn)行。二次開發(fā)有些廠商提供了dll形式的SDK你需要在自己的程序里動(dòng)態(tài)調(diào)用這些dll的導(dǎo)出函數(shù)第一步當(dāng)然是把dll從官方安裝包中提取出來。這些需求的共通點(diǎn)是dll文件本身是軟件的一部分提取之后用于備份、修復(fù)、研究或集成而不是用來繞過授權(quán)。后者我既不做也不寫這篇文章只講正路子。1.3 先從要不要提取想清楚很多dll根本不該手動(dòng)碰在動(dòng)手之前我想先潑一盆冷水。dll不是純文本它是PE格式的二進(jìn)制文件Portable Executable內(nèi)部結(jié)構(gòu)包含DOS頭、PE頭、節(jié)區(qū)表、導(dǎo)入表、導(dǎo)出表、資源段等。直接拿記事本打開看到的全是亂碼。所以提取dll這件事本質(zhì)上是從指定位置把二進(jìn)制文件完整復(fù)制出來而不是解包出某種代碼。另外一點(diǎn)要提醒如果是Windows系統(tǒng)目錄里的dll比如C:WindowsSystem32下的絕大多數(shù)屬于系統(tǒng)組件不應(yīng)該去提取、覆蓋、刪除。微軟對系統(tǒng)文件有專門的文件保護(hù)機(jī)制你強(qiáng)行替換輕則觸發(fā)系統(tǒng)文件檢查報(bào)錯(cuò)重則導(dǎo)致系統(tǒng)不穩(wěn)定。普通用戶遇到某某dll缺失的報(bào)錯(cuò)時(shí)優(yōu)先級應(yīng)該是先用系統(tǒng)工具修復(fù)再考慮從可信來源復(fù)制而不是亂七八糟的下載站下個(gè)dll修復(fù)工具亂裝一通。所以這篇文章里的提取默認(rèn)指你有權(quán)訪問的、非系統(tǒng)關(guān)鍵路徑下的軟件dll比如自己電腦上安裝的第三方軟件目錄、官方安裝緩存包中的dll。這本身不需要任何破解手段最多就是繞開權(quán)限和占用問題。2. 提取前的基本功先摸清目標(biāo)dll的位置和狀態(tài)2.1 先做兩件事定位和確認(rèn)不管用什么方案動(dòng)手前必須先搞清楚兩個(gè)問題你要的dll在哪、它現(xiàn)在處于什么狀態(tài)。第一是位置。第三方軟件安裝后dll一般出現(xiàn)在以下幾個(gè)地方軟件安裝目錄根目錄比如C:Program FilesSomeApp。軟件的bin、lib、plugins、runtime等子目錄。Windows的System32或SysWOW64目錄如果這個(gè)軟件被系統(tǒng)級集成。安裝包緩存目錄比如C:ProgramDataPackage Cache這類位置。%AppData%或%LocalAppData%下部分UWP應(yīng)用或用戶級軟件會(huì)放在這里。定位方式很簡單拿到軟件快捷方式右鍵→打開文件所在位置基本就能看到主程序目錄。更穩(wěn)妥的是打開任務(wù)管理器切到詳細(xì)信息頁簽找到對應(yīng)軟件的進(jìn)程右鍵→打開文件所在位置這樣定位到的目錄一定是正在使用的dll所在目錄。第二是狀態(tài)。你要提取的dll是否正被某個(gè)進(jìn)程占用決定了你能不能直接復(fù)制。如果直接復(fù)制時(shí)報(bào)文件正在被另一個(gè)程序使用就說明它已經(jīng)加載到某個(gè)進(jìn)程內(nèi)存里了。這時(shí)候就有兩條路要么從進(jìn)程內(nèi)存中抓取方案三要么先關(guān)掉相關(guān)軟件再復(fù)制方案一。2.2 必備工具清單不需要重型武器提取dll這件事老實(shí)說并不需要什么高端工具。手頭有一臺(tái)Windows電腦、一雙能看提示信息的眼睛再加幾個(gè)免費(fèi)小工具基本就夠用了。我平時(shí)常用的工具清單如下工具用途是否需要安裝難度文件資源管理器定位dll、直接復(fù)制系統(tǒng)自帶入門7-Zip解壓exe/msi安裝包提取內(nèi)部文件綠色版即可入門Process Explorer查看進(jìn)程加載的dll、提取已加載dll免安裝中等proc_dump抓取進(jìn)程內(nèi)存中的模塊導(dǎo)出命令行工具進(jìn)階Dependencies查看dll的依賴關(guān)系、導(dǎo)出函數(shù)免安裝進(jìn)階資源管理器任務(wù)管理器結(jié)束占用進(jìn)程、查看PID系統(tǒng)自帶入門這些工具的共同點(diǎn)是不需要破解不需要注冊機(jī)官方渠道都能下載到。我不會(huì)推薦任何帶捆綁或者來源不明的dll修復(fù)大全之類的軟件那才是真正會(huì)把你電腦搞壞的東西。2.3 權(quán)限和32/64位的判斷提前確認(rèn)提取前我強(qiáng)烈建議你先確認(rèn)兩件事否則后面十有八九要返工。第一是權(quán)限。如果你要復(fù)制的dll位于Program Files、System32這類高權(quán)限目錄直接在資源管理器里復(fù)制粘貼可能會(huì)被拒。解決辦法是右鍵資源管理器選擇以管理員身份運(yùn)行或者先把目標(biāo)文件復(fù)制到當(dāng)前用戶有權(quán)限的目錄比如桌面、文檔文件夾再做后續(xù)處理。第二是位數(shù)判斷。dll分32位和64位兩種不能混用。怎么判斷一個(gè)dll是32位還是64位最簡單的方法裝一個(gè)Dependencies工具微軟官方有一些支持庫但Dependencies更好用把dll拖進(jìn)去工具會(huì)直接顯示它的PE格式是x86還是x64。沒有工具的情況下還有一個(gè)土辦法打開命令行進(jìn)入dll所在目錄用dumpbin /headers需要Visual Studio環(huán)境或者where /r C: xxx.dll配合file命令檢查但這些對小白不太友好。注意64位系統(tǒng)上System32目錄里放的是64位dllSysWOW64目錄里放的是32位dll名字雖然反直覺但這是Windows的設(shè)計(jì)。3. 四種最常用的dll提取方案與操作步驟3.1 方案一最基礎(chǔ)的文件復(fù)制法別嫌簡單適用場景軟件已經(jīng)安裝完成dll就在安裝目錄下且該軟件當(dāng)前沒有運(yùn)行。操作步驟很簡單定位到軟件安裝目錄找到目標(biāo)dll。右鍵復(fù)制粘貼到你要保存的地方。如果復(fù)制時(shí)提示權(quán)限不足或文件被占用先關(guān)閉軟件再以管理員身份打開資源管理器重試。這個(gè)方案的優(yōu)點(diǎn)是零學(xué)習(xí)成本不依賴任何外部工具。缺點(diǎn)也很明顯如果dll被占用你就復(fù)制不出來如果dll在安裝包內(nèi)部而非安裝目錄那你根本找不到它。所以它只能算基礎(chǔ)中的基礎(chǔ)。有一種情況要特別說明你在安裝目錄下找到的dll很可能不是完整的有效版本。比如某些軟件在啟動(dòng)時(shí)會(huì)動(dòng)態(tài)生成配置并寫入dll同目錄下的外部文件你復(fù)制出的dll本身沒問題但它依賴的配置、子目錄、資源文件沒有跟著復(fù)制所以提取出來看著有文件放到另一臺(tái)機(jī)器上卻跑不起來。這不算提取失敗而是只提取dll、沒有提取完整依賴導(dǎo)致的。后續(xù)要驗(yàn)證有效性時(shí)我會(huì)在第5章詳細(xì)說依賴檢查的方法。3.2 方案二從安裝包中解出dll沒有安裝也能拿適用場景你只有軟件的安裝程序setup.exe、installer.msi、.exe安裝包還沒安裝或者安裝目錄里沒有你想要的dll但你懷疑它在安裝包里。很多安裝包本質(zhì)上是一個(gè)自解壓壓縮殼里面打包了真正的安裝數(shù)據(jù)和文件流。用7-Zip直接打開setup.exe有時(shí)候能像看壓縮包一樣看到內(nèi)部目錄結(jié)構(gòu)。具體做法確保已安裝7-Zip。右鍵點(diǎn)擊安裝程序選擇打開壓縮包不能用解壓先打開看結(jié)構(gòu)。在打開的窗口里你會(huì)看到類似[0]、[1]編號的流或者$TEMP之類的目錄逐層進(jìn)入直到看到.dll、.exe、.cab、.msi等文件。選中目標(biāo)dll拖出來即可。這里有個(gè)關(guān)鍵點(diǎn)如果安裝包里面是一個(gè).msi文件不要直接解壓要用管理器模式提取這在方案四里說明。如果安裝包是Inno Setup封裝的怎么判斷用7-Zip打開后能看到{app}、{tmp}這種占位目錄基本就是Inno Setup那就用Inno Setup Unpacker這類專用工具它能更完整地解出內(nèi)部文件。7-Zip雖然能解出一部分但往往拿不到所有打包的組件。從安裝包提取有三點(diǎn)好處一是不需要先安裝完整軟件二是可以精確拿到原始未注冊的dll文件三是安裝包內(nèi)的dll通常沒有被占用復(fù)制過程干凈利落。但這一招也有局限安裝包可能對內(nèi)部文件做了壓縮甚至異或混淆直接解出來的是經(jīng)過處理的樁文件而不是真正的dll。我在處理國內(nèi)一些老牌軟件時(shí)遇到過好幾次解出來的文件大小不對、頭部信息損壞這時(shí)候只能先正常安裝再從安裝目錄提取。3.3 方案三從運(yùn)行中的進(jìn)程里抓取dll繞過文件占用適用場景軟件正在運(yùn)行dll已經(jīng)加載進(jìn)內(nèi)存但磁盤上的文件被鎖定無法復(fù)制。這一招也是做動(dòng)態(tài)分析的人最常用的基本功。這里要用到Process ExplorerSysinternals套件里的經(jīng)典工具微軟官方免費(fèi)免安裝直接運(yùn)行exe即可。操作步驟以管理員身份啟動(dòng)Process Explorer。在進(jìn)程列表里找到目標(biāo)軟件的主進(jìn)程通常和軟件同名比如MyApp.exe。如果你不懂怎么找可以先打開軟件再看。雙擊進(jìn)程打開進(jìn)程屬性面板切到Image或Strings頁簽——注意不同版本的Process Explorer界面不同新版通常在底部會(huì)有該進(jìn)程加載的所有dll列表。在dll列表里找到目標(biāo)dll選中它右鍵→Create Diff Image或者通過Strings查看詳細(xì)路徑。關(guān)鍵一步右鍵目標(biāo)dll→Save As把它保存到本機(jī)任意位置。這個(gè)Save As操作實(shí)際是把該dll的完整內(nèi)存鏡像寫出來得到的就是一份可用的dll文件副本。它最大的意義在于即使原始文件被刪除、被標(biāo)記為待刪除、或被獨(dú)占鎖定只要它在內(nèi)存中加載著你就能把它摳出來。我實(shí)際使用中發(fā)現(xiàn)的注意點(diǎn)如果你想要的是某個(gè)已經(jīng)被hook或者被修改過的dll從內(nèi)存里抓出來的是運(yùn)行時(shí)被修改后的版本而不是磁盤上的原始版本。做逆向分析時(shí)要注意這一點(diǎn)兩種版本可能不等同。Process Explorer的dll列表刷新頻率有限如果你剛啟動(dòng)軟件最好等幾秒讓列表穩(wěn)定后再保存。即便軟件當(dāng)前運(yùn)行正常也要先確認(rèn)進(jìn)程有權(quán)限訪問。用管理員身份運(yùn)行Process Explorer能避免很多Access Denied報(bào)錯(cuò)。如果在Process Explorer里找不到目標(biāo)dll還可以用命令行工具proc_dump定向抓取發(fā)布模塊。這個(gè)用法比較高級普通提取用不上我在這里只提一句proc_dump可以做進(jìn)程的內(nèi)存dump然后你用PE工具從dump文件里檢查模塊對動(dòng)態(tài)分析是很有用的路子。3.4 方案四從MSI安裝包中提取dll利用管理安裝模式適用場景你的安裝包是.msi格式或者setup.exe引導(dǎo)之后會(huì)在某個(gè)緩存目錄留下.msi文件你想不安裝直接拿到里面的dll。Windows Installer提供一個(gè)官方支持的管理安裝administrative install功能用命令行就能把MSI中的文件解到指定目錄。操作命令如下msiexec /a 路徑到你的安裝包.msi /qb TARGETDIRD:提取目錄參數(shù)說明/a啟用管理安裝模式它不會(huì)在系統(tǒng)里注冊軟件只是把安裝文件解壓到TARGETDIR指定的位置。/qb只顯示基本進(jìn)度條界面不需要你點(diǎn)按鈕。TARGETDIR解壓目標(biāo)目錄必須寫完整路徑路徑末尾不要省掉反斜杠盡量別有中文和空格避免出現(xiàn)解析問題。執(zhí)行完以后在D:提取目錄下通常會(huì)出現(xiàn)一個(gè)類似安裝后的目錄結(jié)構(gòu)你進(jìn)入對應(yīng)子目錄就能找到目標(biāo)dll。如果MSI包的某個(gè)文件被設(shè)置成僅在安裝時(shí)才生成這種模式解出來的可能是原始模板而不是最終落地的文件這一點(diǎn)同樣要在后續(xù)驗(yàn)證時(shí)注意。我自己處理setup.exe時(shí)常用Resource Hacker或者Universal Extractor一類工具先解出內(nèi)層的.msi再跑上面這條命令。整個(gè)過程比直接裝一遍軟件要快而且不污染系統(tǒng)。3.5 提取后的校驗(yàn)與歸檔復(fù)制出來并不是終點(diǎn)很多新手容易在這里翻車費(fèi)了老大勁把dll復(fù)制出來了結(jié)果放到另一臺(tái)電腦上一運(yùn)行還報(bào)錯(cuò)就認(rèn)為提取失敗了。其實(shí)文件本身很可能沒錯(cuò)是忽略了三件事。第一是校驗(yàn)文件是否完整。用右鍵→屬性→數(shù)字簽名查看簽名是否有效或用PowerShell命令Get-FileHash D:提取目錄your.dll -Algorithm SHA256如果軟件原版有簽名提取出來的dll哈希值應(yīng)該和原文件一致除非你從內(nèi)存里抓的是修改版。不一致時(shí)要警惕提取過程出問題。第二是記錄原文件的時(shí)間戳和版本號。在文件屬性→詳細(xì)信息里能看到文件版本、產(chǎn)品版本。我在做遷移備份時(shí)會(huì)把原始位置、原文件名、版本號、提取日期記到一個(gè)文本文件里和dll放一起。這不僅方便你事后追溯也方便你將來反查這個(gè)dll到底是哪個(gè)軟件裝的。第三是檢查依賴關(guān)系。dll之間是會(huì)互相調(diào)用的一個(gè)dll可能依賴另一個(gè)dll。你只把目標(biāo)dll提取出來但它的依賴dll沒提取放到干凈環(huán)境比如精簡版Windows虛擬機(jī)里自然跑不起來。關(guān)于依賴檢查的詳細(xì)操作我會(huì)在第5章展開講。4. 常見問題與排查技巧實(shí)錄4.1 文件被占用、權(quán)限不足Windows最經(jīng)典的攔路虎我在給同事遠(yuǎn)程指導(dǎo)時(shí)90%的人第一步就會(huì)卡在這個(gè)問題上。明明找到了dll一復(fù)制就彈文件正在被另一程序使用或需要管理員權(quán)限。排障順序如下先確認(rèn)軟件是否還在運(yùn)行任務(wù)管理器里把對應(yīng)進(jìn)程全部結(jié)束注意有些軟件會(huì)留常駐后臺(tái)進(jìn)程托盤區(qū)圖標(biāo)不算結(jié)束要去任務(wù)管理器詳細(xì)信息里一個(gè)個(gè)找。如果結(jié)束進(jìn)程后還是被占用有可能是Windows資源管理器緩存或殺毒軟件的實(shí)時(shí)防護(hù)在訪問該目錄。這時(shí)候把殺毒軟件實(shí)時(shí)防護(hù)臨時(shí)關(guān)掉再試或者直接進(jìn)安全模式操作。如果提示權(quán)限不足在資源管理器里對目標(biāo)文件夾右鍵→屬性→安全→編輯給當(dāng)前用戶加完全控制權(quán)限或者直接用管理員身份運(yùn)行資源管理器。還不行就用方案三從進(jìn)程內(nèi)存里抓。這里我提供一個(gè)很少人提的小技巧用handle.exeSysinternals的另一個(gè)工具可以精確查到底是誰占用了這個(gè)dllhandle.exe 你的dll文件名它會(huì)列出占用該文件的進(jìn)程PID和句柄類型你能看到是主程序占用還是某個(gè)插件進(jìn)程占用。知道是誰占用才能高效決定結(jié)束哪個(gè)進(jìn)程。4.2 提取出的dll在另一臺(tái)電腦上不能用依賴缺失和運(yùn)行庫缺失這種情況最典型也最容易讓新手崩潰。把dll復(fù)制到另一臺(tái)電腦后軟件還是報(bào)無法定位程序輸入點(diǎn)或無法加載DLL。問題大概率出在兩個(gè)方面第一目標(biāo)dll依賴了其他dll而這些依賴沒有跟著過去。解決方法是用Dependencies工具打開dll文件查看它的Imports導(dǎo)入表把缺失的依賴模塊一并提取。Dependencies會(huì)在左側(cè)列出一棵依賴樹缺失的項(xiàng)會(huì)用紅色或黃色標(biāo)出來。第二目標(biāo)dll本身依賴了Visual C運(yùn)行庫、.NET運(yùn)行時(shí)等系統(tǒng)組件。這類dll就算你復(fù)制一百個(gè)過去沒有運(yùn)行庫照樣跑不起來。報(bào)找不到MSVCP140.dll這類錯(cuò)誤時(shí)正確解法是裝對應(yīng)版本的Visual C Redistributable而不是去網(wǎng)上隨便下載一個(gè)dll丟進(jìn)System32。注意在純技術(shù)交流時(shí)我??吹接腥苏f從另一臺(tái)電腦拷dll過來就能修復(fù)這個(gè)說法只在特定條件下成立。除非你有十足把握確認(rèn)目標(biāo)系統(tǒng)缺的就是這一個(gè)文件且版本兼容否則后果是修好了這一個(gè)報(bào)錯(cuò)又冒出三個(gè)新報(bào)錯(cuò)。我真的建議優(yōu)先用運(yùn)行庫安裝包和系統(tǒng)自帶修復(fù)工具。4.3 32位dll被當(dāng)成64位用或者反過來Windows 64位系統(tǒng)上32位進(jìn)程運(yùn)行時(shí)需要的是SysWOW64目錄下的32位dll64位進(jìn)程需要的是System32目錄下的64位dll。名字聽著反直覺但這是微軟系統(tǒng)的老規(guī)矩。如果你提取出來的dll放錯(cuò)位置最常見的報(bào)錯(cuò)是不是有效的Win32應(yīng)用程序或者應(yīng)用程序無法啟動(dòng) 0xc000007b。判斷dll位數(shù)的方法除了用Dependencies還有一個(gè)輕量級技巧用記事本打開dll不可能得到結(jié)果但可以看它的頭部。用任意十六進(jìn)制工具打開dll找到PE頭區(qū)域如果顯示PE..L說明是64位PE..d?說明是32位準(zhǔn)確說在0x5C偏移處的機(jī)器碼0x8664代表x640x014c代表x86。對新手來說我建議直接用Dependencies看兩秒鐘就有結(jié)論。4.4 殺毒軟件攔截提取操作并不是誤報(bào)那么簡單提取dll時(shí)殺毒軟件突然彈窗檢測到可疑操作這種情況碰到過好幾次。有真正誤報(bào)的也有因?yàn)槟悴僮鞣绞讲灰?guī)范導(dǎo)致報(bào)警的。經(jīng)驗(yàn)是先把提取出來的dll放到單獨(dú)文件夾用Virustotal之類的在線掃描服務(wù)查一下哈希值看看實(shí)際檢出率。如果確認(rèn)文件來源可信可以在本地殺毒軟件里設(shè)置排除目錄再繼續(xù)。但我不建議為了提取一個(gè)dll把整個(gè)殺毒軟件關(guān)掉這是很多人的壞習(xí)慣中一次招就得不償失。另外提一句從內(nèi)存中抓取的dll文件其PE結(jié)構(gòu)經(jīng)過內(nèi)存對齊和磁盤對齊方式不一樣某些安全軟件會(huì)把它識(shí)別為格式異常。這在分析工作中很正常不代表文件有毒。5. 提取完之后的正確姿勢驗(yàn)證、分析和善后5.1 用Dependencies解讀你的dll底細(xì)提取dll只是開始你真正想干的事大概率在后面。這里我強(qiáng)烈建議你學(xué)一下Dependencies這個(gè)工具它比老牌工具Dependency Walker好用太多。用法很簡單把dll文件拖進(jìn)Dependencies窗口它會(huì)自動(dòng)解析PE頭列出以下關(guān)鍵信息架構(gòu)x86、x64、ARM64。導(dǎo)入表Imports當(dāng)前dll調(diào)用了哪些外部dll的哪些函數(shù)。導(dǎo)出表Exports當(dāng)前dll為其他程序提供了哪些函數(shù)。延遲加載導(dǎo)入表。依賴樹以圖形方式展開所有依賴項(xiàng)缺失項(xiàng)會(huì)高亮。導(dǎo)入表常被大家忽略但它是判斷這個(gè)dll適合在什么環(huán)境用的重要依據(jù)。比如一個(gè)dll導(dǎo)入了USER32.dll里的MessageBoxW說明它很可能有GUI交互導(dǎo)出表里如果包含某個(gè)特定前綴的函數(shù)名往往暗示它是某個(gè)插件的接口dll。5.2 驗(yàn)證數(shù)字簽名和文件信息不碰來路不明的文件提取完dll我建議你養(yǎng)成一個(gè)習(xí)慣先看數(shù)字簽名。右鍵dll→屬性→數(shù)字簽名如果顯示簽名無效或者無法驗(yàn)證簽名而原始文件是有簽名的那說明你提取的版本不對、被篡改過或者從內(nèi)存提取時(shí)破壞了簽名區(qū)。在涉密、安全敏感的項(xiàng)目里這種文件要直接棄用。再一個(gè)點(diǎn)是文件屬性里的原始文件名和文件版本。很多軟件自帶的dll版本號會(huì)寫在Version Info資源段里。你看一眼版本號就能判斷自己的提取對象是不是最新版。不同版本的dll之間可能存在函數(shù)集差異這在二次開發(fā)時(shí)是致命問題——你調(diào)用的導(dǎo)出函數(shù)在舊版dll里可能壓根不存在。善后工作也很重要。提取出來的dll和原始軟件之間可能存在授權(quán)綁定、聯(lián)網(wǎng)校驗(yàn)等機(jī)制。把dll單獨(dú)抽出來用于其他環(huán)境時(shí)如果出現(xiàn)意外彈窗或者功能失效不要第一時(shí)間懷疑提取沒提取好先思考這個(gè)軟件本身的保護(hù)機(jī)制。這一點(diǎn)尤其要在心里有數(shù)。6. 從一枚dll延伸出去你可以繼續(xù)學(xué)習(xí)什么dll提取只是入口順著這條路可以深挖的知識(shí)比你想象中多得多。我自己就是先學(xué)會(huì)提取dll后來一步步走到PE解析、函數(shù)調(diào)用Hook、資源修改這條路上的。至少有三個(gè)方向值得延伸PE文件格式花半天時(shí)間讀懂DOS頭、PE頭、節(jié)區(qū)表、導(dǎo)入表、導(dǎo)出表之后你再看到dll就不會(huì)只把它當(dāng)文件而是一套有結(jié)構(gòu)的數(shù)據(jù)。Windows進(jìn)程加載機(jī)制理解系統(tǒng)是怎么把dll映射進(jìn)進(jìn)程地址空間的LoadLibrary和靜態(tài)導(dǎo)入的區(qū)別在哪里為什么有些dll改個(gè)名字就加載失敗。導(dǎo)出函數(shù)分析用Dependencies查看導(dǎo)出表找出你想調(diào)用的函數(shù)配合官方文檔或者反匯編工具去理解它的行為這就是很多SDK逆向工作的起點(diǎn)。我個(gè)人在實(shí)際操作中最大的體會(huì)是很多人一上來就追求高級工具反而在基礎(chǔ)的文件復(fù)制、安裝包解壓、進(jìn)程管理上栽跟頭。其實(shí)dll提取這件事七八成場景靠的是耐心和細(xì)心——耐心找到目標(biāo)文件細(xì)心判斷它的位數(shù)、版本、依賴和占用狀態(tài)剩下兩三成才是工具技巧的比拼。最后再分享一個(gè)小技巧不管用哪一種方案提取dll我都建議在操作前建一個(gè)以軟件名版本號日期命名的文件夾把提取出的dll、對應(yīng)的依賴清單、提取方式說明放進(jìn)去。這個(gè)習(xí)慣看著不起眼但當(dāng)你需要回退版本、復(fù)現(xiàn)問題、給同事交接時(shí)它能幫你省下大把時(shí)間。我就是靠這個(gè)習(xí)慣在前幾年做系統(tǒng)遷移時(shí)幾乎零成本地恢復(fù)了十幾個(gè)老軟件的運(yùn)行環(huán)境沒有一次翻車。