Android逆向之路---ApkTool項目概覽,編譯ApkTool項目源碼

前言

平時逆向apk,大部分公司仍是都是使用混淆技術作爲基礎的。這週末,脫了騰訊最新版本的樂固的殼,正在研究。 無聊之餘,想和你們聊一聊關於ApkTool這個項目,以爲工程師們寫的仍是很好的。 本章先大致的介紹一下ApkTool,而後之後的文章在依次的說下項目的各個模塊。java

問題

使用ApkTool的時候,老是有的公司插入一些干擾代碼來防止ApkTool逆向,這個時候就須要咱們讀過ApkTool的源碼, 而後手動定位問題所在解決問題了linux

ApkTool工具概覽

項目地址git

Apktool是一個項目的集合,包含子項目和一些依賴項。 分爲了如下幾個子項:github

  • 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不能夠) gitshell

編譯ApkTool工具步驟

ApkTool項目使用Gradle工具構建windows

我用的是windows環境, 首先咱們從git上clone安全

git clone git://github.com/iBotPeaches/Apktool.git

cd Apktool

./gradlew.bat
#linux的話就是gradlew文件了


複製代碼

編譯完成後,文件位置在這裏"./brut.apktool/apktool-cli/build/libs/apktool-xxxxx.jar"bash

Window環境要求

windows有一個最大長度文件路徑限制。在ApkTool的存盤路徑,因爲Windows上最多255個字符的限制,咱們須要強制執行一些要求。ide

這裏總共留下了37個字符來克隆Windows的項目。也就是說,目錄的深度不要太深。 舉個栗子,下面的路徑就能夠,個人就是存放到了工具

D:/gitclone/Apktool
複製代碼

這裏總共佔了19個字符。因此,不要將這個目錄的長度太深,超過37.

編譯結果

執行./gradlew命令以後,會輸出以下

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

源碼以下,我加了註釋:

public static void main(String[] args) throws IOException, InterruptedException, BrutException {

        // 設置verbosity的默認值,後面會根據咱們傳入的參數更改
        //
        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;
        }

        //首先檢查verbose選項
        if (commandLine.hasOption("-v") || commandLine.hasOption("--verbose")) {
            verbosity = Verbosity.VERBOSE;
        } else if (commandLine.hasOption("-q") || commandLine.hasOption("--quiet")) {
            verbosity = Verbosity.QUIET;
        }
        //設置好verbose
        setupLogging(verbosity);

        //檢測是不是使用advance,
        if (commandLine.hasOption("advance") || commandLine.hasOption("advanced")) {
            setAdvanceMode(true);
        }

        boolean cmdFound = false;
        for (String opt : commandLine.getArgs()) {
            //若是有解包指令,那麼執行cmdDecode,如下相似
            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;
            }
        }

        //若是沒有命令未找到,那麼先看看有沒有version選項,有的話就打印版本信息
        //沒有的話,彈出幫助文檔,而後退出了
        if (!cmdFound) {
            if (commandLine.hasOption("version")) {
                _version();
                System.exit(0);
            } else {
                usage();
            }
        }
    }

複製代碼

美好的開始

本篇做爲一個開篇,就是開個頭,若是你對如何分析打包解包有很大的興趣, 那麼歡迎本身去認真分析cmdDecode方法,還有cmdBuild方法, 還有ApkTool裏面的ApkDecoder,Androlib等關鍵的類,關鍵的方法。

算是但願和讀者一塊兒探討一些思路,還有就是若是想研究resources.arsc,或者dex文件等,代碼部分和文件的格式密切相關

後序但願本身可以一點一點補全,也但願你們能督促我,

關於我

我的網站:MartinHan的小站

博客:hanhan12312的專欄

知乎:MartinHan01)

相關文章
相關標籤/搜索