手把手教你改造 AAR:解包、注入逻辑、重打包,一条龙玩转第三方 SDK!

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

一、什么是 AAR 文件?

AAR 文件(Android Archive)是 Android Studio 用来打包 Android Library(库模块) 的一种压缩文件格式,扩展名是 .aar,类似于 Java 的 .jar 文件,但功能更丰富,用于复用 UI 组件、资源和代码。

AAR 文件结构(解压后)

your-lib.aar
├── AndroidManifest.xml       # 库模块的清单文件
├── classes.jar               # 编译后的 Java/Kotlin 类文件(字节码)
├── res/                      # 资源目录(layout、drawable、values 等)
├── R.txt                     # 编译生成的 R 类符号文件
├── assets/                   # assets 目录中的内容
├── libs/                     # 依赖的 .jar 库
├── jni/                      # native 库(.so 文件)
├── proguard.txt              # 混淆配置文件
├── public.txt                # 声明哪些资源是公开的
└── META-INF/                 # 元数据(如 aar metadata、许可证等)

使用 AAR 的场景举例:

  • 引入第三方 SDK(如广告、支付库)

  • 组件化开发中将公共模块打成 AAR

  • 在没有上传 Maven 仓库的情况下本地集成依赖

二、如何解包 AAR 文件

.aar 实质上是一个 ZIP 压缩包,可以使用 Python 标准库中的 zipfile 和 os 模块实现对 .aar 文件的解包。

import os
import zipfile

def unpack_aar(aar_path, output_dir=None):
    # 1. 校验输入文件是否是合法的 .aar 文件
    if not os.path.isfile(aar_path) or not aar_path.endswith(".aar"):
        print("❌ 输入文件不是有效的 .aar 文件")
        return

    # 2. 默认输出路径为同名目录
    if output_dir is None:
        base_name = os.path.splitext(os.path.basename(aar_path))[0]
        output_dir = os.path.join(os.path.dirname(aar_path), base_name)

    # 3. 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    # 4. 使用 zipfile 解压 .aar 文件
    with zipfile.ZipFile(aar_path, "r") as zip_ref:
        zip_ref.extractall(output_dir)
        print(f"✅ 已解包到:{output_dir}")

通过 unpack_aar() 解包后,就可以进一步操作 .aar 中的内容,比如提取 classes.jar 并修改 jar 中的 java 代码。

(anti-app) PS D:\Python\anti-app\aar> python aarkit.py unpack "D:\Python\anti-app\app\Ksfndkd\sanfang-jiagu-0_0_1.aar"
✅ 已解包到:D:\Python\anti-app\app\Ksfndkd\sanfang-jiagu-0_0_1

word/media/image1.png

三、如何重打包 AAR 文件

使用 zipfile 将解包目录重新打包成一个 .aar 文件

import os
import zipfile
from datetime import datetime

def pack_aar(input_dir, output_aar=None):
    # 如果输入目录不存在,打印错误信息并退出
    if not os.path.isdir(input_dir):
        print("❌ 输入目录不存在")
        return

    # 如果未指定输出 aar 文件路径,则自动生成一个带时间戳的文件名
    if output_aar is None:
        base_name = os.path.basename(os.path.normpath(input_dir))  # 获取目录名
        timestamp = datetime.now().strftime("%Y%m%d%H%M")           # 当前时间戳
        # 输出路径为:输入目录的上一级 + 自动生成的文件名
        output_aar = os.path.join(os.path.dirname(input_dir), f"{base_name}-{timestamp}.aar")

    # 创建一个压缩文件(.aar 格式),使用 ZIP_DEFLATED 压缩方式
    with zipfile.ZipFile(output_aar, "w", zipfile.ZIP_DEFLATED) as zipf:
        # 遍历输入目录及其子目录中的所有文件
        for root, _, files in os.walk(input_dir):
            for file in files:
                full_path = os.path.join(root, file)                      # 文件的完整路径
                arcname = os.path.relpath(full_path, input_dir)          # 计算相对路径(作为 zip 中的路径)
                zipf.write(full_path, arcname)                           # 写入压缩包

    print(f"✅ 已打包为:{output_aar}")

四、AAR 修改实战:注入自定义逻辑

需求:修改 jar 中指定的类 Bhubscfh 的静态代码块的 xjhbp.classescxclcy(120); 调用后插入下面的代码加载自定义的 Hook 库,实现 Hook 指定方法并修改返回值。

System.loadLibrary("my_hook");

将 classes.jar 转为 smali 代码

Jar → Smali 转换流程:

1、JAR → DEX

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值