Android 如何分析线上混淆异常

518 阅读2分钟
  • 分析异常信息,得到App版本信息,混淆过的异常堆栈
Process: com.test.xxx
PID: 17906
UID: 1000
Frozen: false
Flags: 0x28c8bec5
Package: com.test.xxx v100000000 (10.0.0-20240711164441)
Foreground: Yes
Process-Runtime: 215118
Crash-Handler: com.android.internal.os.RuntimeInit$KillApplicationHandler
Loading-Progress: 1.0
Dropped-Count: 0
ShouldUpload: true
ExceptionConfig: 

java.lang.IllegalArgumentException: cannot use a recycled source in createBitmap
        at android.graphics.Bitmap.createBitmap(Bitmap.java:913)
        at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:835)
====================================================================================================
java.lang.IllegalArgumentException: cannot use a recycled source in createBitmap
        at android.graphics.Bitmap.createBitmap(Bitmap.java:913)
        at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:835)
        ...省略到业务异常
        ...

版本信息

Package: com.test.xxx v100000000 (10.0.0-20240711164441)
  • mapping文件
# compiler: R8
# compiler_version: 3.1.66
# min_api: 31
# pg_map_id: 91d205f
# common_typos_disable
# {"id":"com.android.tools.r8.mapping","version":"1.0"}
a.a.a.a -> a.a:
# {"id":"sourceFile","fileName":""}
    void a(long) -> b
    boolean a(org.xmlpull.v1.XmlPullParser) -> c
    void a(com.zookingsoft.expression.Expression,long) -> j
a.a.a.a$a -> a.a$a:
# {"id":"sourceFile","fileName":""}
a.a.a.b -> a.b:
# {"id":"sourceFile","fileName":""}
    void a(long) -> b
    boolean a(org.xmlpull.v1.XmlPullParser) -> c
    void b() -> d
    void c() -> e
    void d() -> f
    void e() -> g
    void f() -> h
    void g() -> i
a.a.a.c -> a.c:
# {"id":"sourceFile","fileName":""}
    void a() -> b
    void a(a.a.a.b) -> c
    java.util.ArrayList b(a.a.a.c) -> d
    void b() -> e
    java.util.ArrayList c(a.a.a.c) -> f
    void c() -> g
a.a.a.c$a -> a.c$a:
# {"id":"sourceFile","fileName":""}
a.a.a.d -> a.d:
# {"id":"sourceFile","fileName":""}
    void a(long) -> b
    boolean a(org.xmlpull.v1.XmlPullParser) -> c
    void a(com.zookingsoft.expression.Expression,com.zookingsoft.expression.Expression,long) -> j
a.a.a.d$a -> a.d$a:
# {"id":"sourceFile","fileName":""}
a.a.a.e -> a.e:
# {"id":"sourceFile","fileName":""}
    void a(long) -> b
    boolean a(org.xmlpull.v1.XmlPullParser) -> c
    void a(com.zookingsoft.expression.Expression,long) -> j
a.a.a.e$a -> a.e$a:
# {"id":"sourceFile","fileName":""}
a.a.a.f -> a.f:

mapping文件就是一个映射表,记录了混淆名字直接的对应关系,比如createData名称被混淆成aa,所以通过这个文件,可以把混淆后的异常堆栈反混淆还原回去。一般在打包apk发布出去之前,都会有仓库记录下发布apk的相关信息,包括messagemappingapk等。

  • message 文件

message 文件其实就是代码提交记录

TestApp
code_path:
revision:f438891d6432b23641f472a76aa8a412a278c237
ftp_path:/
build_number:102167

changes:
f438891  #1353178 修复问题1
c5542da  #1365711 修复问题2
3cbdb1f  #1361482 修复问题3

由于本地代码在不断迭代,但是异常可能是历史的,为了还原异常对应的代码,需要回退代码。

通过message 文件可以找到revision,然后回退本地代码到该版本,

git reset --hard f438891d6432b23641f472a76aa8a412a278c237

  • retrace 命令反混淆异常堆栈

/Android/Sdk/tools/proguard/bin/retrace.sh -verbose ./mappings.txt ./obfuscated_stacktrace.txt > ./deobfuscated_stacktrace.txt

得到混淆之后的异常日志

java.lang.IllegalArgumentException: cannot use a recycled source in createBitmap
    at android.graphics.Bitmap.createBitmap(Bitmap.java:913)
    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:835)
    ...省略到业务异常
    ...
  • Analyze Stack Trace 工具

把反混淆后的异常堆栈,放到工具中解析定位异常位置