一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于編譯器用于快速檢測(cè)原生代碼中內(nèi)存錯(cuò)誤的ASan

電子工程師 ? 來(lái)源:哆啦安全 ? 作者:哆啦安全 ? 2022-07-29 16:04 ? 次閱讀

什么是 ASan

ASan 是Address Sanitizer簡(jiǎn)稱(chēng),它是是一種基于編譯器用于快速檢測(cè)原生代碼中內(nèi)存錯(cuò)誤的工具。

簡(jiǎn)而言之,ASan 就是一個(gè)用于快速檢測(cè)內(nèi)存錯(cuò)誤的工具。這里很多朋友有誤解,ASan 其實(shí)并不能用于內(nèi)存泄漏檢測(cè),Android 平臺(tái)內(nèi)存泄漏檢測(cè)推薦 MallocDebug。

另外需要注意的是Android O(API >= 27)及以上版本才支持 ASan ,NDK 需要選用 r20 及以上版本。

ASan 可以檢測(cè)到內(nèi)存錯(cuò)誤類(lèi)型如下:

Stack and heap buffer overflow/underflow 棧和堆緩沖區(qū)上溢/下溢;

Heap use after free 堆內(nèi)存被釋放之后還在使用其指針;

Stack use outside scope 在某個(gè)局部變量的作用域之外,使用其指針;

Double free/wild free 指針重復(fù)釋放的情況。

ASan 支持 arm 和 x86 平臺(tái),使用 ASan 時(shí),APP 性能會(huì)變慢且內(nèi)存占用會(huì)飆升。針對(duì) arm64 平臺(tái),Android 官方推薦使用 HWAddress Sanitizer (HWASan),后面會(huì)介紹。

關(guān)于 ASan 的原理本文不做深入討論,該文章的主要目的是幫助開(kāi)發(fā)者快速上手 ASan 的使用。

這里感性地介紹下 ASan 的工作原理ASan 相當(dāng)于接管了內(nèi)存的分配,當(dāng)分配一塊內(nèi)存時(shí),會(huì)在這塊內(nèi)存的前后添加"標(biāo)志位",然后再次使用該內(nèi)存的時(shí)候檢查"標(biāo)志位"是否被修改,當(dāng)發(fā)現(xiàn)"標(biāo)志位"被修改時(shí),判斷出現(xiàn)內(nèi)存錯(cuò)誤。

怎么使用 ASan

之所以寫(xiě)這篇文件,就是因?yàn)榘l(fā)現(xiàn)一些文章介紹 ASan 使用方法搞得非常復(fù)雜,不易上手。

其實(shí) Android 官方的使用說(shuō)明非常簡(jiǎn)潔,就是復(fù)制黏貼,添加兩行代碼就搞定。

官方文檔:https://developer.android.com/ndk/guides/asan

修改編譯腳本

CMake 方式

APP 下面的 build.gradle 添加:

android{
defaultConfig{
externalNativeBuild{
cmake{
#CanalsousesystemornoneasANDROID_STL.
arguments"-DANDROID_ARM_MODE=arm","-DANDROID_STL=c++_shared"
}
}
}
}

CMakeLists.txt 腳本添加:

target_compile_options(${libname}PUBLIC-fsanitize=address-fno-omit-frame-pointer)
set_target_properties(${libname}PROPERTIESLINK_FLAGS-fsanitize=address)

Ndk-Build 方式

Application.mk 文件添加:

APP_STL:=c++_shared#Orsystem,ornone.
APP_CFLAGS:=-fsanitize=address-fno-omit-frame-pointer
APP_LDFLAGS:=-fsanitize=address

Android.mk 文件添加:

APP_STL:=c++_shared#Orsystem,ornone.
APP_CFLAGS:=-fsanitize=address-fno-omit-frame-pointer
APP_LDFLAGS:=-fsanitize=address

拷貝 Asan 庫(kù)到 jniLibs 目錄下

Asan 庫(kù)位于下面路徑下:

android-ndk-r21toolchainsllvmprebuiltwindows-x86_64lib64clang9.0.8liblinux

64 位 libclang_rt.asan-aarch64-android.so , 32 位 libclang_rt.asan-arm-android.so ,分別拷貝兩個(gè)庫(kù)到 jniLibs 相應(yīng)的目錄下。

