Skip to content

Instantly share code, notes, and snippets.

@wdv4758h
Last active April 21, 2017 07:56
Show Gist options
  • Select an option

  • Save wdv4758h/6197a343b8fbfab0333a to your computer and use it in GitHub Desktop.

Select an option

Save wdv4758h/6197a343b8fbfab0333a to your computer and use it in GitHub Desktop.

Android Memory Leak Profiling

我們寫程式總免不了會有 bugs, 其中 Memory 相關的 bugs 佔了一大部份, 有工具可以幫我們檢查嗎?

有的, 最常見的是 Valgrind, 除此之外還有 Pin、Dr.Memory、Sanitizer ...

  AddressSanitizer Valgrind (Memcheck) Valgrind (SGCheck)
technology CTI DBI DBI
ARCH x86, x86_64, ARM, PPC, ... x86, x86_64, ARM, PPC, ... x86, x86_64, ARM, PPC, ...
OS Linux, FreeBSD, Android, Mac, Windows, ... Linux, FreeBSD, Android, Mac, ... Linux, FreeBSD, Android, Mac, ...
Slowdown 2x 20x  
Detects:
Heap OOB O O X
Stack OOB O X O
Global OOB O X O
UAF O O X
UAR O X* X
UMR X O X
Leaks O O X

* : 可能會變成 UAF 被偵測到

縮寫 全名
CTI Compile-Time Instrumentation
DBI Dynamic Binary Instrumentation
UMR Uninitialized Memory Reads
UAF Use-After-Free (aka dangling pointer)
UAR Use-After-Return
OOB Out-Of-Bounds

沒在上面 table !?

int *x = malloc(sizeof(int));
free(x);
free(x);
int *x = malloc(sizeof(int));
free(x);
*x = 42;
char *x = malloc(sizeof(char) * 3);
x[42] = 'C';
char x[3];
x[42] = 'C';
char x[3];
x[42] = 'C';
int* f() {
    int a = 0;
    return &a;
}

void g() {
    int* x = f();
    *x = 42;
}
int x;
if (x > 0)
    return 1;
  • Valgrind
  • LLVM Sanitizer

Wrapper for Activity Manager

setprop wrap.$PACKAGE "logwrapper /data/local/Inst/bin/start_valgrind.sh"

script 1 : start_valgrind.sh

#!/system/bin/sh

PACKAGE="com.android.browser"

export TMPDIR=/data/data/$PACKAGE

VGPARAMS="--log-file=$TMPDIR/valgrind.log.%p --error-limit=no --trace-children=yes"

# Memcheck tool
VGPLUGIN="--tool=memcheck --leak-check=full --show-reachable=yes"

echo "valgrind args: $*"
exec /data/local/Inst/bin/valgrind $VGPARAMS $VGPLUGIN $*

stcript 2 : bootstrap_valgrind.sh

#!/usr/bin/env sh

PACKAGE="com.android.browser"
ACTIVITY=".BrowserActivity"


adb push start_valgrind.sh /data/local/Inst/bin/
adb shell chmod 777 /data/local/Inst/bin/start_valgrind.sh

adb root
adb shell setprop wrap.$PACKAGE "logwrapper /data/local/Inst/bin/start_valgrind.sh"

echo "wrap.$PACKAGE: $(adb shell getprop wrap.$PACKAGE)"

# -S: force stop the target app before starting the activity
# -D: enable debugging
# -a: <ACTION> Specify the intent action, such as "android.intent.action.VIEW". You can declare this only once.
# -n: <COMPONENT> Specify the component name with package name prefix to create an explicit intent, such as "com.example.app/.ExampleActivity".

adb shell am start -S -a android.intent.action.MAIN -n $PACKAGE/$ACTIVITY

adb logcat -c   # -c: clears (flushes) the entire log and exits.
adb logcat

valgrind first revision : https://github.com/svn2github/valgrind-master-mirror/commit/de4a1d01951937632098a6cda45859afa587a06f

