- Go語言精進之路:從新手到高手的編程思想、方法和技巧(2)
- 白明
- 924字
- 2022-01-04 17:42:24
45.2 go-fuzz的初步工作原理
go-fuzz實際上是基于前面提到的老牌模糊測試項目afl-fuzz的邏輯設計和實現的。不同的是在使用的時候,afl-fuzz對于每個輸入用例(input case)都會創建(fork)一個進程(process)去執行,而go-fuzz則是將輸入用例中的數據傳給下面這樣一個Fuzz函數,這樣就無須反復重啟程序。
func Fuzz(data []byte) int
go-fuzz進一步完善了Go開發測試工具集,很多較早接受Go語言的公司(如Cloudflare等)已經開始使用go-fuzz來測試自己的產品以提高產品質量了。
go-fuzz的工作流程如下:
1)生成隨機數據;
2)將上述數據作為輸入傳遞給被測程序;
3)觀察是否有崩潰記錄(crash),如果發現崩潰記錄,則說明找到了潛在的bug。
之后開發者可以根據crash記錄情況去確認和修復bug。修復bug后,我們一般會為被測代碼添加針對這個bug的單元測試用例以驗證bug已經修復。
go-fuzz采用的是代碼覆蓋率引導的fuzzing算法(Coverage-guided fuzzing)。go-fuzz運行起來后將進入一個死循環,該循環中的邏輯的偽代碼大致如下:
// go-fuzz-build在構建用于go-fuzz的二進制文件(*.zip)的過程中 // 在被測對象代碼中埋入用于統計代碼覆蓋率的樁代碼及其他信息 Instrument program for code coverage Collect initial corpus of inputs // 收集初始輸入數據語料(位于工作路徑下的corpus目錄下) for { // 從corpus中讀取語料并做隨機變化 Randomly mutate an input from the corpus // 執行Fuzz,收集代碼覆蓋率數據 Execute and collect coverage // 如果輸入數據提供了新的代碼覆蓋率,則將該輸入數據存入語料庫(corpus) If the input gives new coverage, add it to corpus }
go-fuzz的核心是對語料庫的輸入數據如何進行變化。go-fuzz內部使用兩種對語料庫的輸入數據進行變化的方法:突變(mutation)和改寫(versify)。突變是一種低級方法,主要是對語料庫的字節進行小修改。下面是一些常見的突變策略:
- 插入/刪除/重復/復制隨機范圍的隨機字節;
- 位翻轉;
- 交換2字節;
- 將一個字節設置為隨機值;
- 從一個byte/uint16/uint32/uint64中添加/減去;
- 將一個byte/uint16/uint32替換為另一個值;
- 將一個ASCII數字替換為另一個數字;
- 拼接另一個輸入;
- 插入其他輸入的一部分;
- 插入字符串/整數字面值;
- 替換為字符串/整數字面值。
例如,下面是對輸入語料采用突變方法的輸入數據演進序列:
"" "", "A" "", "A", "AB" "", "A", "AB", "ABC" "", "A", "AB", "ABC", "ABCD"
改寫是比較先進的高級方法,它會學習文本的結構,對輸入進行簡單分析,識別出輸入語料數據中各個部分的類型,比如數字、字母數字、列表、引用等,然后針對不同部分運用突變策略。 下面是應用改寫方法進行語料處理的例子:
原始語料輸入:
`<item name="foo"><prop name="price">100</prop></item>`
運用改寫方法后的輸入數據例子:
<item name="rb54ana"><item name="foo"><prop name="price"></prop><prop/></item> </item> <item name=""><prop name="price">=</prop><prop/> </item> <item name=""><prop F="">-026023767521520230564132665e0333302100</prop><prop/> </item> <item SN="foo_P"><prop name="_G_nx">510</prop><prop name="vC">-9e-07036514 </prop></item> <item name="foo"><prop name="c8">prop name="p"</prop>/}<prop name=" price">01e-6 </prop></item> <item name="foo"><item name="foo"><prop JY="">100</prop></item>8<prop/></item>
- 微信公眾平臺與小程序開發:從零搭建整套系統
- Learn Type:Driven Development
- 快速念咒:MySQL入門指南與進階實戰
- Nginx實戰:基于Lua語言的配置、開發與架構詳解
- Linux C編程:一站式學習
- Mastering openFrameworks:Creative Coding Demystified
- 零基礎學C語言(升級版)
- 寫給青少年的人工智能(Python版·微課視頻版)
- 關系數據庫與SQL Server 2012(第3版)
- Oracle SOA Suite 12c Administrator's Guide
- 前端架構設計
- Java核心技術速學版(第3版)
- HTML 5與CSS 3權威指南(第4版·下冊)
- OpenCL異構并行計算:原理、機制與優化實踐
- Procedural Content Generation for Unity Game Development