dex2jar 和 jd-gui
dex2jar反編譯的時候出了點問題:
輸出錯誤 Detail Error Information in File ./APK-error.zip
看了下大多數都是一樣的問題:java.lang.RuntimeException: can not merge I and Z
sourceforge上解釋就是錯誤的原因在于一個參數異常,其實就是寫代碼的人故意把booleanl和int類型混淆,導致dex2jar出錯
解決方案:
1、如果出錯代碼量不大的話可以直接修改代碼,也即修改 smali 文件,在出錯的地方加一個對類型的判斷和賦值,參見https://github.com/pxb1988/dex2jar/issues/11;
2、如果需要修改的代碼量太多,或者想一勞永逸解決這個問題,也可以去修改dex2jar,針對bug出現的函數做類型修復。
BTW,這個 bug 是2015/5/13被提出來,作者第二天就做了回復,后續版本的 dex2jar 已經修復了這個問題。目前市面上的流通的dex2jar_2.0,dex2jar_2.1 都是老版本,都存在這個問題。項目截止到2019/9 作者都還在更新,最好的方法當然是自己下載源碼編譯一個,也是非常簡單的。
基于源碼2.x分支最新版代碼(5 Sep 2019)編譯好資源已經上傳,md5為ec185c22e87038f5082784e541d19fe0
- dex-tools-2.1-SNAPSHOT.zip
如果想自己編譯的話,dex2jar源碼地址:https://github.com/pxb1988/dex2jar.git,步驟如下
#安裝gradle brew install gradle # 編譯源碼 git clone https://github.com/pxb1988/dex2jar.git cd dex2jar gradle clean distZip # if build successfull, the zip file is under dex-tools/build/distributions/編譯成功后,腳本會出現在dex-tools/build/distributions/目錄下,是一個zip文件,解壓后就是各種工具
貼上原作者的回復
notice the line invoke-static { v0, p1 }, Lcom/twitter/android/TweetActivity;->a(Lcom/twitter/android/TweetActivity;I)Z.
p1 is defined as Z (boolean) but used as I(int)
the problem is caused by strict type calculation, because in java syntaxt, a boolean can not assign to an inteager. so dex2jar forbid merge type Z and I. It is simple to fix
-
modify the dex by hand and add the following code before invoke-static { v0, p1 }, Lcom/twitter/android/TweetActivity;->a(Lcom/twitter/android/TweetActivity;I)Z
if-eqz p1, :LZEROconst p1, 1goto :Lend :LZEROconst p1, 0 :Lend -
OR modify the dex2jar code. return Type I when merge I and Z at com.googlecode.dex2jar.ir.TypeClass.merge(TypeClass.java:100)
Q1:dex2jar解析應用有時候正常,有時候會報OOM的錯誤?
Java中的對象創建和回收:
String a; //聲明了一個變量,a為空
String a = new String(); //聲明了一個對象,同時在堆上為該對象分配了空間,變量存儲空間地址
String a = “XXX”; //查找對象地址,并在空間上填充了內容,不存在則新建對象存儲
注:此處的a是一個引用類型,通過a可以引用String類中的成員變量和成員方法
棧內存由Java自動分配并釋放;
堆內存(new創建)由Java虛擬機的自動垃圾回收器來管理。
解決辦法也是簡單粗暴,直接修改dex2jar執行腳本設置,改-Xmx參數來增加堆空間,not an elegant way。
Q2:想進一步驗證dex2jar的結果,運行jd-gui查看jar閃退?
重新安裝jd-gui,命令是brew cask install jd-gui,安裝太慢了,放棄;
自己下載源碼編譯安裝
# 下載 git clone https://github.com/java-decompiler/jd-gui.git cd jd-gui # 編譯jar ./gradlew build # 安裝app(optional) ./gradlew installOsxDist編譯完成后,會在項目build/libs/目錄下生成jd-gui-1.6.6.jar和jd-gui-1.6.6-min.jar,雙擊即可運行;
如果安裝app,則會在項目build/distributions/目錄下生成各平臺的壓縮包,解壓jd-gui-osx-1.6.6.zip就可以得到JD-GUI.app,也是雙擊運行。
編譯遇到的其他問題:
1、編譯過程中會重新下載gradle,因為網絡問題會特別慢,方法是修改gradle/wrapper/gradle-wrapper.properties里面的distributionUrl屬性,改為本地.gradle/wrapper/dist/目錄下的下載好的gradle文件路徑;
2、運行時會報一個與Java9的兼容問題,重新安裝低版本的jdk折騰好久沒解決,最后發現是gradle版本不對,看原來的工程拿gradle2.4編的,于是又改成2.4的版本,終于編過了;
3、注意換了jdk版本,dex2jar又不能運行了,顯示找不到類方法java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer;,測試了下,果然是java版本的問題(心累),因為從jdk9之后,增加了一些新特性,可以訪問某些模塊的受限類。
修改方法是找到jd-gui安裝路徑Contents目錄下的Info.plist,修改VMOptions屬性:
也可以修改universalJavaApplicationStub.sh或者workaround的java屬性
java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED -jar [jd-gui_jar]總結
以上是生活随笔為你收集整理的dex2jar 和 jd-gui的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpWebRequest类
- 下一篇: 小型移动 webApp Demo 知识点