新建 wrap.sh 文件,拷貝下面內(nèi)容到文件中:

#!/system/bin/sh
HERE="$(cd"$(dirname"$0")"&&pwd)"
exportASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
ASAN_LIB=$(ls$HERE/libclang_rt.asan-*-android.so)
if[-f"$HERE/libc++_shared.so"];then
#Workaroundforhttps://github.com/android-ndk/ndk/issues/988.
exportLD_PRELOAD="$ASAN_LIB$HERE/libc++_shared.so"
else
exportLD_PRELOAD="$ASAN_LIB"
fi
"$@"

在 main 文件夾下新建目錄 resourceslib 然后將 wrap.sh 文件拷貝到相應(yīng)的目錄下面,最終的目錄結(jié)構(gòu)是這樣的:


└──app
└──src
└──main
├──jniLibs
│├──arm64-v8a
││└──libclang_rt.asan-aarch64-android.so
│├──armeabi-v7a
││└──libclang_rt.asan-arm-android.so
│├──x86
││└──libclang_rt.asan-i686-android.so
│└──x86_64
│└──libclang_rt.asan-x86_64-android.so
└──resources
└──lib
├──arm64-v8a
│└──wrap.sh
├──armeabi-v7a
│└──wrap.sh
├──x86
│└──wrap.sh
└──x86_64
└──wrap.sh

自此 ASan 接入完成,是不是很簡(jiǎn)單?

ASan 檢測(cè)內(nèi)存錯(cuò)誤

這一節(jié)我們?cè)诖a中故意設(shè)置一些常見(jiàn)的內(nèi)存錯(cuò)誤(內(nèi)存越界等)用來(lái)測(cè)試 ASan 檢測(cè)出來(lái)的結(jié)果是否正確。

需要注意的是,當(dāng) ASan 檢測(cè)出內(nèi)存錯(cuò)誤,程序就會(huì)立即 crash ,不再往下執(zhí)行,log 中會(huì)出現(xiàn)關(guān)鍵字 AddressSanitizer。

堆內(nèi)存溢出

staticvoidHeapBufferOverflow(){
int*arr=newint[1024];
arr[0]=11;
arr[1024]=12;
LOGCATE("HeapBufferOverflowarr[0]=%d,arr[1024]",arr[0],arr[1024]);
}

ASan 檢測(cè)結(jié)果(crash log)中出現(xiàn)關(guān)鍵字 heap-buffer-overflow :

05-1319:52:16.24741944194Icom.byteflow.learnffmpeg:=================================================================
05-1319:52:16.24741944194Icom.byteflow.learnffmpeg:==4194==ERROR:AddressSanitizer:heap-buffer-overflowonaddress0x004f0d5a8100atpc0x0074f822b648bp0x007ff0227a00sp0x007ff02279f8
05-1319:52:16.24741944194Icom.byteflow.learnffmpeg:WRITEofsize4at0x004f0d5a8100threadT0
05-1319:52:16.2572333423334DLauncher_UnlockAnimationStateMachine:mResetIdleStateRunnable
05-1319:52:16.26541944194Icom.byteflow.learnffmpeg:#00x74f822b644(/data/app/com.byteflow.learnffmpeg-mVg7CcQSTXVnJhfo7u0XLA==/lib/arm64/liblearn-ffmpeg.so+0x146644)
05-1319:52:16.26541944194Icom.byteflow.learnffmpeg:#10x74f8229b20(/data/app/com.byteflow.learnffmpeg-mVg7CcQSTXVnJhfo7u0XLA==/lib/arm64/liblearn-ffmpeg.so+0x144b20)
05-1319:52:16.26541944194Icom.byteflow.learnffmpeg:#20x74f8229a7c(/data/app/com.byteflow.learnffmpeg-mVg7CcQSTXVnJhfo7u0XLA==/lib/arm64/liblearn-ffmpeg.so+0x144a7c)
05-1319:52:16.26541944194Icom.byteflow.learnffmpeg:#30x74fdaac0a0(/data/app/com.byteflow.learnffmpeg-mVg7CcQSTXVnJhfo7u0XLA==/oat/arm64/base.odex+0xb0a0)
05-1319:52:16.26541944194Icom.byteflow.learnffmpeg:........

棧內(nèi)存溢出

