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
is defined as
p1
(boolean) but used as
Z
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
and
Z
. It is simple to fix
I
- 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, :LZERO const p1, 1 goto :Lend :LZERO const 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
屬性:
VMOptions=-Xms512m --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED;
也可以修改
universalJavaApplicationStub.sh
或者
workaround
的
java
屬性