当前位置: 首页 > news >正文

APK重打包流程

一、说在前面的话。

在本篇文章中,我们将深入讲解如何对APK进行重打包

  • 如何对APK进行反编译与重打包
  • 如何修改包名
  • 如何在Smali文件中插入自定义逻辑

🛠️ 所需工具

在操作过程中,将使用以下工具:

1、Apktool

用于对APK进行反编译(decode)与重新打包(build)

下载地址:https://github.com/iBotPeaches/Apktool/releases

2、 Zipalign 与 Apksigner

这两个工具是Android SDK中的构建工具,主要作用如下:

  • zipalign :对 APK 进行对齐优化,提高运行效率。
  • apksigner:对 APK 进行签名,使其可安装到 Android 设备上。

它们通常位于以下目录中:

$ANDROID_HOME/build-tools/<version>/

✅ 建议:选择与项目compileSdkVersion接近的build-tools版本,避免兼容性问题,一般不建议使用高于当前的compileSdkVersion的版本

二、进入正题

1、反编译APK

介绍如何使用apktool对APK进行反编译,获取Smali和资源文件。

apktool d. 原始.apk -o 接包目录

说明:

  • d 表示decode(反编译)
  • -o 后面跟输出目录

实例代码:

java -jar apktool_2.12.0.jar d zy.apk -o  zy

2、修改包名

✅ A.修改AndroidManifest.xmlpackage属性
在上文的目录中,zy/AndroidManifest.xml中:

<manifest package="com.old.package.name" ...

修改为:

<manifest package="com.new.package.name" ...

✅ B.重命名Smali目录结构
假如原来是:

zy/smali/com/old/package/name/

你需要将它移动为:

zy/smali/com/new/package/name/

你可以用下面的命令辅助:

cd your_app_decoded/smali
mkdir -p com/new/package/name
mv com/old/package/name/* com/new/package/name/
rm -r com/old

✅ C.替换smali文件中的包名
使用sed或者脚本所有的.smali文件中的旧包名改为新的:

find . -type f -name "*.smali" -exec sed -i '' 's/com\/old\/package\/name/com\/new\/package\/name/g' {} +

注意:smali文件中的包名是用 / 分割的

如果遇到分包的就会比较麻烦了,如下图:

在这里插入图片描述
就像这样的,上面的命令就有点吃力了,所以最好采用脚本的形式

下面是一个Python 脚本,可以自动完成上述的任务:
✅它的主要功能:

  • 遍历所有 smali_classes 目录
  • 重命名包名路径
  • 替换所有 .smali 文件中旧包名为新包名
  • 替换所有 res/ 和 AndroidManifest.xml 中的旧包名

Python 脚本:rename_package.py

import os
import shutil# 配置旧包名和新包名
old_package = "com.location.gps"
new_package = "com.location.gzk"# 转换为路径形式
old_path = old_package.replace('.', '/')
new_path = new_package.replace('.', '/')# 要处理的文件夹前缀
smali_prefixes = [d for d in os.listdir() if d.startswith("smali_classes") or d == "smali"]def rename_package_dirs():for smali_dir in smali_prefixes:old_dir = os.path.join(smali_dir, old_path)new_dir = os.path.join(smali_dir, new_path)if os.path.exists(old_dir):os.makedirs(os.path.dirname(new_dir), exist_ok=True)print(f"[+] 移动目录: {old_dir} -> {new_dir}")shutil.move(old_dir, new_dir)# 清除空目录(防止重复打包问题)for smali_dir in smali_prefixes:for root, dirs, files in os.walk(smali_dir, topdown=False):if not os.listdir(root):os.rmdir(root)def replace_in_files(root_dir, file_exts, old_str, new_str):for root, dirs, files in os.walk(root_dir):for file in files:if any(file.endswith(ext) for ext in file_exts):file_path = os.path.join(root, file)try:with open(file_path, 'r', encoding='utf-8') as f:content = f.read()new_content = content.replace(old_str, new_str)if new_content != content:with open(file_path, 'w', encoding='utf-8') as f:f.write(new_content)print(f"[~] 替换文件: {file_path}")except Exception as e:print(f"[!] 跳过文件(编码问题): {file_path}")def main():print(">>> 开始修改包名 ...")# 1. 移动包名路径rename_package_dirs()# 2. 替换 smali 中的包名replace_in_files(".", [".smali"], "L" + old_path.replace('/', '/') + "/", "L" + new_path.replace('/', '/') + "/")# 3. 替换 Manifest 和 XML 中的包名replace_in_files(".", [".xml"], old_package, new_package)# 4. 替换 Manifest 文件中的主包名manifest_path = "AndroidManifest.xml"if os.path.exists(manifest_path):replace_in_files(".", ["AndroidManifest.xml"], old_package, new_package)print("✅ 包名修改完成!")if __name__ == "__main__":main()

把它放到apktools解包的目录里(例如 AndroidManifest.xmlsmali_classes 所在目录)
在命令行运行:

python3 rename_package.py

3、在Smali文件中插入自定义逻辑

例如,你要在Application.onCreate()插入代码:

1、找到Application类

在AndroidManifest.xml中找到:

<application android:name="com.xxx.MyApp" ...>

对应的smali文件是:

smali/com/xxx/MyApp.smali
2、编辑.smali

找到onCreate方法(如何没有找到就添加)

.method public onCreate()V.locals 1invoke-super {p0}, Landroid/app/Application;->onCreate()V# 自定义代码开始const-string v0, "Hello Custom Code"invoke-static {v0}, Landroid/util/Log;->d(Ljava/lang/String;)I# 自定义代码结束return-void
.end method

你可以调用任意Java中支持的方法,但要注意调用路径和参数签名是否正确。

还有一点:如果新增了变量一定要记得修改locals的值,否则会报异常错误的。
.locals N 声明该方法最多用到了N个本地寄存器


4、重新打包APK

还是用到上文提到的:apktool

java -jar apktool_2.12.0.jar  b zy -o new_app.apk

5、对 APK 签名

先 zipalign(必须):

$ANDROID_HOME/build-tools/<version>/zipalign -p -f 4 new_app.apk output.apk

需要注意的地方: 最好加上-p,不然很容易出现:

Serving...
Failure [INSTALL_FAILED_INTERNAL_ERROR: Failed to extract native libraries, res=-110]
Performing Streamed Install
adb: failed to install /Volumes/SD/soft/reapk/my_signed.apk: Failure [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2].

然后签名(使用 apksigner):

 $ANDROID_HOME/build-tools/<version>/apksigner sign \--ks xx.jks \--ks-key-alias xx \--ks-pass pass:xx \--key-pass pass:xx \--out my_signed.apk \output.apk

如果你没有签名文件,可以先创建:

keytool -genkey -v -keystore xx.jks -alias alias_name -xx RSA -keysize 2048 -validity 10000
6、测试安装
adb install -r signed.apk

至此 基础的重打包的流程已完结

http://www.dtcms.com/a/304272.html

相关文章:

  • K8s集群两者不同的对外暴露服务的方式
  • 如何迁移gitlab到另一台服务器
  • Makefile 快速入门指南
  • LangChain和LangGraph 里面的 `create_react_agent`有什么不同
  • 机器学习—逻辑回归
  • VitePress学习-自定义主题
  • 使用 Django REST Framework 构建强大的 API
  • 在依赖关系正确的情况下,执行 mvn install 提示找不到软件包
  • Python Day17 面向对象 及例题分析
  • Apache Ignite 的分布式队列(IgniteQueue)和分布式集合(IgniteSet)的介绍
  • 集成电路学习:什么是Wi-Fi无线保真度
  • 机器学习sklearn:泰坦尼克幸存预测(决策树、网格搜索找最佳参数)
  • 永磁同步电机无速度算法--静态补偿电压模型Harnefors观测器
  • 泛微E9 引入高版本spring导致webservices接口报错
  • vue2 使用liveplayer加载视频
  • 【初识数据结构】CS61B中的基数排序
  • 彻底清理ArcGIS 10.2残留的步骤
  • 【自制组件库】从零到一实现属于自己的 Vue3 组件库!!!
  • 堆的理论知识
  • uniapp如何封装uni.request 全局使用
  • qt webengine播放视频
  • VS+Qt中使用QCustomPlot绘制曲线标签(附源码)
  • 002 TrafficGenerator 类详解
  • FCN语义分割算法原理与实战
  • 八股训练营 40 天心得:一场结束,也是一场新的开始
  • 力扣热题100--------240.搜索二维矩阵
  • LeetCode热题100——46. 全排列
  • 研电赛-基于GD32的纳型无人机AI追踪系统1
  • vue相关的拖拉拽官网
  • minio安装 windows系统