发布时间:2026/6/30 7:00:28
Frida动态Hook实战:逆向分析Android小说App的AES加密接口
1. 项目概述与核心价值最近在分析一个小说App的数据接口时遇到了一个典型的场景网络请求的正文和关键参数都被AES加密了返回的数据也是一串看不懂的密文。对于想研究其内容更新机制、或者做一些合规范围内的数据分析来说这无疑是一道屏障。直接去逆向算法如果App做了混淆或加固那将是一场持久战。这时候动态分析工具的优势就体现出来了。我选择使用Frida这个“瑞士军刀”进行Hook直接拦截App运行时的加密函数调用拿到明文的输入和输出从而绕过复杂的静态分析。这个项目就是一次完整的实战记录我会分享从环境搭建、定位关键函数到编写稳定Hook脚本的全过程并提供可直接复用的脚本。无论你是移动安全研究员、爬虫工程师还是对Android逆向感兴趣的开发者这套方法都能为你提供一个清晰、高效的解题思路。2. 环境准备与工具选型解析工欲善其事必先利其器。一个稳定、高效的逆向分析环境是成功的第一步。这里的选择没有绝对的对错只有是否适合当前场景。2.1 核心工具为什么是Frida在众多动态插桩工具如Xposed、Substrate中我首选Frida。原因很简单跨平台、脚本化、对Java和Native层支持都极好。Xposed需要修改系统或安装特定框架重启频繁而Frida以注入模式运行大部分操作无需重启设备或App极大提升了调试效率。你可以用Python或JavaScript快速编写逻辑动态地拦截、修改函数行为这对于快速探明加密逻辑来说再合适不过。安装要点Python端pip install frida-tools。建议使用虚拟环境避免包冲突。设备端Frida Server这是核心。需要根据你的Android设备或模拟器的CPU架构通常是arm或x86_64下载对应的frida-server二进制文件。模拟器推荐我使用雷电模拟器9Android 9它稳定且兼容性好CPU架构通常为x86_64。在逆向初期模拟器比真机更方便进行快照、重置等操作。操作将下载的frida-server-xx.x.x-android-x86_64推送到设备/data/local/tmp/目录赋予可执行权限chmod 755并以root权限运行。确保电脑能adb shell进入设备。注意有些App会检测Frida的运行环境。如果遇到闪退可能需要尝试Frida的隐身模式、修改Frida Server文件名、或使用其他反反调试技巧这属于更进阶的对抗本次基础实战暂不展开。2.2 辅助工具定位关键代码Frida负责“动手”但我们得先知道“对谁动手”。这就需要静态分析工具来缩小范围。APK分析工具Jadx-GUI / GDA用于将目标小说App的APK文件反编译成Java/Kotlin代码。我们的首要任务就是在这里搜索与加密相关的关键词如AES、Cipher、encrypt、decrypt以及常见的加密库类名。网络抓包工具Charles / Fiddler / HTTP Toolkit用于捕获App的网络请求。我们的目标是找到那个被加密的请求观察其URL、Header以及最重要的——那一长串看似随机的请求体密文。同时也要留意响应数据很可能也是加密的。抓包工具能帮我们确认加解密的发生位置在请求发出前/响应解析后。工具链协作流程抓包找到加密接口 - 反编译APK搜索加密特征 - 使用Frida Hook可疑函数进行验证 - 最终定位到目标函数。3. 逆向分析与关键函数定位实战理论说再多不如一次实战。假设我们的目标小说App在获取章节内容时发送了一个POST请求其body是一个dataxxxxxx的密文响应也是密文。3.1 静态搜索与初步研判用Jadx-GUI打开APK进行全局搜索Navigate - Text Search。搜索“AES”可能会直接找到使用AES/CBC/PKCS5Padding等字符串的代码这能快速定位加密类。搜索“Cipher”Android标准的加密操作主要通过javax.crypto.Cipher类完成。搜索Cipher.getInstance是黄金线索。搜索“encrypt”关注自定义的EncryptUtil、SecurityHelper等工具类。假设我们幸运地找到了一个名为com.xxx.novel.security.AESUtils的类里面有一个encrypt方法和一个decrypt方法。代码可能如下public class AESUtils { private static final String TRANSFORMATION AES/CBC/PKCS5Padding; private static final String KEY 一个16/24/32字节的字符串; public static String encrypt(String plainText) { // ... 初始化Cipher进行加密最后可能Base64编码输出 } public static String decrypt(String cipherText) { // ... Base64解码初始化Cipher进行解密 } }这看起来就是我们的目标。但别急实战中往往没这么直接。3.2 动态验证与精确打击静态代码可能被混淆类名、方法名变成a,b,c或者加密逻辑分散在多个地方。这时就需要Frida动态验证。首先写一个简单的Frida脚本尝试Hook我们怀疑的类和方法。即使类名被混淆只要方法逻辑是加密其参数和返回值特征传入字符串返回字符串是明显的。基础Hook脚本框架Java.perform(function () { // 尝试定位目标类如果被混淆可能需要遍历或通过特征查找 var AESUtils Java.use(com.xxx.novel.security.AESUtils); // Hook encrypt方法 AESUtils.encrypt.overload(java.lang.String).implementation function (plainText) { console.log(\n[AESUtils.encrypt] 被调用); console.log(明文输入: plainText); // 调用原方法获取加密结果 var result this.encrypt(plainText); console.log(加密结果: result); // 将结果打印到日志并可以存储下来供后续分析 send({type: encrypt, input: plainText, output: result}); return result; }; // Hook decrypt方法 AESUtils.decrypt.overload(java.lang.String).implementation function (cipherText) { console.log(\n[AESUtils.decrypt] 被调用); console.log(密文输入: cipherText); var result this.decrypt(cipherText); console.log(解密结果: result); send({type: decrypt, input: cipherText, output: result}); return result; }; });运行这个脚本frida -U -f com.xxx.novel -l hook.js --no-pause然后在App内触发章节加载。如果控制台打印出了我们抓包看到的密文以及对应的明文可能是JSON格式的请求参数那么恭喜目标锁定成功实操心得如果直接Hook不到可能是类加载时机问题。可以尝试使用Java.choose()在堆上枚举已存在的实例或者Hook更底层的Cipher.doFinal()方法。Cipher.doFinal是加密解密的最终执行者几乎所有的Java层加密都会调用到它这是一个非常可靠的“锚点”。4. 完整Frida Hook脚本编写与解析一旦确认了目标函数我们就可以编写一个功能更完整、更健壮的Hook脚本。这个脚本不仅要打印日志还要能处理多种情况并方便我们导出数据。4.1 脚本结构设计一个完整的Hook脚本应该包含以下部分目标类与方法声明清晰定义要Hook的类和方法签名。Hook实现逻辑在implementation中打印输入输出、记录调用栈帮助理解函数调用链路、甚至修改参数或返回值用于测试。数据输出模块将拦截到的关键数据通过send()发送到Python端方便保存到文件或数据库。错误处理与兼容性考虑方法重载、混淆导致的多个同名方法等情况。4.2 实战脚本示例与逐行解读以下是一个针对可能被混淆的AES工具类的增强版Hook脚本。我们假设找到了加密方法但类名是a.a方法名是b。Java.perform(function () { console.log([*] 开始Hook小说App加密函数...); // 目标类可能已被混淆 var TargetClass Java.use(a.a); // 假设加密方法是 b接收一个String参数返回String // 使用overload明确指定参数类型避免混淆 TargetClass.b.overload(java.lang.String).implementation function (inputStr) { console.log(\n AES加密函数被调用 ); // 1. 打印输入 console.log([输入参数], inputStr); // 2. 打印调用栈帮助定位是谁调用了加密 // console.log(Java.use(android.util.Log).getStackTraceString(Java.use(java.lang.Exception).$new())); // 3. 调用原方法获取加密结果 var encryptedResult this.b(inputStr); console.log([加密输出], encryptedResult); // 4. 将数据发送到Python端进行处理或存储 send({ event: encrypt, timestamp: new Date().toISOString(), plain_text: inputStr, cipher_text: encryptedResult }); // 5. 返回原结果不影响App正常流程 return encryptedResult; }; // 同理Hook解密方法如果有的话方法名可能是c或其他 // TargetClass.c.overload(java.lang.String).implementation function (inputStr) {...} console.log([*] Hook注入完成等待触发...); });Python控制端脚本 Frida脚本通常通过Python加载和执行同时我们可以编写Python代码来接收脚本send()过来的数据。import frida import json import sys def on_message(message, data): 处理从Frida脚本发送过来的消息 if message[type] send: payload message[payload] print(f[收到数据] 事件: {payload.get(event)}) print(f明文: {payload.get(plain_text)}) print(f密文: {payload.get(cipher_text)}) print(- * 50) # 可以选择将数据保存到文件 with open(hook_data.log, a, encodingutf-8) as f: f.write(json.dumps(payload, ensure_asciiFalse) \n) elif message[type] error: print(f[脚本错误] {message[stack]}) def main(): # 连接设备 device frida.get_usb_device() # 附加到目标App进程假设App已启动 # 方式一附加到已运行的进程 # pid device.spawn([com.xxx.novel]) # 如果需要重启App # session device.attach(pid) # device.resume(pid) # 方式二更常用附加到已运行的进程 session device.attach(com.xxx.novel) # 加载Hook脚本 with open(hook_aes.js, r, encodingutf-8) as f: js_code f.read() script session.create_script(js_code) script.on(message, on_message) # 设置消息回调 script.load() print([*] 脚本已加载正在监听...) # 保持脚本运行 sys.stdin.read() if __name__ __main__: main()运行这个Python脚本然后在小说App里操作你就能在控制台实时看到加密前后的数据并且所有记录都会保存到hook_data.log文件中。5. 加密逻辑分析与算法还原通过Frida Hook我们已经拿到了大量的“明文-密文”对。接下来目标是从这些数据中逆向出完整的AES加密算法包括模式CBC/ECB等、填充PKCS5/PKCS7等、密钥Key和初始化向量IV。5.1 分析Hook数据查看日志文件你可能会发现明文{bookId:12345,chapterId:678,timestamp:1648886400}密文U2FsdGVkX1oH5Q...一串Base64编码的字符串关键观察点密文长度AES是块加密明文不是16字节倍数时会填充。观察不同长度明文产生的密文长度变化可以推测块大小和模式。密文一致性使用相同的明文多次请求密文是否相同如果相同可能是ECB模式不推荐不安全或者密钥和IV固定。如果不同极可能是CBC模式且IV是随机生成的。IV通常会随着密文一起传输有时在密文头部有时在另一个参数里。5.2 深入静态代码带着动态获取的信息再回头仔细看反编译的AESUtils类。找Key和IV它们可能硬编码在代码里字符串常量也可能来自服务器下发、设备信息计算等。搜索SecretKeySpec和IvParameterSpec的初始化代码。看模式字符串Cipher.getInstance(“AES/...”)中的字符串直接指明了模式和填充方式。CBC需要IVECB不需要。看编码方式加密后的字节数组通常会用Base64或Hex编码成字符串进行传输。算法还原示例 假设我们从代码中分析出模式AES/CBC/PKCS5Padding密钥Key“this_is_a_16byte_key”(16字节)初始向量IV“1234567890123456”(16字节)那么用Python还原加密算法就非常简单了from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 def encrypt(plaintext): key bthis_is_a_16byte_key # 16字节 iv b1234567890123456 # 16字节 cipher AES.new(key, AES.MODE_CBC, iv) # 明文需要编码为bytes并进行PKCS5/PKCS7填充 ciphertext cipher.encrypt(pad(plaintext.encode(utf-8), AES.block_size)) # 结果通常Base64编码 return base64.b64encode(ciphertext).decode(utf-8) # 测试 plain_json {bookId:12345,chapterId:678} encrypted_data encrypt(plain_json) print(f加密结果: {encrypted_data})用这个Python函数加密得到的字符串应该和Frida Hook下来的密文一致如果IV是固定的。如果不一致检查IV是否是动态的、密钥是否正确、或者是否有其他额外的处理步骤如对明文先做MD5哈希等。6. 常见问题排查与避坑指南在实际操作中你几乎一定会遇到下面这些问题。这里记录了我的踩坑实录和解决方案。6.1 Frida连接与注入失败问题frida-ps -U看不到进程或者attach失败。排查设备连接确保adb devices能看到设备并且Frida Server已在设备上运行ps | grep frida。端口冲突Frida默认使用27042端口。确保没有其他程序占用。版本不匹配电脑端的frida和frida-tools版本应与设备端的frida-server版本尽量一致。使用frida --version和adb shell /data/local/tmp/frida-server --version查看。模拟器设置雷电模拟器需要开启root权限。在设置-其他设置中开启。6.2 Hook不到目标函数问题脚本注入成功但控制台没有打印预期的日志。排查类名/方法名错误混淆后的类名可能不固定。尝试使用Java.enumerateLoadedClasses()在运行时枚举所有已加载的类搜索包含AES、Cipher、encrypt等关键词的类。方法重载使用overload正确指定参数类型。用目标类.方法名.overloads查看所有重载。调用时机脚本注入时目标类可能还未被加载。可以Hookjava.lang.ClassLoader的loadClass方法在类加载时再执行Hook逻辑。最保险的方案直接Hookjavax.crypto.Cipher类的getInstance、init、doFinal方法。这是加密操作的必经之路虽然信息更底层但绝对可靠。6.3 App检测到Frida导致崩溃问题一启动App或注入脚本后App立刻闪退。对策重命名Frida Server将设备端的frida-server文件改名为其他名字如fs并相应修改连接脚本。使用非常规端口启动Frida Server时指定端口./fs -l 0.0.0.0:8080 电脑连接时使用frida -H 设备IP:8080。使用隐藏技术Frida提供了一些反检测选项如--enable-sandbox。社区也有如frida-unpack等工具可以尝试。终极方案如果只是需要数据可以考虑在非Root环境下使用objection基于Frida的命令行工具的android hooking watch class等命令或者使用r0capture等针对非Root的抓包工具但它们的功能和灵活性可能不如直接写脚本。6.4 加密算法复杂不止AES问题Hook到数据后发现密文规律不符合AES或者有多层加密。思路多种算法组合可能是先RSA加密AES密钥再用AES加密数据。需要找到密钥交换的逻辑。自定义加密开发者可能自己实现了XOR、TEA等简单算法或者对标准AES的输出做了二次处理如字节反转、特定位置替换。这时需要仔细分析Hook到的输入输出字节数组寻找规律。借助自动化工具对于已知算法可以使用CyberChef这样的在线工具进行多种解码、解密尝试。对于未知算法需要更深入的逆向分析其汇编或字节码。整个逆向过程就像侦探破案Frida是你的“监控探头”静态分析是你的“案卷调查”两者结合耐心分析总能找到突破口。最后再次强调所有技术都应用于合法合规的学习与研究目的尊重开发者的劳动成果和软件的使用条款。

相关新闻

Cadence Allegro PCB设计进阶:为封装(footprint)精准装配3D模型
2026/6/30 6:00:28

Cadence Allegro PCB设计进阶:为封装(footprint)精准装配3D模型

1. 为什么需要为PCB封装添加3D模型 在传统的PCB设计中,工程师往往只需要关注二维布局和走线,但随着电子产品越来越复杂,机械结构越来越紧凑,单纯的二维设计已经无法满足需求。我记得刚开始做PCB设计时,结构工程师经常抱…

阅读更多
符文世界:龙之荒野上传存档教程
2026/6/30 6:00:28

符文世界:龙之荒野上传存档教程

本教程转载莱卡云游戏服务器的莱卡云:龙之荒野上传存档教程【百度搜索莱卡云开服可搜到】本教程同时也是修改参数教程找本地存档复制这段内容👉【%APPDATA%\..\Local\RSDragonwilds\Saved\SaveGames】使用winR搜索在弹出来的文件夹内就有你所有的存档文件…

阅读更多
大数据转大模型:从问题定位到方案成型
2026/6/30 6:00:28

大数据转大模型:从问题定位到方案成型

聊《大数据转大模型:从问题定位到方案成型》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要本文概述文章目标、核心观点和实践价值。前两周,公司决定把内部沉淀了五年的知识库接入大模型…

阅读更多
谷歌浏览器多开
2026/6/30 17:00:30

谷歌浏览器多开

谷歌浏览器多开 echo off chcp 65001 title Chrome 开发多开(无缓存跨域)start "" "C:\Program Files\Google\Chrome\Application\chrome.exe" --user-data-dir"D:\software\google\Profile1" --no-first-run --no-default-browser-check --allo…

阅读更多
MATLAB实战:用fitdist函数搞定风速与光伏数据的Weibull和Beta分布拟合
2026/6/30 17:00:30

MATLAB实战:用fitdist函数搞定风速与光伏数据的Weibull和Beta分布拟合

MATLAB实战:用fitdist函数搞定风速与光伏数据的Weibull和Beta分布拟合在可再生能源领域,风速和太阳辐照度的概率分布建模是电力系统规划、风机性能评估和光伏出力预测的基础工作。对于工程师和研究人员来说,掌握MATLAB中fitdist函数的实战应用…

阅读更多
flink的CDC功能的设置
2026/6/30 17:00:30

flink的CDC功能的设置

Flink CDC 功能设置 Flink CDC(Change Data Capture)功能用于捕获数据库的变更事件,并将其作为流处理的数据源。以下是常见的设置方法: 添加依赖 在项目的 pom.xml 文件中添加 Flink CDC 连接器的依赖。以 MySQL CDC 为例&…

阅读更多
阿里云PAI-DSW免费额度薅羊毛指南:手把手教你用A10 GPU 30天免费跑通ChatGLM
2026/6/30 17:00:30

阿里云PAI-DSW免费额度薅羊毛指南:手把手教你用A10 GPU 30天免费跑通ChatGLM

阿里云A10 GPU极致性价比实战:30天免费运行ChatGLM全攻略当开源大模型遇上免费云计算资源,会碰撞出怎样的火花?对于预算有限却渴望探索AI前沿技术的开发者而言,阿里云PAI-DSW提供的5000CU免费额度无疑是绝佳的实验平台。但如何将这…

阅读更多
Cssbuy反向海淘系统搭建方案
2026/6/30 17:00:30

Cssbuy反向海淘系统搭建方案

📁 项目技术目录# 反向海淘全网代购集运系统目录(Cssbuy同款架构) # 系统演示测试、API调用测试:http://console.open.onebound.cn/console/?iNewRookiecssbuy-south-america/ ├── docs/ # 项目文档 │…

阅读更多
Hi7001替代H5112A:100V输入与模拟/PWM双模调光的国产升级方案
2026/6/30 16:00:30

Hi7001替代H5112A:100V输入与模拟/PWM双模调光的国产升级方案

在降压型LED恒流驱动方案选型中,封装兼容性与调光灵活性往往是硬件工程师评估替代方案时的核心考量。Hi7001与H5112A均采用SOP-8封装,管脚定义高度兼容,在无需改动PCB布局的前提下,Hi7001提供了更宽的输入电压范围以及模拟调光与P…

阅读更多
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告
2026/6/28 0:00:11

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

阅读更多
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?
2026/6/28 0:00:11

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

阅读更多
如何在1分钟内为Windows安装苹果USB网络共享驱动:完整解决方案
2026/6/30 0:00:27

如何在1分钟内为Windows安装苹果USB网络共享驱动:完整解决方案

如何在1分钟内为Windows安装苹果USB网络共享驱动:完整解决方案 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.co…

阅读更多
AScript异步执行与await关键字
2026/6/30 0:00:27

AScript异步执行与await关键字

、异步解析执行 AScript提供了 Script.EvalAsync 异步方法,异步执行脚本,可设置 CancellationToken 参数。 AScript执行模式有解析执行和编译执行两种模式,这两种模式下的异步执行又有所不同: 1)解析执行模式&#…

阅读更多
AI时代真的风水轮流转,前段时间最火的还是Claude Code,转眼间Codex就火得一塌糊涂。Codex是由OpenAI 推出的AI智能体。
2026/6/30 0:00:27

AI时代真的风水轮流转,前段时间最火的还是Claude Code,转眼间Codex就火得一塌糊涂。Codex是由OpenAI 推出的AI智能体。

它不仅能回答问题,编写代码,还能读取电脑本地文件,修改项目,浏览网页,调用外部工具,自动化执行任务,操作浏览器甚至桌面应用。 也是早早的就给身边不是程序员的亲朋好友安利了,都是用…

阅读更多
GIT修改用户名
2026/6/28 5:47:46

GIT修改用户名

在GIT中修改用户名可按以下步骤操作: 查看当前git的用户名,使用命令git config --list或git config user.name。修改git用户名,使用命令git config --global user.name "xxx(新的用户名)",将其中…

阅读更多
Win11Debloat:让你的Windows系统重获新生的终极优化工具
2026/6/30 14:19:49

Win11Debloat:让你的Windows系统重获新生的终极优化工具

Win11Debloat:让你的Windows系统重获新生的终极优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …

阅读更多
技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践
2026/6/30 14:19:48

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter m4s-converter是一个…

阅读更多