//stack-buffer-overflow
staticvoidStackBufferOverflow(){
intarr[1024];
arr[0]=11;
arr[1024]=12;
LOGCATE("StackBufferOverflowarr[0]=%d,arr[1024]",arr[0],arr[1024]);
}

ASan 檢測(cè)結(jié)果(crash log)中出現(xiàn)關(guān)鍵字 stack-buffer-overflow :

05-1319:54:30.37150025002Icom.byteflow.learnffmpeg:=================================================================
05-1319:54:30.37150025002Icom.byteflow.learnffmpeg:==5002==ERROR:AddressSanitizer:stack-buffer-overflowonaddress0x007ff02278c0atpc0x0074f8bd6640bp0x007ff0226890sp0x007ff0226888
05-1319:54:30.37250025002Icom.byteflow.learnffmpeg:WRITEofsize4at0x007ff02278c0threadT0
05-1319:54:30.38950025002Icom.byteflow.learnffmpeg:#00x74f8bd663c(/data/app/com.byteflow.learnffmpeg-aaLGh4G_-2c2WC7sX0ibag==/lib/arm64/liblearn-ffmpeg.so+0x14663c)
05-1319:54:30.38950025002Icom.byteflow.learnffmpeg:#10x74f8bd4a20(/data/app/com.byteflow.learnffmpeg-aaLGh4G_-2c2WC7sX0ibag==/lib/arm64/liblearn-ffmpeg.so+0x144a20)
05-1319:54:30.38950025002Icom.byteflow.learnffmpeg:#20x74f8bd497c(/data/app/com.byteflow.learnffmpeg-aaLGh4G_-2c2WC7sX0ibag==/lib/arm64/liblearn-ffmpeg.so+0x14497c)
......

使用已釋放的指針

//heap-use-after-free
staticvoidUseAfterFree(){
int*arr=newint[1024];
arr[0]=11;
delete[]arr;
LOGCATE("UseAfterFreearr[0]=%d,arr[1024]",arr[0],arr[1024]);
}

ASan 檢測(cè)結(jié)果(crash log)中出現(xiàn)關(guān)鍵字 heap-use-after-free :

05-131944.43052355235Icom.byteflow.learnffmpeg:=================================================================
05-131944.43052355235Icom.byteflow.learnffmpeg:==5235==ERROR:AddressSanitizer:heap-use-after-freeonaddress0x004f0d5a7100atpc0x0074f7ac945cbp0x007ff02279d0sp0x007ff02279c8
05-1319:56:44.43052355235Icom.byteflow.learnffmpeg:READofsize4at0x004f0d5a7100threadT0
05-1319:56:44.44752355235Icom.byteflow.learnffmpeg:#00x74f7ac9458(/data/app/com.byteflow.learnffmpeg-w2WNuKKPLEj7i4_8_Oj3Sw==/lib/arm64/liblearn-ffmpeg.so+0x146458)
05-1319:56:44.44852355235Icom.byteflow.learnffmpeg:#10x74f7ac7920(/data/app/com.byteflow.learnffmpeg-w2WNuKKPLEj7i4_8_Oj3Sw==/lib/arm64/liblearn-ffmpeg.so+0x144920)
05-1319:56:44.44852355235Icom.byteflow.learnffmpeg:#20x74f7ac787c(/data/app/com.byteflow.learnffmpeg-w2WNuKKPLEj7i4_8_Oj3Sw==/lib/arm64/liblearn-ffmpeg.so+0x14487c)
......

局部變量的作用域之外使用其指針

//stack-use-after-scope
staticint*p;
staticvoidUseAfterScope()
{
{
inta=0;
p=&a;
}
*p=1111;
LOGCATE("UseAfterScope*p=%d",*p);
}

ASan 檢測(cè)結(jié)果(crash log)中出現(xiàn)關(guān)鍵字 stack-use-after-scope :

