Android中jsoup的混淆規則【轉】

Android中jsoup的混淆規則
版權聲明:轉載必須註明本文轉自嚴振杰的博客:http://blog.yanzhenjie.comhtml

說實話這篇文章的標題和內容我以爲很水,因此讀者們要是也以爲這篇文章很水的話,你順着網線來打我啊。哈哈,不開個玩笑這文章都無法繼續往下寫了。java

這段時間天天工做到22點下班回家,到家後基本就23點了,週六週日也是同樣的,因此Github上的項目有嚴重bug會在中午休息的時候抽時間修復,博客基本處於斷更狀態。不過慶幸的是昨晚已經把項目寫完了,安排週一上線,今兒個是週日,終於能夠休息了,也順便把昨晚發現的一個關於jsoup的問題記錄一下。node

發現問題
項目中使用了jsoup來分析html文檔,一切都很順利,可是在代碼混淆後在某些手機上卻發生了異常致使App崩潰。因而趕忙搜索了jsoup的混淆規則,發現千篇一概的規則是:spa

-dontwarn org.jsoup.**
-keep class org.jsoup.**{*;}
1
2
這樣的混淆規則不用試就知道確定是能夠解決問題的,可是把至關於把部分代碼暴露了出去,因而我抓了下崩潰日誌,最主要的地方以下:.net

Caused by: java.lang.ExceptionInInitializerError
at org.a.c.f$a.<init>(SourceFile:372)
at org.a.c.f.<init>(SourceFile:19)
at org.a.d.m.b(SourceFile:32)
at org.a.d.m.a(SourceFile:42)
at org.a.d.b.a(SourceFile:56)
at org.a.d.g.ay(SourceFile:100)
at org.a.a.hm(SourceFile:58)日誌

Caused by: java.lang.IllegalStateException:
Could not read resource entities-xhtml.properties.
Make sure you copy resources for org.a.c.i
at org.a.c.i.a(SourceFile:301)
at org.a.c.i.b(SourceFile:25)
at org.a.c.i$b.<init>(SourceFile:53)
at org.a.c.i$b.<clinit>(SourceFile:34)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
經過下面這句話能夠判斷是jsoup拋出的異常沒跑了:htm

Caused by: java.lang.ExceptionInInitializerError
at org.a.c.f$a.<init>(SourceFile:372)
1
2
而後目光迅速被吸引到這句話:blog

Could not read resource entities-xhtml.properties
1
哦這下明白了,原來是某個類中讀取了entities-xhtml.properties資源文件,混淆以後讀不出來了。憑經驗來分析一下,假若有一個類叫A,那麼java中讀取資源文件咱們通常是:資源

A.class.getResourceAsStream("fileName");
1
而class.getResourceAsStream(String)會指定要加載的資源路徑與當前類所在包的路徑一致。例如咱們寫了一個A類在包com.yanzhenjie.test下,那麼A.class.getResourceAsStream("fileName") 會在com.yanzhenjie.test包下查找相應的資源。若是這個fileName是以/開頭的,那麼就會從classpath的根路徑下開始查找。開發

注:此資源非彼資源文件,只涉獵Android開發的同窗不要把這個資源文件和Android中/res下的資源文件混淆,不是同一個東西。

因此如今問題基本上已經浮出水面了,作了代碼混淆以後,因爲規則外的class文件和路徑所有被混淆,而資源文件的路徑不會被混淆,打包成apk後,class文件在apk/classes.dex中,classes.dex反編譯成jar文件,jar文件再解壓後class文件的路徑會變成a.b.c.className,而資源文件在/apk/packageName下,它們的路徑由於沒有混淆仍是com.yanzhenjie.test.fileName。所以class文件的路徑是a.b.c.className,而資源文件的路徑是com.yanzhenjie.test.fileName因此class.getResourceAsStream(String)會加載不到資源文件,剩下的就是看源碼找出資源文件和class所在包並添加混淆規則了。

java包圖:


根據上面的異常信息和包中的資源文件entities-xxx.properties判斷下,大概加載資源文件的代碼應該在Entities.class中吧,因而咱們打開Entities.class文件,果真發現了報異常的代碼:


再往下翻一點就能夠看到一個枚舉類,咱們知道枚舉至關因而常量。因此下圖中類Entities被load的時候枚舉EscapeMode的幾個成員值就要初始化了,初始化即走本身的構造方法,在構造方法中又調用了上圖中加載資源文件的代碼:


由於咱們發現問題是咱們混淆了Entities.class所在包名致使的異常,因此咱們只要保證這個包名不被混淆便可。

解決方案
最開始說的比較通用的混淆規則確定是能夠解決問題的:

-dontwarn org.jsoup.**
-keep class org.jsoup.**{*;}
1
2
可是這至關於沒有混淆jsoup了,這裏咱們能夠維持包名不混淆便可解決問題,咱們只須要爲jsoup添加以下混淆規則便可:

-keeppackagenames org.jsoup.nodes1我這樣寫能夠解決我遇到的這個問題,若是其它人還遇到其它問題,能夠在博客下方留言,我會給出解決方案。本文結束,一邊帶孩子一邊寫博客,寫完了專心哄孩子去了,白白。————————————————版權聲明:本文爲CSDN博主「嚴振杰」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/yanzhenjie1003/article/details/78384725

相關文章
相關標籤/搜索