Apktool 2.9.3 + dex2jar 2.1 组合实战:Mac 环境反编译与 Smali 代码修改

Apktool 2.9.3 + dex2jar 2.1 组合实战:Mac 环境反编译与 Smali 代码修改

Mac环境下的Android逆向工程:Apktool与dex2jar深度实战指南

1. 逆向工程工具链概述

在Mac环境下进行Android应用逆向分析,需要一套完整的工具链配合使用。这套工具链主要包括三个核心组件:

  • Apktool:负责反编译APK文件,提取资源文件(如图片、XML布局文件等)并将Dalvik字节码转换为可读的Smali代码
  • dex2jar:将APK中的classes.dex文件转换为Java标准的JAR文件
  • JD-GUI:可视化查看JAR文件中的Java源代码

这三个工具的组合使用,可以让我们从APK文件中提取出几乎所有的原始资源,并尽可能还原出可读的源代码。

提示:虽然这些工具能还原大部分代码,但经过混淆的代码仍然难以完全恢复原始结构和命名。

2. 环境准备与工具安装

2.1 安装Java开发环境

逆向工程工具大多依赖Java环境,首先需要确保系统已安装JDK:

brew install --cask adoptopenjdk

验证安装:

java -version

2.2 安装Apktool

通过Homebrew安装最新版Apktool:

brew install apktool

验证安装:

apktool -version

2.3 安装dex2jar

从GitHub下载最新版dex2jar:

wget https://github.com/pxb1988/dex2jar/releases/download/2.1/dex-tools-2.1.zip unzip dex-tools-2.1.zip -d dex2jar chmod +x dex2jar/*.sh

2.4 安装JD-GUI

下载并安装JD-GUI:

brew install --cask jd-gui

3. 完整逆向流程实战

3.1 反编译APK资源文件

使用Apktool反编译目标APK:

apktool d target.apk -o output_dir

关键参数说明:

参数说明
-d反编译模式
-o指定输出目录
-s不反编译代码(仅资源)
-r不反编译资源

反编译成功后,output_dir目录结构如下:

output_dir/ ├── AndroidManifest.xml ├── apktool.yml ├── original/ ├── res/ └── smali/

3.2 提取并转换DEX文件

从APK中提取classes.dex文件:

unzip target.apk classes.dex -d temp_dir

使用dex2jar转换为JAR文件:

./dex2jar/d2j-dex2jar.sh temp_dir/classes.dex -o output.jar

3.3 查看Java源代码

使用JD-GUI打开生成的output.jar文件:

open -a "JD-GUI" output.jar

4. Smali代码修改与重打包

4.1 理解Smali语法基础

Smali是Dalvik虚拟机的汇编语言,基本结构示例:

.class public Lcom/example/Test; .super Ljava/lang/Object; .source "Test.java" # 实例字段 .field private count:I # 直接方法 .method public constructor <init>()V .registers 1 .prologue .line 3 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method

4.2 常见修改场景

  1. 绕过简单验证
.method public static isPremium()Z .registers 1 const/4 v0, 0x0 # 原始值 # 修改为 const/4 v0, 0x1 # 始终返回true return v0 .end method
  1. 修改API端点
const-string v0, "http://original.api.com" # 修改为 const-string v0, "http://your.proxy.com"

4.3 重打包APK

修改完成后,使用Apktool重新打包:

apktool b output_dir -o modified.apk

4.4 签名APK

生成签名密钥:

keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias

使用jarsigner签名:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.jks modified.apk my-alias

优化APK:

zipalign -v 4 modified.apk final.apk

5. 高级技巧与问题解决

5.1 处理多DEX文件

现代APK通常包含多个DEX文件,处理流程:

# 提取所有DEX unzip target.apk "classes*.dex" -d temp_dir # 批量转换 for dex in temp_dir/classes*.dex; do ./dex2jar/d2j-dex2jar.sh "$dex" -o "${dex%.*}.jar" done

5.2 Android 12+导出属性问题

针对Android 12+的导出属性要求,修改AndroidManifest.xml:

<activity android:name=".TargetActivity" android:exported="true"> <!-- 明确声明导出属性 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> </intent-filter> </activity>

5.3 自动化脚本示例

完整流程自动化脚本:

#!/bin/bash APK=$1 OUTPUT_DIR=${APK%.*} # 反编译资源 apktool d $APK -o $OUTPUT_DIR # 提取并转换DEX unzip $APK "classes*.dex" -d $OUTPUT_DIR/dex for dex in $OUTPUT_DIR/dex/classes*.dex; do ./dex2jar/d2j-dex2jar.sh "$dex" -o "${dex%.*}.jar" done # 自动打开JD-GUI open -a "JD-GUI" $OUTPUT_DIR/dex/classes*.jar echo "反编译完成,输出目录: $OUTPUT_DIR"

6. 逆向工程中的注意事项

  1. 法律风险:仅对拥有合法权限的应用进行逆向分析
  2. 代码混淆:面对Proguard混淆时,需要耐心分析关键逻辑
  3. 完整性检查:某些应用会校验自身完整性,修改后可能导致崩溃
  4. 多版本适配:不同Android版本的核心库可能有差异

在实际项目中,逆向工程往往需要结合静态分析和动态调试才能取得最佳效果。掌握这些工具的使用只是第一步,真正的挑战在于理解业务逻辑和找到关键代码位置。