Android逆向之路---ApkTool项目概览,编译ApkTool项目源码
前言
平时逆向apk,大部分公司还是都是使用混淆技术做为基础的。这周末,脱了腾讯最新版本的乐固的壳,正在研究。
无聊之余,想和大家聊一聊关于ApkTool这个项目,觉得工程师们写的还是很好的。
本章先大体的介绍一下ApkTool,然后以后的文章在依次的说下项目的各个模块。
问题
使用ApkTool的时候,总是有的公司插入一些干扰代码来防止ApkTool逆向,这个时候就需要我们读过ApkTool的源码,
然后手动定位问题所在解决问题了
项目地址
Apktool是一个项目的集合,包含子项目和一些依赖项。
分为了以下几个子项:
- brut.apktool.lib - 主项目,所有的依赖的代码(Main, all the Library code)
- brut.apktool.cli - 程序的入口吧,这个库里只有一个Main.java
- brut.j.dir - 工具项目
- brut.j.util - 工具项目
- brut.j.common - 工具项目
编译的环境
JDK 7或8 (OpenJDK不可以)
git
ApkTool项目使用Gradle工具构建
我用的是windows环境,
首先我们从git上clone
1 2 3 4 5 6 7 8
| git clone git://github.com/iBotPeaches/Apktool.git
cd Apktool
./gradlew.bat #linux的话就是gradlew文件了
|
编译完成后,文件位置在这里”./brut.apktool/apktool-cli/build/libs/apktool-xxxxx.jar”
Window环境要求
windows有一个最大长度文件路径限制。在ApkTool的存盘路径,由于Windows上最多255个字符的限制,我们需要强制执行一些要求。
这里总共留下了37个字符来克隆Windows的项目。也就是说,目录的深度不要太深。
举个栗子,下面的路径就可以,我的就是存放到了
这里总共占了19个字符。所以,不要将这个目录的长度太深,超过37.
编译结果
执行./gradlew命令之后,会输出如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| Building SNAPSHOT (master): 3879b9 :brut.apktool:compileJava NO-SOURCE :brut.apktool:processResources NO-SOURCE :brut.apktool:classes UP-TO-DATE :brut.apktool:jar :brut.apktool:assemble :brut.apktool:license :brut.apktool:compileTestJava NO-SOURCE :brut.apktool:processTestResources NO-SOURCE :brut.apktool:testClasses UP-TO-DATE :brut.apktool:test NO-SOURCE :brut.apktool:check :brut.apktool:build :brut.j.common:compileJava UP-TO-DATE :brut.j.common:processResources NO-SOURCE :brut.j.common:classes UP-TO-DATE :brut.j.common:jar UP-TO-DATE :brut.j.util:compileJava UP-TO-DATE :brut.j.util:processResources NO-SOURCE :brut.j.util:classes UP-TO-DATE :brut.j.util:jar UP-TO-DATE :brut.j.dir:compileJava UP-TO-DATE :brut.j.dir:processResources NO-SOURCE :brut.j.dir:classes UP-TO-DATE :brut.j.dir:jar UP-TO-DATE 注: 某些输入文件使用了未经检查或不安全的操作。 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。 :brut.apktool:apktool-lib:compileJava :brut.apktool:apktool-lib:processResources :brut.apktool:apktool-lib:classes :brut.apktool:apktool-lib:jar :brut.apktool:apktool-cli:compileJava :brut.apktool:apktool-cli:processResources NO-SOURCE :brut.apktool:apktool-cli:classes :brut.apktool:apktool-cli:jar :brut.apktool:apktool-cli:assemble :brut.apktool:apktool-cli:license :brut.apktool:apktool-cli:compileTestJava NO-SOURCE :brut.apktool:apktool-cli:processTestResources NO-SOURCE :brut.apktool:apktool-cli:testClasses UP-TO-DATE :brut.apktool:apktool-cli:test NO-SOURCE :brut.apktool:apktool-cli:check :brut.apktool:apktool-cli:build :brut.apktool:apktool-lib:assemble :brut.apktool:apktool-lib:license :brut.apktool:apktool-lib:compileTestJava :brut.apktool:apktool-lib:processTestResources :brut.apktool:apktool-lib:testClasses :brut.apktool:apktool-lib:test :brut.apktool:apktool-lib:check :brut.apktool:apktool-lib:build
BUILD SUCCESSFUL in 1m 25s 15 actionable tasks: 9 executed, 6 up-to-date 19:25:03: Task execution finished 'build'.
|
最后就编译成功了
使用方法
相信这个大家都不陌生,毕竟平时经常用的,那我就说两个常用指令
apk拆包
apktool d ******.apk
apk二次打包
apktool b your_path
分析入口
首先我们用idea将项目打开,
然后看Main.java类,路径就在brut.apktool/apktool-cli/src/main...../Main.java
源码如下,我加了注释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| public static void main(String[] args) throws IOException, InterruptedException, BrutException {
Verbosity verbosity = Verbosity.NORMAL;
CommandLineParser parser = new DefaultParser(); CommandLine commandLine;
_Options();
try { commandLine = parser.parse(allOptions, args, false); } catch (ParseException ex) { System.err.println(ex.getMessage()); usage(); return; }
if (commandLine.hasOption("-v") || commandLine.hasOption("--verbose")) { verbosity = Verbosity.VERBOSE; } else if (commandLine.hasOption("-q") || commandLine.hasOption("--quiet")) { verbosity = Verbosity.QUIET; } setupLogging(verbosity);
if (commandLine.hasOption("advance") || commandLine.hasOption("advanced")) { setAdvanceMode(true); }
boolean cmdFound = false; for (String opt : commandLine.getArgs()) { if (opt.equalsIgnoreCase("d") || opt.equalsIgnoreCase("decode")) { cmdDecode(commandLine); cmdFound = true; } else if (opt.equalsIgnoreCase("b") || opt.equalsIgnoreCase("build")) { cmdBuild(commandLine); cmdFound = true; } else if (opt.equalsIgnoreCase("if") || opt.equalsIgnoreCase("install-framework")) { cmdInstallFramework(commandLine); cmdFound = true; } else if (opt.equalsIgnoreCase("empty-framework-dir")) { cmdEmptyFrameworkDirectory(commandLine); cmdFound = true; } else if (opt.equalsIgnoreCase("publicize-resources")) { cmdPublicizeResources(commandLine); cmdFound = true; } }
if (!cmdFound) { if (commandLine.hasOption("version")) { _version(); System.exit(0); } else { usage(); } } }
|
美好的开始
本篇作为一个开篇,就是开个头,如果你对如何分析打包解包有很大的兴趣,
那么欢迎自己去认真分析cmdDecode方法,还有cmdBuild方法,
还有ApkTool里面的ApkDecoder,Androlib等关键的类,关键的方法。
算是希望和读者一起探讨一些思路,还有就是如果想研究resources.arsc,或者dex文件等,代码部分和文件的格式密切相关
后序希望自己能够一点一点补全,也希望大家能督促我,
关于我
个人网站:MartinHan的小站
博客:hanhan12312的专栏
知乎:MartinHan01)