試與 LoadLibraryA 早期加載實(shí)戰(zhàn))
應(yīng)用安全測(cè)試漏洞掃描【免費(fèi)下載鏈接】AFLplusplusAFL is a state-of-the-art fuzzer, and #1 in benchmarks. It was originally based on AFL. Today it comes with qemu 5.1, collision-free coverage, enhanced laf-intel redqueen, AFLfast power schedules, MOpt mutators, unicorn_mode, and a lot more!項(xiàng)目地址https://gitcode.com/gh_mirrors/af/AFLplusplus點(diǎn)擊查看免費(fèi)下載本指南聚焦于 AFL QEMU 模式下 Wine 子模式-W的兩類核心問題如何通過WINEDEBUG環(huán)境變量開啟 Wine 自身的調(diào)試輸出以及如何解決 fork 后LoadLibrary動(dòng)態(tài)加載失敗錯(cuò)誤碼 87的問題。讀完本文你將掌握 Wine 模式的基本運(yùn)行機(jī)制、調(diào)試通道的選擇方法以及通過修改 PE 導(dǎo)入表或鏈接.lib靜態(tài)導(dǎo)入兩種方式實(shí)現(xiàn)“早期 DLL 加載”的完整實(shí)操方案。1. 背景AFL 的 Wine 模式是什么AFL 的 QEMU 模式可以通過 Wine 運(yùn)行 Win32 PE 二進(jìn)制并進(jìn)行插樁模糊測(cè)試這一能力被稱作 Wine 模式Wine mode。在 qemu_mode/README.md 中Wine 模式被描述為“QEMU mode can use Wine to fuzz Win32 PE binaries via the-Wflag of afl-fuzz”也就是說只需在啟動(dòng)afl-fuzz時(shí)附加-W選項(xiàng)即可啟用。Wine 模式在整個(gè) AFL 中屬于“binary-only 目標(biāo)模糊測(cè)試”家族的成員docs/fuzzing_binary-only_targets.md 明確指出Wine 模式用 QEMU 插樁運(yùn)行 Win32 PE 二進(jìn)制運(yùn)行前提是系統(tǒng)安裝了Wine、Python 3 以及 Python 的 pefile 包docs/features.md 亦將其列為“Win32 PE binary-only fuzzing with QEMU and Wine”特性docs/Changelog.md 記載了 Wine 模式隨 QEMU 插樁引入的歷史。需要特別說明的是Wine 模式下被模糊測(cè)試的程序仍運(yùn)行在 QEMU 用戶態(tài)模擬之中因此它天然繼承了 QEMU 模式的性能特征通常比編譯期插樁慢 25 倍參見 docs/fuzzing_binary-only_targets.md。此外部分目標(biāo)程序需要 GUI 交互這類程序必須經(jīng)過補(bǔ)丁改造才能用于無頭模糊測(cè)試。而 Wine 模式自身還有兩個(gè)特有的坑調(diào)試輸出難以閱讀、以及LoadLibrary在 fork 后加載失敗——這正是本指南要解決的內(nèi)容。2. 開啟 Wine 調(diào)試WINEDEBUG 環(huán)境變量Wine 自帶一套靈活的調(diào)試基礎(chǔ)設(shè)施。默認(rèn)情況下 Wine 的調(diào)試輸出較為沉默一旦目標(biāo)程序在 Wine 中行為異常第一件要做的事就是打開調(diào)試通道。AFL 的官方做法非常簡(jiǎn)單設(shè)置WINEDEBUG環(huán)境變量。WINEDEBUGtimestamp,tid,loaddll ./afl-fuzz -W -i seeds -o out -- ./target.exe 示例中的timestamp、tid、loaddll分別是三個(gè) Wine 調(diào)試通道debug channel的開關(guān)timestamp為每條調(diào)試消息附加時(shí)間戳便于定位調(diào)用時(shí)序tid附加線程 ID便于區(qū)分多線程下的消息來源loaddll輸出 DLL 加載/卸載事件這是排查“庫加載失敗”類問題時(shí)的核心通道。WINEDEBUG的語法基于通道channel列表表示開啟某個(gè)通道-表示關(guān)閉以逗號(hào)分隔。需要診斷 PE 加載細(xì)節(jié)時(shí)還可疊加module、relay等通道而在調(diào)試完成后務(wù)必清空該變量或使用-all關(guān)閉全部輸出避免海量日志拖慢模糊測(cè)試循環(huán)。3. LoadLibraryA 工作區(qū)fork 后加載失敗錯(cuò)誤碼 873.1 問題現(xiàn)象Wine 模式基于 fork 服務(wù)器forkserver架構(gòu)QEMU 啟動(dòng)目標(biāo)進(jìn)程后在入口點(diǎn)附近掛起并等待afl-fuzz的 fork 指令每個(gè)測(cè)試用例在 fork 出的子進(jìn)程中執(zhí)行。關(guān)鍵限制在于如果在入口點(diǎn)entry point之后、fork 發(fā)生之前程序通過LoadLibrary/LoadLibraryA動(dòng)態(tài)加載了外部 DLLfork 出的子進(jìn)程將無法正確加載這些庫Windows API 會(huì)返回錯(cuò)誤碼 87。錯(cuò)誤碼 87 在 Windows 語義中對(duì)應(yīng)ERROR_INVALID_PARAMETER即“參數(shù)無效”。從 Wine 模式的實(shí)際運(yùn)行看這一錯(cuò)誤并非參數(shù)本身的問題而是 fork 語義與 Wine 內(nèi)部加載狀態(tài)之間的不一致導(dǎo)致的加載失敗。官方文檔給出的結(jié)論非常明確The forked process fails to load libraries loaded viaLoadLibraryif the load happens after the entry point (error code: 87).即凡是需要在模糊測(cè)試循環(huán)中使用的庫都必須在 fork 發(fā)生之前完成加載。3.2 解決思路既然“在入口點(diǎn)之后用LoadLibrary動(dòng)態(tài)加載”不可靠那么解決方案就是把外部庫的加載時(shí)機(jī)提前到入口點(diǎn)之前讓庫隨 PE 文件本身一起在進(jìn)程早期就緒。AFL 官方文檔提供了兩種互為補(bǔ)充的手段直接修改 PE 文件的 Import Directory導(dǎo)入表讓 DLL 作為靜態(tài)導(dǎo)入在進(jìn)程啟動(dòng)時(shí)被加載從 DLL 導(dǎo)出表生成.lib導(dǎo)入庫并與 harness 鏈接讓鏈接器在生成 PE 時(shí)自動(dòng)寫入導(dǎo)入表?xiàng)l目。兩種手段的最終目標(biāo)一致在 PE 映像里留下導(dǎo)入記錄使系統(tǒng)在程序最早啟動(dòng)階段早于我們的入口點(diǎn)與 fork完成 DLL 的映射與初始化。4. 方案一直接編輯 PE 導(dǎo)入表這是最直接的手段。任何 PE 編輯器如 CFF Explorer、LordPE 等都可以打開目標(biāo) PE 文件在Import Directory中加入目標(biāo) DLL 的名稱條目。經(jīng)過修改后PE 加載器在進(jìn)程啟動(dòng)時(shí)會(huì)立刻加載該 DLL從而繞開 fork 后LoadLibrary失敗的路徑。操作要點(diǎn)在編輯前保留原始 PE 備份確認(rèn) DLL 與其依賴項(xiàng)都可被 Wine 找到可結(jié)合 2.1 節(jié)的loaddll通道驗(yàn)證加載序列修改后建議先用 Wine 單獨(dú)運(yùn)行一次確認(rèn)無導(dǎo)入表解析錯(cuò)誤常見于導(dǎo)入序號(hào)與名稱不匹配。該方案的優(yōu)勢(shì)是零編譯依賴適合對(duì)閉源、無源碼的 PE 目標(biāo)做快速修復(fù)劣勢(shì)是每次 PE 更新都需要重新打補(bǔ)丁且手工編輯導(dǎo)入表對(duì)操作者的 PE 結(jié)構(gòu)知識(shí)有一定要求。4. 方案二dumpbin lib 生成導(dǎo)入庫并鏈接如果目標(biāo)程序有對(duì)應(yīng)的 harness 源碼例如用 C 語言編寫的一個(gè)薄封裝把 PE 目標(biāo)當(dāng)作被測(cè)函數(shù)調(diào)用則可以用官方推薦的“從導(dǎo)出表生成導(dǎo)入庫”的鏈路讓鏈接器自動(dòng)完成早期加載。完整步驟如下Step 1導(dǎo)出 DLL 的導(dǎo)出表dumpbin /exports filename.dlldumpbin是 MSVC 工具鏈自帶的 PE 轉(zhuǎn)儲(chǔ)工具。它會(huì)列出 DLL 導(dǎo)出的全部函數(shù)名及其序號(hào)。Step 2將導(dǎo)出函數(shù)名寫入.def文件將上一步輸出的導(dǎo)出函數(shù)名逐一粘貼進(jìn)一個(gè)模塊定義文件.def。典型的.def內(nèi)容形如LIBRARY filename EXPORTS FuncA FuncB FuncCStep 3用 lib 工具生成導(dǎo)入庫lib /def:deffile /OUT:libfilelib會(huì)根據(jù).def文件生成一個(gè).lib導(dǎo)入庫文件。Step 4把導(dǎo)入庫加入鏈接器選項(xiàng)將生成的.lib加入 harness 的鏈接命令行或工程配置中。Step 5在 harness 源碼中引用其導(dǎo)出符號(hào)在 harness 中對(duì)目標(biāo) DLL 的導(dǎo)出函數(shù)使用__declspec(dllimport)聲明例如__declspec(dllimport) int FuncA(void);一旦鏈接器在 harness 的目標(biāo)文件中檢測(cè)到對(duì)dllimport符號(hào)的引用它就會(huì)把對(duì)應(yīng) DLL 寫入生成 PE 的 Import Directory從而觸發(fā)早期 DLL 加載。正如文檔所強(qiáng)調(diào)的Once the usage of an export is detected (__declspec(dllimport)), the linker adds the early DLL load.相比方案一該方案由鏈接器自動(dòng)維護(hù)導(dǎo)入表DLL 更新后只需重新鏈接 harness更適合有源碼、需要長(zhǎng)期迭代的模糊測(cè)試工程。5. 源碼級(jí)佐證-W參數(shù)與 afl-wine-trace 的調(diào)用鏈理解了問題與解法后再回到源碼層面看 Wine 模式是如何串起來的這能幫你更快定位“我的環(huán)境為什么沒生效”。-W參數(shù)解析afl-fuzz在 src/afl-fuzz.c 中解析-W并置位afl-use_wine隨后在 src/afl-fuzz.c 調(diào)用get_wine_argv()重寫目標(biāo)命令行。同樣的-W邏輯也存在于 src/afl-showmap.c、src/afl-cmin.c 與 src/afl-tmin.c即覆蓋率查看、語料精簡(jiǎn)與最小化工具也復(fù)用同一套 Wine 啟動(dòng)邏輯。argv 重寫get_wine_argv()定義于 src/afl-common.c。它把目標(biāo)二進(jìn)制解析出的路徑放到new_argv[1]并把a(bǔ)rgv[0]替換為afl-wine-trace的路徑通過find_afl_binary查找從而讓真正的“執(zhí)行者”變成 Wine 模式的包裝腳本。afl-wine-trace 腳本倉庫根目錄的 afl-wine-trace 是 Wine 模式的核心包裝器它做的事與本指南的兩大主題直接相關(guān)使用pefile解析 PE 頭若未顯式設(shè)置則自動(dòng)把AFL_ENTRYPOINT設(shè)為ImageBase AddressOfEntryPoint把AFL_CODE_START/AFL_CODE_END設(shè)為代碼段BaseOfCode起止——這意味著默認(rèn)插樁范圍就是目標(biāo) PE 自身的代碼段與 Wine 系統(tǒng) DLL 分離根據(jù) PE 的Machine字段AMD64/IA64 走 64 位I386 走 32 位選擇預(yù)加載qemu_mode/unsigaction/unsigaction64.so或unsigaction32.so并通過QEMU_SET_ENV一并注入WINEARCHwin64或WINEARCHwin32。unsigaction子模塊正是為 Wine 模式準(zhǔn)備的qemu_mode/unsigaction/README.md 明言它“Mainly needed by Wine mode but can be used as a separate tool”解析 QEMU 路徑優(yōu)先WINECOV_QEMU_PATH其次afl-qemu-trace最后回退到系統(tǒng)qemu-x86_64/qemu-i386與 Wine 路徑優(yōu)先AFL_WINE_PATH其次PATH中的wine、/usr/bin/wine、/usr/lib/wine/wine對(duì)參數(shù)中含.cur_input的路徑調(diào)用winepath --windows將其轉(zhuǎn)換為 Windows 風(fēng)格路徑后替換回 argv最后以os.execve(qemu, [qemu, wine] argv)啟動(dòng) QEMU→Wine→目標(biāo)程序 的完整鏈路。理解這條鏈路對(duì)排障很有幫助如果loaddll日志顯示 DLL 加載時(shí)序異??梢韵却_認(rèn)AFL_ENTRYPOINT是否被腳本正確設(shè)為 PE 入口點(diǎn)如果 Wine 環(huán)境不對(duì)則應(yīng)檢查AFL_WINE_PATH與WINEARCH的取值是否符合目標(biāo) PE 的位數(shù)。6. 排障速查從現(xiàn)象到對(duì)策現(xiàn)象排查手段對(duì)策Wine 內(nèi)部行為不透明、無法定位崩潰點(diǎn)設(shè)置WINEDEBUGtimestamp,tid,loaddll可疊加module、relay分析加載時(shí)序聚焦崩潰前的最后一條加載/調(diào)用記錄fork 子進(jìn)程調(diào)用LoadLibrary返回 87用loaddll確認(rèn)加載發(fā)生在入口點(diǎn)之后將 DLL 加入 PE Import Directory或用 dumpbin/lib 生成導(dǎo)入庫提前鏈接PE 位數(shù)與 Wine 架構(gòu)不匹配查看 afl-wine-trace 打印的 exec 命令與WINEARCH確保 32 位 PE 對(duì)應(yīng) win32、64 位 PE 對(duì)應(yīng) win64必要時(shí)用AFL_WINE_PATH指定 Wine 路徑插樁范圍異常誤插樁系統(tǒng) DLL檢查AFL_CODE_START/AFL_CODE_END取值默認(rèn)腳本已按 PE 代碼段自動(dòng)設(shè)置如需插樁庫代碼再考慮AFL_INST_LIBS17. 小結(jié)AFL 的 Wine 模式讓“無源碼 Win32 PE 目標(biāo)”也能接入 QEMU 插樁模糊測(cè)試但 fork 服務(wù)器架構(gòu)與 Wine 動(dòng)態(tài)加載語義之間存在天然沖突。本文梳理的WINEDEBUG調(diào)試通道與兩種“早期 DLL 加載”方案PE 導(dǎo)入表直改、.def/.lib鏈接正是解決這一沖突的標(biāo)準(zhǔn)路徑結(jié)合 afl-wine-trace 與 src/afl-common.c 的調(diào)用鏈你可以快速定位 Wine 架構(gòu)、插樁范圍與加載時(shí)序三類常見問題。相關(guān)背景與其余 QEMU 模式能力可繼續(xù)參閱 qemu_mode/README.md 與 docs/fuzzing_binary-only_targets.md。贊分享應(yīng)用安全測(cè)試漏洞掃描【免費(fèi)下載鏈接】AFLplusplusAFL is a state-of-the-art fuzzer, and #1 in benchmarks. It was originally based on AFL. Today it comes with qemu 5.1, collision-free coverage, enhanced laf-intel redqueen, AFLfast power schedules, MOpt mutators, unicorn_mode, and a lot more!項(xiàng)目地址https://gitcode.com/gh_mirrors/af/AFLplusplus點(diǎn)擊查看免費(fèi)下載相關(guān)推薦AFL FRIDA 模式故障排查與調(diào)試完全指南從環(huán)境變量診斷到 gdb 持久模式調(diào)優(yōu)AFL FRIDA 模式故障排查與調(diào)試完全指南從環(huán)境變量診斷到 gdb 持久模式調(diào)優(yōu) 導(dǎo)讀 本文以 AFL 倉庫中 frida_mode/DEBUGG應(yīng)用安全測(cè)試漏洞掃描AFL 常見問題FAQ權(quán)威指南灰盒模糊測(cè)試原理、性能調(diào)優(yōu)與故障排查實(shí)戰(zhàn)AFL 常見問題FAQ權(quán)威指南灰盒模糊測(cè)試原理、性能調(diào)優(yōu)與故障排查實(shí)戰(zhàn) 導(dǎo)讀 本文以 AFL 官方 FAQ docs/FAQ.md https應(yīng)用安全測(cè)試漏洞掃描ComfyUI-Florence2模型加載故障排查與修復(fù)指南ComfyUI Florence2模型加載故障排查與修復(fù)指南 當(dāng)你在ComfyUI中嘗試使用Florence2視覺語言模型時(shí)可能會(huì)遇到一個(gè)令人困惑的問題Fl人工智能大模型計(jì)算機(jī)視覺多模態(tài)本地部署AI 應(yīng)用上一篇GraalWasm 解釋器基準(zhǔn)套件WAT 基準(zhǔn)文件的生成、復(fù)現(xiàn)與運(yùn)行指南下一篇如何用dreamtime集成LUIS實(shí)現(xiàn)智能意圖識(shí)別完整入門教程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考