Android : https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid
http://lists.llvm.org/pipermail/llvm-dev/2013-June/063073.html

及早除蟲,避免腐爛

系統程式


timeline

Valgrind ----->

Sanitizer ------------>

code coverage


其中 Memory 相關的問題佔了很大一部份,

Therac-25 是由 AECL 生產的輻射治療機器, 但是因為軟體的問題造成六起醫療事故, 使患者死亡或者受到嚴重的輻射灼傷。

Therac-25 使用 PDP-11 進行機器控制, 沿用原先有硬體保護機制的 Therac-20 的軟體, 操作過快時會造成 race conditions, 產生嚴重的後果。 但是原先的 Therac-20 有硬體保護, 所以先前都沒有出問題, 後來 Therac-25 完全由軟體控制, 問題因此顯現。

歐洲太空總署耗費 10 年打造無人駕駛的 Ariane 5 火箭, 於 1996 年 6 月 4 日進行發射, 但是因為軟體錯誤, 造成升空後 37 秒就爆炸, 損失約 3.7 億美元。

此軟體 bug 為 64-bit 浮點數和 16-bit 整數的轉換, 整套系統承襲自 Ariane 4, 但是 Ariane 5 的運算能力比 Ariane 5 高, 原先不會發生的問題就此產生, 造成 overflow, 產生 hardware exception, 最後使整個系統失效, 造成火箭發射失敗。

  • 靜態
  • 動態
    • 搭配 Test Case
    • 搭配 Fuzz Testing
  優點 缺點
靜態 執行前找出問題 有些問題無法找到
動態 可找出更多種類的問題
  • 無法在執行前找出問題
  • 需要搭配 Testing 使用
  • Coverity
  • Valgrind
  • LLVM Sanitizer

Valgrind 是一個 Dynamic Binary Instrumentation Framework, 可以在已經編完的 Binary 程式裡插入檢查的 code。 內部使用 VEX IR 作為中間層, 任何平台的 Binary (x86/MIPS/ARM/...) 只要接上 frontend 轉成 VEX IR, 就可以接上已經寫好的 Plugin, JIT 地轉換成新的 Binary 後執行。

可以解決 Ariane 5 的問題

  • no false positive
  • need good multithread test
  • data race
  • thread leak
  • deadlocks
  • incorrect uses of mutexes
  • malloc calls in signal handlers
  • ...
  • natively understands atomic operations (can find bugs in lock-free algorithms)

市面上常見的分析工具大多先針對 x86 平台, 然而現今 ARM 的設備已經相當普遍, 這些工具在 ARM 上又是否能使用呢?

仍然缺乏

zygote with sanitizer

http://lists.llvm.org/pipermail/llvm-dev/2013-June/063101.html http://address-sanitizer.googlecode.com/svn-history/r1624/wiki/Android.wiki https://github.com/google/sanitizers/wiki/AddressSanitizer https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid

Android NDK supports AddressSanitizer on arm, armv7 and x86 ABIs starting with version r10d (2014-12).

AddressSanitizer on Android requires a rooted device (either -eng or -userdebug build, or any other setup that allows editing the contents of the /system partition).

!!! http://swsys.ru/index.php?page=article&id=3593&lang=en

Combining compile-time and run-time instrumentation for testing tools 昨天晚上找到的 還沒空讀完 裡面提到 DRASan 是要結合 Dynamo 和 AddressSanitizer (有看到裡面在討論混合式的 Instrumentation)

http://blog.chromium.org/2012/04/fuzzing-for-security.html

Static binary instrumentation

https://www.chromium.org/developers/how-tos/using-drmemory https://en.wikipedia.org/wiki/DynamoRIO#cite_note-9

dr memory vs valgrind

http://seclab.cs.sunysb.edu/seclab/pubs/vee14.pdf

Still working on it ...


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment