版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
ApkTool 简介
apktool 用于对 Android 应用(.apk 文件)进行 反编译 和 重打包(回编译)。它可以将 APK 中的资源文件、AndroidManifest.xml 以及 DEX 代码(转换为 smali 代码)提取出来并可编辑,便于进行逆向分析、修改资源或注入逻辑等操作。
使用 ApkTool 反编译和回编译 APK
从官网下载 apktool 的 jar 文件到本地,需要 Java 环境(JDK 8+)。
1. 反编译 APK
apktool d myapp.apk
# 或指定输出目录
apktool d myapp.apk -o myapp_decoded
会得到如下结构:
myapp_decoded/
├── AndroidManifest.xml
├── smali/ <-- 反编译后的 Java 代码(smali)
├── res/ <-- 资源文件
├── assets/
└── original/ <-- 原始META信息
你可以:
-
编辑 res/layout 里的 XML 修改 UI;
-
修改 AndroidManifest.xml 中的权限或组件;
-
修改 smali 文件插入代码(如打印 log 或 hook 某函数);
2. 回编译 APK
apktool b myapp_decoded -o my_new.apk
uber-apk-signer(签名工具)
uber-apk-signer 是一个用于批量签名、对齐(zipalign)并自动验证 Android APK 的命令行工具,支持 Android 签名方案 v1、v2、v3 和 v4。它可以使用内置的 debug keystore 进行便捷调试签名,也支持使用自定义的 release 证书,适合自动化构建与测试流程。
基本用法(签名一个或多个 APK)
java -jar uber-apk-signer-<version>.jar \
--apks "<apk路径或目录>" \
--ks "<keystore路径>" \
--ksAlias "<别名>" \
--ksPass "<keystore密码>" \
--ksKeyPass "<key密码>" \
--out "<输出目录>" \
--overwrite
参数说明:
参数 | 说明 |
---|---|
–apks | 要签名的 APK 或包含 APK 的目录(支持多个路径,空格分隔)。 |
–ks | keystore 文件路径(支持多个,用 index=xxx.jks 格式)。 |
–ksAlias | keystore 中的 alias(必须与 keystore 对应)。 |
–ksPass | keystore 的密码。 |
–ksKeyPass | key 的密码。 |
–out | 输出签名后 APK 的目录。 |
–overwrite | 是否覆盖原始 APK。 |
–debug / --verbose | 显示更多调试信息。 |
–skipZipAlign | 跳过 Zipalign(一般不建议)。 |
示例:签名单个 APK
java -jar uber-apk-signer-1.3.0.jar --apks "D:\Python\anti-app\app\Ksfndkd\app-release\dist\app-release.apk" --ks "D:\Projects\AndroidExample\cyrus.jks" --ksAlias "cyrus_studio" --ksPass "cyrus_studio" --ksKeyPass "cyrus_studio" --out "D:\Python\anti-app\app\Ksfndkd\app-release\dist"
输出文件将位于 D:\Python\anti-app\app\Ksfndkd\app-release\dist\app-release-aligned-signed.apk
其他常用功能:
功能 | 命令参数 |
---|---|
仅验证签名 | –onlyVerify |
使用 debug 签名 | 不填 --ks,将使用内置 debug keystore |
dry run 模式 | –dryRun 不真实执行的情况下,查看会处理哪些 APK |
忽略旧签名重签 | –allowResign |
指定 zipalign 路径 | –zipAlignPath <path> |
apk助手脚本(apk_helper.bat)
下面是一个 apk助手脚本(apk_helper.bat),支持以下功能:
-
反编译 APK
-
回编译 APK
-
签名 APK
-
安装 APK
使用前准备:
1、下载 apktool.jar 和 uber-apk-signer.jar 放在脚本同级目录下
2、如何需要用到 签名APK 功能,需要在脚本中增加 keystore 配置
:: keystore 配置
set JKS_PATH=D:\Projects\AndroidExample\cyrus.jks
set KEY_ALIAS=cyrus_studio
set STORE_PASS=cyrus_studio
set KEY_PASS=cyrus_studio
代码实现如下:
@echo off
setlocal enabledelayedexpansion
REM ==== 配置开始 ====
:: apktool 路径
set APKTOOL_JAR=apktool_2.12.0.jar
:: uber-apk-signer 路径
set SIGNER_JAR=uber-apk-signer-1.3.0.jar
:: keystore 配置
set JKS_PATH=D:\Projects\AndroidExample\cyrus.jks
set KEY_ALIAS=cyrus_studio
set STORE_PASS=cyrus_studio
set KEY_PASS=cyrus_studio
REM ==== 配置结束 ====
:MENU
echo ========================================
echo APK 助手 - 请选择功能
echo ========================================
echo 1. 反编译 APK
echo 2. 回编译 APK
echo 3. 签名 APK
echo 4. 安装 APK
echo 0. 退出
echo ========================================
set /p choice=请输入选项(0-4):
if "%choice%"=="1" goto DECOMPILE
if "%choice%"=="2" goto REBUILD
if "%choice%"=="3" goto SIGNAPK
if "%choice%"=="4" goto INSTALLAPK
if "%choice%"=="0" exit
goto MENU
:DECOMPILE
echo.
set /p apk_path=请输入 APK 路径(可拖入):
set "apk_path=%apk_path:"=%"
for %%F in ("%apk_path%") do set "apk_name=%%~nF" & set "apk_dir=%%~dpF"
set out_dir=%apk_dir%%apk_name%
echo 正在反编译到:%out_dir%
java -jar "%APKTOOL_JAR%" d -f "%apk_path%" -o "%out_dir%"
echo 反编译完成!
goto MENU
:REBUILD
echo.
set /p project_dir=请输入 APK 反编译目录(可拖入):
set "project_dir=%project_dir:"=%"
java -jar "%APKTOOL_JAR%" b "%project_dir%"
echo 回编译完成!输出路径:%project_dir%\dist\
goto MENU
:SIGNAPK
echo.
set /p apk_path=请输入待签名 APK 路径(可拖入):
set "apk_path=%apk_path:"=%"
:: 检查配置完整性
if not exist "%SIGNER_JAR%" (
echo [错误] uber-apk-signer.jar 未找到,请检查 SIGNER_JAR 路径配置!
goto MENU
)
if not exist "%JKS_PATH%" (
echo [错误] JKS 文件不存在,请配置 JKS_PATH。
goto MENU
)
:: 解析文件路径信息
for %%F in ("%apk_path%") do (
set "apk_name=%%~nF"
set "apk_dir=%%~dpF"
)
echo 开始签名...
java -jar "%SIGNER_JAR%" --apks "%apk_path%" --ks "%JKS_PATH%" --ksAlias "%KEY_ALIAS%" --ksKeyPass "%KEY_PASS%" --ksPass "%STORE_PASS%" --out %apk_dir%
:: 检查输出并重命名
set signed_apk=%apk_dir%%apk_name%-aligned-signed.apk
if exist "%signed_apk%" (
echo 签名完成:%signed_apk%
) else (
echo [错误] 签名失败,未生成预期的文件:%signed_apk%
)
goto MENU
:INSTALLAPK
echo.
set /p apk_path=请输入待安装的 APK 路径(可拖入):
set "apk_path=%apk_path:"=%"
if not exist "%apk_path%" (
echo [错误] APK 文件不存在,请检查路径!
goto MENU
)
echo 正在通过 adb 安装 APK:%apk_path%
adb install -r "%apk_path%"
if %ERRORLEVEL% EQU 0 (
echo 安装成功!
) else (
echo [错误] 安装失败,请确保设备已连接,并启用 USB 调试。
)
goto MENU
效果如下: