如何利用Sanitizer解決Android中的Bug?

2021-02-15 谷歌開發者

AddressSanitizer (ASan) 是一項基於編譯器的儀器測試功能,可在運行時檢測 C/C++ 代碼中的多種內存錯誤。在 Android 中,已經測試了對下列內存錯誤類型的檢查功能:

Android 可通過 ASan 執行全面的構建儀器測試,還可以通過 asanwrapper 執行應用級的 ASan 儀器測試。關於這兩種儀器測試技巧的說明均可在 source.android.com 中找到。

AddressSanitizer 基於以下兩個高級概念。第一個概念是針對與內存有關的所有函數調用(包括 alloca、malloc 和 free 等)執行儀器測試並輸出用於跟蹤內存分配、釋放和使用情況統計的信息。通過此儀器測試,ASan 可檢測無效的內存使用錯誤,包括重複釋放、範圍後使用、返回後使用和釋放後使用等錯誤。ASan 還可以檢測在定義的內存區域邊界外發生的讀寫操作。為完成此檢測,它填充所有分配的內存緩衝區和變量。如果對此填充區域進行讀或寫,ASan 將捕獲此操作,並輸出有助於診斷內存違例的信息。在 ASan 術語中,此填充被稱為中毒內存。

下面是包含堆疊分配變量的中毒內存填充布局示例:

▲ ASANified 堆疊變量示例,此變量包含一個由 8 個元素組成的 int8_t 數組、一個 uint32_t 數組和一個由 16 個元素組成的 int8_t 數組。右側顯示使用 ASAN 編譯後的內存布局,其中每個變量之間插入填充。對於每個堆棧變量,變量前後有 32 個填充字節。如果一個變量的對象大小不是 32 個字節,則插入 32 - n 個額外的填充字節,其中 n 是對象大小。


ASan 使用影子內存跟蹤哪些字節為正常內存,哪些字節為中毒內存。字節可以標記為完全正常(在影子內存中標記為 0)、完全中毒(設置對應影子字節的高位)或前面 k 個字節未中毒(影子字節值為 k)。如果影子內存顯示某個字節中毒,則 ASan 會使程序崩潰,並輸出有用的調試信息,包括調用堆棧、影子內存映射、內存違例類型、讀取或寫入的內容、導致違例的計算機以及內存內容。

AddressSanitizer: heap-buffer-overflow on address 0xe6146cf3 at pc 0xe86eeb3c bp 0xffe67348 sp 0xffe66f14WRITE of size 39 at 0xe6146cf3 thread T0 #0 0xe86eeb3b (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) #1 0xaddc5d27 (/data/simple_test_fuzzer+0x4d27) #2 0xaddd08b9 (/data/simple_test_fuzzer+0xf8b9) #3 0xaddd0a97 (/data/simple_test_fuzzer+0xfa97) #4 0xaddd0fbb (/data/simple_test_fuzzer+0xffbb) #5 0xaddd109f (/data/simple_test_fuzzer+0x1009f) #6 0xaddcbfb9 (/data/simple_test_fuzzer+0xafb9) #7 0xaddc9ceb (/data/simple_test_fuzzer+0x8ceb) #8 0xe8655635 (/system/lib/libc.so+0x7a635)0xe6146cf3 is located 0 bytes to the right of 35-byte region [0xe6146cd0,0xe6146cf3)allocated by thread T0 here: #0 0xe87159df (/system/lib/libclang_rt.asan-arm-android.so+0x8b9df) #1 0xaddc5ca7 (/data/simple_test_fuzzer+0x4ca7) #2 0xaddd08b9 (/data/simple_test_fuzzer+0xf8b9)SUMMARY: AddressSanitizer: heap-buffer-overflow (/system/lib/libclang_rt.asan-arm-android.so+0x64b3b) Shadow bytes around the buggy address: 0x1cc28d40: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 0x1cc28d50: fa fa 00 00 00 00 07 fa fa fa fd fd fd fd fd fd 0x1cc28d60: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1cc28d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa=>0x1cc28d90: fa fa fa fa fa fa fa fa fa fa 00 00 00 00[03]fa 0x1cc28da0: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 03 fa 0x1cc28db0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa 0x1cc28dc0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28dd0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fd 0x1cc28de0: fa fa 00 00 00 00 00 02 fa fa fd fd fd fd fd fdShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb

有關報告各個部分的含義以及如何提高其易讀性的更多信息,可查看 LLVM 網站:

https://clang.llvm.org/docs/AddressSanitizer.html

和 Github:

https://github.com/google/sanitizers/wiki/AddressSanitizer


有時,錯誤發現過程可能無法確定問題所在,當錯誤需要特殊設置或更高級的技巧(例如堆填充或利用爭用條件)才能發現時,更是如此。其中許多錯誤並不能即時發現,可能需要檢查數千條指令才能找到內存違例的真正原因所在。ASan 可針對所有與內存有關的函數執行儀器測試並為必須觸發 ASan 相關回調才可訪問的區域填充數據,可在發生內存違例時立即捕獲違例,而不是等待崩潰導致數據損壞。這對於錯誤發現和根源診斷極為有用。此外,ASAN 還是一個非常有用的模糊測試工具,一直用於 Android 上的各種模糊測試工作。

相關焦點

  • 很少有人會告訴你的 Android 開發基本常識 移動開發
    學會提問:你身邊有很多資源,比如同事、StackOverflow、QQ 技術交流群、搜尋引擎,當你遇到問題的時候完全可以利用身邊的資源來解決遇到的問題,如果一個問題在一個小時之內自己都不能夠解決它,我就會通過搜尋引擎、Github、QQ 技術交流群、同事、StackOverflow(以上排序是按優先級排列的)來解決它。
  • Android Crash 案例解決方案
    非法狀態異常六、ArrayIndexOutOfBoundsException 數組越界異常七、SecurityException 安全異常八、llegalArgumentException: Service not registered 服務未註冊異常九、BadTokenException:Exception 在Android 中經常會遇到,那麼遇到異常我們該如何解決
  • Android Jetpack CameraX 庫 Beta 版正式發布!
    這次的版本將為開發者呈現一個基礎的相機API,未來會一如既往地提供與兼容性有關或其他bug的修復程序和解決方法,助力您在多臺設備上打造一致的開發者體驗。除了在自動化測試農場擴大測試範圍,有很多應用也在生產環境中使用了CameraX庫,這使得我們有信心向各位開發者推薦CameraX,推薦大家開始嘗試並將基於CameraX的應用發布到應用商店。
  • 在 Android 開發中使用協程 | 代碼實戰
    如果伺服器後來又修改了這篇文章的內容,新的更改是不會顯示在瀏覽器中的,除非您主動刷新了瀏覽器頁面。儘管這樣的方式缺少了流式請求那樣的實時推送特性,但是它還是非常有用的。在 Android 的應用中您可以用這種方式解決很多問題,比如對數據的查詢、存儲或更新,它還很適用於處理列表排序問題。我們通過一個展示有序列表的例子來探索一下如何構建一次性請求。
  • Android 多主題之坑
    解決的方法:在view的drawstateChanged()中手動調用invalidate方法。在view的drawstateChanged()中apply新的drawable state。等待你來補充。關於.9png.9png在繪製時如果.9png內含有padding值,則5.0以下時view的padding會消失。
  • Android基礎 - 如何做魯棒性更高的布局
    因為其跟我們日常所理解的畫布類似,我們想將哪個部件放在畫布的哪個位置都是非常自由的,但事實上,從結構的完整性上講,RelativeLayout並不是真正適合作為布局主體進行布局構建方式,雖然看似其十分好用,但實際上當我們將作為底子的畫布變換一個方向和大小,可能就沒那麼方便了:使用RelativeLayout構建的布局.png這可能會直接導致界面混亂,以至於出現「換了個手機就不能用了」的尷尬情況,那麼如何避免此類問題呢
  • Android中的窗口——Activity
    雖然在不同的電腦上都安裝和配置了JDK,但在Eclipse中為JDK起的名字可能不同。在Eclipse中配置的JDK可以在「Preferences」對話框中的「Java」 > 「Installed JREs」節點對應的右側列表中找到。如果發現和Android工程原來所有的Eclipse中的JDK名字不同,可以在這裡修改一下。• 引用的jar文件在目標機器上不存在。
  • 賽博朋克2077bug及解決方法匯總-賽博朋克2077問題bug匯總及解決方法
    賽博朋克2077bug是有很多的,不少玩家都想知道該如何解決這些問題或者是bug,今天就為大家帶來關於這個方面的具體攻略,通過下面的文章內容,就讓我們來一起了解一下吧,希望能幫到有需要的玩家群體。
  • 【Android基礎學習一】Android 常用 adb 命令總結
    , 列印dumpsys、dumpstate、logcat的輸出,也是用於分析錯誤輸出比較多,建議重定向到一個文件中adb bugreport > d:\bugreport.logadb install , 安裝應用,覆蓋安裝是使用 -r 選項windows 下如果需要安裝含有中文名的 apk ,需要對 adb 進行修改,百度可以找到做出修改的
  • Win10 1903新BUG如何解決?又有哪些特性?
    神奇的是,每個用戶獲得的體驗居然還各不相同,由於這個老張遇到的bug過分愚蠢,今天被逼的不得不對Win10 1903批判一番,究竟發生何事、請容我慢慢道來。▌校色文件無法載入首先要說的這個問題目前已經找到臨時解決辦法了。
  • Android應用耗電量分析與優化建議
    bugreport文件上傳至頁面,在網頁中生成詳細的圖表數據來展示手機上各模塊電量消耗過程,最後通過App數據的分析制定出相關的電量優化的方法。可參考:https://github.com/google/battery-historianApp電量消耗分析工具安裝成功後我們需要從手機上導出數據進行分析# 將bugreport的信息保存到.zip文件中$ adb bugreport bugreport.zipAndroid 6.0以下系統請使用以下導出命令# 將bugreport
  • 34個Android常用adbshell命令匯總
    adb一般位於/platform-tools/目錄下,其中是android sdk的安裝目錄。可以把adb路徑添加進系統環境變量path裡面,例:D:\sdk\platform-tools;這樣就能在打開powershell時就能響應adb命令,不用每次都進入adb目錄。
  • 一個 2 年 Android 開發者的 18 條忠告
    如果在開發app的時候遇到一個問題,而這個問題已經被別人很好的解決了,為什麼不使用它呢?你可以節省大量時間啊。把更多的精力花在app的業務邏輯上吧。如果你想在app中發起一個網絡調用,是不需要自己去造一個Retrofit(注3)來的。福利:Android Arsenal(注4)網站維護了一個幾乎包含所有Android library的資料庫,可以去看看。
  • Android中如何實現圖文混排
    ss.setSpan(span, 18, 19, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); txtInfo.setText(ss);txtInfo.setMovementMethod(LinkMovementMethod.getInstance()); //實現文本的滾動 通常用於顯示文字,但有時候也需要在文字中夾雜一些圖片
  • 《模擬人生4》綠色生活bug解決方法介紹 綠色生活bug怎麼解決
    模擬人生4綠色生活bug怎麼解決?在更新後,有些玩家遇到了主控不受控制做蛋糕/玩泥巴的bug,這裡給大家帶來了模擬人生4綠色生活bug解決方法介紹,一起來看下吧。 模擬人生4綠色生活bug怎麼解決?
  • Android測試 常用adb 命令總結
    kill-server , adb start-server , 結束 adb 服務, 啟動 adb 服務,通常兩個命令一起用一般在連接出現異常,使用 adb devices 未正常列出設備, 設備狀態異常時使用 kill-server,然後運行 start-server 進行重啟服務adb logcat , 列印 Android 的系統日誌,這個可以單獨拿出來講adb bugreport
  • 如何遠程控制Android手機,為所欲為?
    今天我們介紹一下MDM,看了下邊的介紹你就知道如何控制自己的設備了,首先介紹一下MDM是什麼的縮寫,MDM是什麼?
  • Android代碼混淆使用手冊
    -keep public class * extends android.view.View{    *** get*();    void set*(***);    public (android.content.Context);    public (android.content.Context, android.util.AttributeSet);
  • Android上玩玩Hook:Cydia Substrate實戰
    我們也知道,在Android系統中使用了沙箱機制,普通用戶程序的進程空間都是獨立的,程序的運行彼此間都不受幹擾。這就使我們希望通過一個程序改變其他程序的某些行為的想法不能直接實現,但是Hook的出現給我們開拓了解決此類問題的道路。當然,根據Hook對象與Hook後處理的事件方式不同,Hook還分為不同的種類,如消息Hook、API Hook等。
  • android 狀態欄梳理
    狀態欄透明其實在實際操作中,使用狀態欄透明的操作不多,而且都不是為了讓狀態欄去透明,而是奔著狀態欄在透明時會失去位置這個特性來,比如讓圖片延伸至標題欄這裡我們可以選擇 theme 或是代碼的方式,但是 theme