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 作者都还在更新,最好的方法当然是自己下载源码编译一个,也是非常简单的。

dex2jar源码地址:https://github.com/pxb1988/dex2jar.git
安装gradle

brew install gradle

编译源码

gradle clean distZip

编译成功后,脚本会出现在/dex-tools/build/distributions/目录下

贴上原作者的回复

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, :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下载https://github.com/java-decompiler/jd-gui.git;
编译源码:运行./gradlew build在项目"build/libs/“目录下生成jd-gui-1.4.0.jar,双击即可运行;
也可以运行./gradlew installOsxDist在项目"build/install/jd-gui-osx/”目录下生成JD-GUI.app,双击运行。

编译过程中会重新下载gradle,特别慢;
方法是修改gradle-wrapper.properties里面的distributionUrl属性,改为gradle/wrapper/目录下的下载好的gradle文件;
运行继续报一个与Java9的兼容问题,折腾好久没解决,选择重新安装低版本的jdk;
安装好后,build还是有问题,发现是gradle版本不对,看原来的工程拿gradle2.4编的,于是又改成2.4的版本,终于编过了。

换了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属性
java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED -jar [jd-gui_jar]。

你可能感兴趣的:(android逆向)