逆向开发使用dx.jar、d8.jar、baksmali.jar将jar转dex文件,解决requires --min-sdk-version >= 26 (currently 13)问题

apk母包中合并第三方SDK代码

  • 当我们需要将某些第三方SDK的代码合并到自己的apk母包的时候,一般的流程是解压第三方SDK的aar文件,然后合并里面的资源文件,assets、res目录直接拷贝合并就行,jni目录合并到apk的libs目录,AndroidManifest.xml文件则需要根据实际情况进行XML元素的合并,一部分元素或者属性不能进行合并,classes.jar以及libs下的jar文件则需要使用dx.jar或者d8.jar转为dex文件,然后再使用baksmali.jar转为smali文件,最后就可以合并到母包apk的smali目录里面了
  • 在合并jar文件的时候需要特别注意一下jar文件里面是否还含有assets、unknown等其他资源文件,预防我们在手动进行合并的时候遗漏了,unknown资源文件的合并可以参考这篇文章:Android逆向开发处理unknown文件&AppsFlyer库中classes.jar中的a-,b-资源合并问题_林慈桥的博客-CSDN博客

使用dx.jar将aar包中的jar转为dex文件

  • 首先进入dx.jar 所在的目录
  • 然后再文件目录里面输入cmd按回车键,直接进入cmd命令窗口,可以看到已经定位到了dx.jar所在的目录 
  • 为了便于测试,我们在AS里面新建一个modul,然后编写一些代码,里面使用了java8的lambda表达式,gradle里面配置了java8的编译环境,这样我们构建一个aar包
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
package com.test.lib;

import android.util.Log;

import java.io.FileFilter;

public class Test {
    public void fun() {
        FileFilter fileFilter = file -> false;
        Log.e("test", fileFilter.toString());
    }
}
  • 我们将生成的的x7.aar包拷贝到dx.jar所在目录,然后将x7.aar改为x7.zip,然后解压到x7目录下,然后我们执行java的jar命令,执行命令之前需要配置java环境变量,否则需要执行命令的时候需要输入java.exe所在的全路径,接下来执行命令:java -jar dx.jar --dex --output=x7/my.dex x7/classes.jar
H:\Sdk\build-tools\28.0.3\lib>java -jar dx.jar --dex --output=/my.dex x7/classes.jar
Uncaught translation error: com.android.dx.cf.code.SimException: ERROR in com.test.lib.Test.fun:()V: invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13)
1 error; aborting
  • 很不幸的是jar转dex失败了,里面有提示:invalid opcode ba - invokedynamic requires --min-sdk-version >= 26 (currently 13) ,我们试着在命令里面加上--min-sdk-version=26参数,再执行命令:java -jar dx.jar --dex --min-sdk-version=26 --output=x7/my.dex x7/classes.jar
H:\Sdk\build-tools\28.0.3\lib>java -jar dx.jar --dex --min-sdk-version=26 --output=x7/my.dex x7/classes.jar
  • OK,好像执行成功了,我们看下
  • 接下来我们还需要将my.dex转为smali文件,我们将 baksmali.jar文件拷贝到dx.jar同目录下,方便我们执行命令,然后执行命令:java -jar baksmali.jar -o x7_smalid x7/my.dex
H:\Sdk\build-tools\28.0.3\lib>java -jar baksmali.jar -o x7_smalid x7/my.dex
Exception in thread "main" org.jf.util.ExceptionWithContext: x7\my.dex is not an apk, dex file or odex file.
        at org.jf.dexlib2.DexFileFactory.loadDexFile(DexFileFactory.java:111)
        at org.jf.dexlib2.DexFileFactory.loadDexFile(DexFileFactory.java:54)
        at org.jf.baksmali.main.main(main.java:252)
  • 结果转smali失败了,看来加了--min-sdk-version=26生成的dex文件还是有问题,baksmali.jar识别不到。产生这个问题的主要原因就是我们的源码里面使用了java8的lambda表达式,如果改成非lambda表达式方式,来执行dx.jar命令,就不会失败了,但是我们也不可能让第三方的SDK去改代码吧,所以还是要有其他方案来解决这个问题,还好google给我们提供了一个d8.jar工具,这个就可以用来处理java8新语法生成的jar转dex失败问题,下面是d8工具的命令说明:
H:\Sdk\build-tools\28.0.3\lib>java -jar d8.jar
Usage: d8 [options] <input-files>
 where <input-files> are any combination of dex, class, zip, jar, or apk files
 and options are:
  --debug                 # Compile with debugging information (default).
  --release               # Compile without debugging information.
  --output <file>         # Output result in <outfile>.
                          # <file> must be an existing directory or a zip file.
  --lib <file>            # Add <file> as a library resource.
  --classpath <file>      # Add <file> as a classpath resource.
  --min-api               # Minimum Android API level compatibility
  --intermediate          # Compile an intermediate result intended for later
                          # merging.
  --file-per-class        # Produce a separate dex file per input class
  --no-desugaring         # Force disable desugaring.
  --main-dex-list <file>  # List of classes to place in the primary dex file.
  --version               # Print the version of d8.
  --help                  # Print this message.
  • 来执行下d8命令:
H:\Sdk\build-tools\28.0.3\lib>java -jar d8.jar --output H:\Sdk\build-tools\28.0.3\lib\x7 x7/classes.jar
Warning in x7\classes.jar:com/test/lib/Test.class:
  Type `android.util.Log` was not found, it is required for default or static interface methods desugaring of `void com.test.lib.Test.fun()`
Warning in synthesized for lambda desugaring:
  Interface `java.io.FileFilter` not found. It's needed to make sure desugaring of `com.test.lib.-$$Lambda$Test$3pJU-DzmeoaW6KjvNrGLr3KT1RM` is correct. Desugaring will assume that this interface has no default method.

  • 可以看到已经生成了一个classes.dex文件,虽然有警告信息,但是执行是成功的,我们再使用baksmali.jar 工具来生成smali文件 
H:\Sdk\build-tools\28.0.3\lib>java -jar baksmali.jar -o x7_smali x7\classes.dex
test

另一种生成smali文件的方法

  • 如果我们不想将dx.jar工具升级为d8.jar该怎么办呢?有一种剑走偏锋的方法就是,引入一个空的项目工程,只引入第三方的SDK的代码,然后生成apk文件,再使用apktool进行反编译得到smali以及其他的代码资源文件
  • 但是gradle需要配置minSdkVersion大于等于24,否则会有其他的问题出现 ,有兴趣的同学可以自己去试试
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值