通常我們的程式碼都是通過ProGuard程式混淆的,混淆後每次修改編譯後在proguard資料夾下會生成下列檔案:
dump.txt:
描述.apk檔案中所有類檔案的內部結構
mapping.txt:
列出原始類的方法、欄位與混淆後的程式碼間的對映,這個檔案比較重要,如果你的程式碼混淆後會產生bug的話,log提示中是混淆後的程式碼,希望定位到原始碼的話就可以根據mapping.txt反推。
sends.txt:
列出了未被混淆的類和成員
usage.txt
列出了在apk中刪除的程式碼
ReTrace是ProGuard的“去混淆”堆疊跟蹤的配套工具,ReTrace可以讀取一個混淆的堆疊資訊,並將其恢復到沒有混淆的情況。恢復基於ProGuard在混淆過程中可以寫出的對映檔案mapping.txt。對映檔案將原始類名和類成員名稱連結到其混淆名稱,它被放在
執行的語法為:
java -jar retrace.jar [options...] mapping_file [stacktrace_file]複製程式碼
mapping_file
混淆時生成的對映檔案的名稱,
stacktrace_file
指定包含堆疊跟蹤的檔案的名稱
options:支援以下選項:
-verbose
指定列印更多資訊豐富的堆疊跟蹤,不僅包括方法名稱,還包括方法返回型別和引數,以及方法的行號等資訊,這個對於快速定位問題幫很有幫助,當然它得有個前期就是你在配置混淆的時候,保留行號資訊 -keepattributesSourceFile,LineNumberTable。
-regex regular_expression
指定用於解析堆疊跟蹤中的行的正規表示式。指定一個不同的正規表示式允許去除模糊更多的一般型別的輸入,而不僅僅是堆疊跟蹤。預設值適用於大多數JVM產生的堆疊跟蹤:
現在假設處理後的應用程式丟擲異常:
java.io.IOException: Can`t read [dummy.jar] (No such file or directory)
at proguard.y.a(MyApplication:188)
at proguard.y.a(MyApplication:158)
at proguard.y.a(MyApplication:136)
at proguard.y.a(MyApplication:66)
at proguard.ProGuard.c(MyApplication:218)
at proguard.ProGuard.a(MyApplication:82)
at proguard.ProGuard.main(MyApplication:538)
Caused by: java.io.IOException: No such file or directory
at proguard.d.q.a(MyApplication:50)
at proguard.y.a(MyApplication:184)
... 6 more複製程式碼
如果我們將堆疊跟蹤儲存在檔案中stacktrace.txt,我們可以使用以下命令恢復堆疊跟蹤:
java -jar retrace.jar mapping.txt stacktrace.txt
輸出將對應於原始堆疊跟蹤:
java.io.IOException: Can`t read [dummy.jar] (No such file or directory)
at proguard.InputReader.readInput(InputReader.java:188)
at proguard.InputReader.readInput(InputReader.java:158)
at proguard.InputReader.readInput(InputReader.java:136)
at proguard.InputReader.execute(InputReader.java:66)
at proguard.ProGuard.readInput(ProGuard.java:218)
at proguard.ProGuard.execute(ProGuard.java:82)
at proguard.ProGuard.main(ProGuard.java:538)
Caused by: java.io.IOException: No such file or directory
at proguard.io.DirectoryPump.pumpDataEntries(DirectoryPump.java:50)
at proguard.InputReader.readInput(InputReader.java:184)
... 6 more複製程式碼
使用行號恢復堆疊跟蹤(詳細)
在前面的例子中,我們也可以使用verbose標誌:
java -jar retrace.jar -verbose mapping.txt stacktrace.txt
輸出結果將如下所示:
java.io.IOException: Can`t read [dummy.jar] (No such file or directory)
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:188)
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,int,int,proguard.io.DataEntryReader)(InputReader.java:158)
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPath,proguard.io.DataEntryReader)(InputReader.java:136)
at proguard.InputReader.void execute(proguard.classfile.ClassPool,proguard.classfile.ClassPool)(InputReader.java:66)
at proguard.ProGuard.void readInput()(ProGuard.java:218)
at proguard.ProGuard.void execute()(ProGuard.java:82)
at proguard.ProGuard.void main(java.lang.String[])(ProGuard.java:538)
Caused by: java.io.IOException: No such file or directory
at proguard.io.DirectoryPump.void pumpDataEntries(proguard.io.DataEntryReader)(DirectoryPump.java:50)
at proguard.InputReader.void readInput(java.lang.String,proguard.ClassPathEntry,proguard.io.DataEntryReader)(InputReader.java:184)
... 6 more複製程式碼
我們還可以在直接在程式中使用程式碼呼叫,我們只要將retrace.jar引入我們的工程,就可以愉快的使用了,直接來看程式碼:
public static void ReTrace(String mapFile,String crashFile,String outFile) {
try {
File file = new File(outFile);
FileOutputStream fis = new FileOutputStream(file, false);
PrintStream out = new PrintStream(fis);
//這個重定向我們的輸出到指定的位置
System.setOut(out);
proguard.retrace.ReTrace localReTrace = new proguard.retrace.ReTrace(proguard.retrace.ReTrace.STACK_TRACE_EXPRESSION,
true, new File(mapFile), new File(
crashFile));
localReTrace.execute();
out.close();
fis.close();
} catch (IOException e) {
System.out.println("轉碼失敗");
e.printStackTrace();
}
}複製程式碼
通過呼叫它的ReTrace(String mapFile,String crashFile,String outFile)方法,
第一個引數為mapping檔案路徑地址
第二個引數為我們的堆疊資訊檔案地址
第三個檔案是我們要輸出解混淆後的檔案地址
參考資訊www.guardsquare.com/en/proguard…