https://developer.android.com/ndk/guides/asan#cmake05-132019.44759075907Icom.byteflow.learnffmpeg:=================================================================
05-132019.44759075907Icom.byteflow.learnffmpeg:==5907==ERROR:AddressSanitizer:stack-use-after-scopeonaddress0x007ff02279a0atpc0x0074f8236438bp0x007ff0227970sp0x007ff0227968
05-1320:01:19.44859075907Icom.byteflow.learnffmpeg:WRITEofsize4at0x007ff02279a0threadT0
05-1320:01:19.4622333423334DLauncher_UnlockAnimationStateMachine:mResetIdleStateRunnable
05-1320:01:19.46459075907Icom.byteflow.learnffmpeg:#00x74f8236434(/data/app/com.byteflow.learnffmpeg-jx_Xi14rwGHag_VZ9KWXYA==/lib/arm64/liblearn-ffmpeg.so+0x146434)
05-1320:01:19.46559075907Icom.byteflow.learnffmpeg:#10x74f8234860(/data/app/com.byteflow.learnffmpeg-jx_Xi14rwGHag_VZ9KWXYA==/lib/arm64/liblearn-ffmpeg.so+0x144860)
05-1320:01:19.46559075907Icom.byteflow.learnffmpeg:#20x74f82347bc(/data/app/com.byteflow.learnffmpeg-jx_Xi14rwGHag_VZ9KWXYA==/lib/arm64/liblearn-ffmpeg.so+0x1447bc)
05-1320:01:19.46559075907Icom.byteflow.learnffmpeg:#30x74fdabe0a0(/data/app/com.byteflow.learnffmpeg-jx_Xi14rwGHag_VZ9KWXYA==/oat/arm64/base.odex+0xb0a0)
.....

重復(fù)釋放指針

//double-free
staticvoidDoubleFree(){
int*arr=newint[1024];
arr[0]=11;
delete[]arr;
delete[]arr;
LOGCATE("UseAfterFreearr[0]=%d",arr[0]);
}

ASan 檢測(cè)結(jié)果(crash log)中出現(xiàn)關(guān)鍵字 double-free :

05-1320:02:16.47461026102Icom.byteflow.learnffmpeg:=================================================================
05-1320:02:16.47561026102Icom.byteflow.learnffmpeg:==6102==ERROR:AddressSanitizer:attemptingdouble-freeon0x004f0d5a7100inthreadT0:
05-1320:02:16.49261026102Icom.byteflow.learnffmpeg:#00x74f9f2b7b0(/data/app/com.byteflow.learnffmpeg-kjj44NZxl-eyA06gf3E2MA==/lib/arm64/libclang_rt.asan-aarch64-android.so+0xd57b0)
05-1320:02:16.49261026102Icom.byteflow.learnffmpeg:#10x74f88cd210(/data/app/com.byteflow.learnffmpeg-kjj44NZxl-eyA06gf3E2MA==/lib/arm64/liblearn-ffmpeg.so+0x146210)
05-1320:02:16.49261026102Icom.byteflow.learnffmpeg:#20x74f88cb720(/data/app/com.byteflow.learnffmpeg-kjj44NZxl-eyA06gf3E2MA==/lib/arm64/liblearn-ffmpeg.so+0x144720)
05-1320:02:16.49261026102Icom.byteflow.learnffmpeg:#30x74f88cb67c(/data/app/com.byteflow.learnffmpeg-kjj44NZxl-eyA06gf3E2MA==/lib/arm64/liblearn-ffmpeg.so+0x14467c)
......

ASan 基本上可以覆蓋到常見(jiàn)的內(nèi)存錯(cuò)誤問(wèn)題,還有其他情況就不一一展示了。

編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Android
    +關(guān)注

    關(guān)注

    12

    文章

    3959

    瀏覽量

    129221
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3102

    瀏覽量

    74883
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1652

    瀏覽量

    49730

原文標(biāo)題:Android Native開(kāi)發(fā)內(nèi)存越界檢測(cè)

文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    ARM最優(yōu)CC++編譯器用戶指南

    ARM最優(yōu)CC++編譯器用戶指南
    發(fā)表于 03-14 10:48 ?3次下載

    使用英特爾編譯器和庫(kù)的新功能構(gòu)建快速代碼

    https://software.intel.com/zh-cn/intel-advisor-xe使用新的英特爾?編譯器15.0版編譯器和庫(kù),可以更快地構(gòu)建快速
    的頭像 發(fā)表于 11-12 07:03 ?2105次閱讀

    CompCert編譯器目標(biāo)代碼生成機(jī)制研究綜述

    CompCert是著名的C語(yǔ)言可信編譯器,是經(jīng)過(guò)形式化驗(yàn)證的編譯器的杰出代表,近年來(lái)被廣泛應(yīng)用于學(xué)術(shù)界和工業(yè)界的許多研發(fā)工作。 Compcert
    發(fā)表于 05-07 10:17 ?7次下載

    用于Python代碼的開(kāi)源式即時(shí)編譯器NUMBA介紹

    Numba 是一個(gè)適用于 Python 代碼的開(kāi)源式即時(shí)編譯器。借助該編譯器,開(kāi)發(fā)者可以使用標(biāo)準(zhǔn) Python 函數(shù)在 CPU 和 GPU 上加速數(shù)值函數(shù)。
    的頭像 發(fā)表于 07-08 09:15 ?1864次閱讀

    CC-RL 編譯器用戶手冊(cè)

    CC-RL 編譯器用戶手冊(cè)
    發(fā)表于 01-13 19:13 ?1次下載
    CC-RL <b class='flag-5'>編譯器用</b>戶手冊(cè)

    CC-RX 編譯器用戶手冊(cè)

    CC-RX 編譯器用戶手冊(cè)
    發(fā)表于 01-13 19:13 ?1次下載
    CC-RX <b class='flag-5'>編譯器用</b>戶手冊(cè)

    Neuron 現(xiàn)場(chǎng)編譯器用戶指南

    Neuron 現(xiàn)場(chǎng)編譯器用戶指南
    發(fā)表于 03-13 19:29 ?0次下載
    Neuron 現(xiàn)場(chǎng)<b class='flag-5'>編譯器用</b>戶指南

    R32C/100系列C編譯器包V.1.01 C編譯器用戶手冊(cè)

    R32C/100系列C編譯器包V.1.01 C編譯器用戶手冊(cè)
    發(fā)表于 04-28 19:54 ?1次下載
    R32C/100系列C<b class='flag-5'>編譯器</b>包V.1.01 C<b class='flag-5'>編譯器用</b>戶手冊(cè)

    CC-RL 編譯器用戶手冊(cè)

    CC-RL 編譯器用戶手冊(cè)
    發(fā)表于 07-03 20:03 ?0次下載
    CC-RL <b class='flag-5'>編譯器用</b>戶手冊(cè)

    CC-RX 編譯器用戶手冊(cè)

    CC-RX 編譯器用戶手冊(cè)
    發(fā)表于 07-03 20:03 ?0次下載
    CC-RX <b class='flag-5'>編譯器用</b>戶手冊(cè)

    Neuron 現(xiàn)場(chǎng)編譯器用戶指南

    Neuron 現(xiàn)場(chǎng)編譯器用戶指南
    發(fā)表于 07-04 20:47 ?0次下載
    Neuron 現(xiàn)場(chǎng)<b class='flag-5'>編譯器用</b>戶指南

    用于AVR MCU的MPLAB XC8 C編譯器用戶指南

    電子發(fā)燒友網(wǎng)站提供《適用于AVR MCU的MPLAB XC8 C編譯器用戶指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-19 15:47 ?3次下載
    適<b class='flag-5'>用于</b>AVR MCU的MPLAB XC8 C<b class='flag-5'>編譯器用</b>戶指南

    MPLAB XC16 C編譯器用戶指南

    電子發(fā)燒友網(wǎng)站提供《MPLAB XC16 C編譯器用戶指南.pdf》資料免費(fèi)下載
    發(fā)表于 09-21 09:27 ?1次下載
    MPLAB XC16 C<b class='flag-5'>編譯器用</b>戶指南

    Triton編譯器與GPU編程的結(jié)合應(yīng)用

    Triton編譯器簡(jiǎn)介 Triton編譯器是一種針對(duì)并行計(jì)算優(yōu)化的編譯器,它能夠自動(dòng)將高級(jí)語(yǔ)言代碼轉(zhuǎn)換為針對(duì)特定硬件優(yōu)化的低級(jí)代碼。Trit
    的頭像 發(fā)表于 12-25 09:13 ?633次閱讀

    用于PIC MCU的MPLAB XC8 C編譯器用戶指南

    電子發(fā)燒友網(wǎng)站提供《適用于PIC MCU的MPLAB XC8 C編譯器用戶指南.pdf》資料免費(fèi)下載
    發(fā)表于 01-22 16:45 ?0次下載
    適<b class='flag-5'>用于</b>PIC MCU的MPLAB XC8 C<b class='flag-5'>編譯器用</b>戶指南