[置顶] ANDROID反编译工具APKTOOL源码调试过程

APKTOOL是目前反编译ANDROID apk的主要工具,可以反编译出APK里的资源文件和smali代码,而有些APK开发者为了防止自己的代码被反编译,针对APKTOOL工具加固代码,使得APKTOOL无法运行正常,比如这篇文章介绍的Android应用资源文件格式解析与保护对抗研究,因此有必要根据具体情况修改APKTOOL源码重新编译,本人花了一天时间来编译调试,现将具体的过程分享一下。

一. 下载源码
APKTOOL源码下载,github上直接DOWNLOAD或者使用GIT来下载,最好使用GIT,它依赖什么项目就会自动的去下载。

二. 源码编译

编译可以直接使用APKTOOL目录下的gradlew.bat命令,我使用了ANDROID STUDIO来编译源码。

1. 源码导入ANDROID STUDIO
“FILE”->”OPEN…”->源码目录
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第1张图片

2. 编译
最右边”Gradle”->刷新同步
这时会自动的从网络上下载指定版本的gradle,如果gradle设置的是offline的话,gradle同步不了,需将gradle设置的offline的选择去掉。
“FILE”->”Settings”->”Build,Execution,Deployment”->”Gradle”
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第2张图片
同步成功的话,gradle窗口会出现如下的任务列表。
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第3张图片

在任务列表里选择如下的任务双击运行,APLTOOL的主要类在brut.apktool:apktool-cli模块里,运行”fatjar”任务生成项目的jar文件。
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第4张图片

这时会在项目目录下自动创建了brut.apkool.smali文件夹(文件夹不存在的话),然而编译会报错,找不到brut.apkool.smali下的源码。

[置顶] ANDROID反编译工具APKTOOL源码调试过程_第5张图片

因为brui.apktool:apktool-cli依赖brui.apktool:apktool-lib,brui.apktool:apktool-lib依赖brut.apkool.smali下的模块,brui.apktool:apktool-lib的build.gradle内容如下:

dependencies {
    compile("junit:junit:4.10") {
        exclude(module: 'hamcrest-core')
    }

    compile project(':brut.j.dir'),
            project(':brut.j.util'),
            project(':brut.j.common'),
            project(':brut.apktool.smali:util'),
            project(':brut.apktool.smali:dexlib2'),
            project(':brut.apktool.smali:baksmali'),
            project(':brut.apktool.smali:smali'),
            depends.snakeyaml,
            depends.xmlpull,
            depends.guava,
            depends.commons_lang

    testCompile depends.xmlunit
}

brut.apkool.smali下源码是空的,这是另一个项目的源码,需要先下载下来。

有两种方式下载:
1. 直接访问https://github.com/JesusFreke/smali下载源码,源码下载完成后将目录下的所有文件复制到brut.apkool.smali文件夹下。
2. 使用gradlew.bat applyPatches命令,这个会将本项目依赖的其他项目源码都同步下来,并下载到指定的目录里,不过这需要先按照git。

smali源码添加完成后再次运行任务,还是会报错”util”模块找不到。
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第6张图片

查看brut.apktool.smali:baksmali的build.gradle内容

dependencies {
    compile project(':util')
    compile project(':dexlib2')
    compile depends.commons_cli
    compile depends.guava

    testCompile depends.junit
    testCompile project(':smali')
}

其依赖util模块,而在目录下明明就有util模块,为什么找不到它呢?
通过上网查找了一下资料,了解了每个项目只能有一个settings.gradle,包含本项目下的所有的模块,apktool的settings.gradle内容如下:

include 'brut.j.common',
        'brut.j.util',
        'brut.j.dir',
        'brut.apktool.smali:util',
        'brut.apktool.smali:dexlib2',
        'brut.apktool.smali:baksmali',
        'brut.apktool.smali:smali',
        'brut.apktool.smali:dexlib2:accessorTestGenerator',
        'brut.apktool:apktool-lib',
        'brut.apktool:apktool-cli'

其中并没有util模块,这里之所以是util,是因为brut.apkool.smali是我后加入的另一个项目,在它的项目settings.gradle文件里是包含了,内容如下:

include 'util', 'dexlib2', 'baksmali', 'smali', 'dexlib2:accessorTestGenerator'

所以直接编译brut.apkool.smali是可以的,如果放在APKTOOL项目里编译就有问题了,解决方法就是将’:util’改为’:brut.apktool.smali:util’,同理其他的也一起改掉。

修改完了再次运行任务,还是报错。
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第7张图片
在brut.apktool\apktool-lib\src\main\java\brut\androlib\src\SmaliDecoder.java文件里出现了两个错误,ClassPath没有dontLoadClassPath静态变量,baksmaliOptions没有DIFFPRE静态变量,我也没弄明白我下载的都是最新的smali代码,为什么smali类里会没有相关变量。

ClassPath.dontLoadClassPath = mDebug;
options.registerInfo = (mDebug ? baksmaliOptions.DIFFPRE : 0);

我把ClassPath.dontLoadClassPath = mDebug;直接去掉,baksmaliOptions.DIFFPRE改为baksmaliOptions.ALL。

修改完后终于编译通过了,在Apktool\brut.apktool\apktool-cli\build\libs目录下成功生成apktool-cli.jar。

三. 调试
“Edit Configurations”->”+”->jar application设置如下内容->”ok”
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第8张图片

在apktool-cli下的[email protected]设置断点,Shift+F9调试成功。
[置顶] ANDROID反编译工具APKTOOL源码调试过程_第9张图片

你可能感兴趣的:(android,反编译,apktool)