news 2026/4/20 20:09:15

实战复盘:我是如何用Frida Hook一个AES加密的SO库,并拿到Key和IV的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实战复盘:我是如何用Frida Hook一个AES加密的SO库,并拿到Key和IV的

逆向工程实战:Frida动态Hook解密AES加密SO库的关键技术解析

在移动安全领域,逆向分析加密算法一直是极具挑战性的技术课题。当遇到关键业务逻辑被编译到SO库中,特别是采用AES这类标准加密算法时,如何高效提取密钥参数成为安全研究人员关注的焦点。本文将分享一套经过实战验证的Frida动态Hook方案,通过真实案例演示如何快速定位SO库中的加密函数、提取AES密钥和初始向量(IV),并验证解密结果的完整流程。

1. 逆向分析前的准备工作

逆向工程的成功往往取决于前期准备的充分程度。在开始Hook之前,我们需要构建完整的分析环境并掌握目标应用的基本信息。

基础环境配置清单

  • 已root的Android测试设备或模拟器(推荐Android 9-11版本)
  • Frida 15.1.17及以上版本(包含frida-server和客户端工具)
  • IDA Pro 7.6用于静态分析(可选但推荐)
  • Python 3.8+环境运行Frida脚本
  • adb工具链用于设备调试

提示:测试设备建议使用x86架构的模拟器或真机,可避免ARM指令集转换带来的兼容性问题。

通过静态分析初步定位加密函数是高效Hook的前提。对于AES加密的SO库,我们需要特别关注以下特征:

  • 函数参数中包含16字节或32字节的固定长度数组
  • 出现标准加密算法常量(如AES_SBOX)
  • 调用OpenSSL或BoringSSL相关加密接口
  • Java层通过JNI调用的native方法
# 检查目标SO库的导出函数 nm -D target.so | grep -i 'aes\|crypt\|decrypt'

2. 关键函数定位技术

当SO库采用动态注册方式时,传统的导出函数搜索方法往往失效。此时需要从JNI_OnLoad入手,追踪RegisterNatives的调用过程。

动态注册函数定位步骤

  1. 在IDA中定位JNI_OnLoad函数入口
  2. 分析RegisterNatives调用参数
  3. 提取JNINativeMethod结构体中的函数指针
  4. 交叉引用定位到实际加密函数
// Frida脚本片段:追踪RegisterNatives调用 Interceptor.attach(Module.findExportByName(null, "RegisterNatives"), { onEnter: function(args) { console.log("[*] RegisterNatives called for class: " + Java.vm.getEnv().getClassName(args[0])); var methods = ptr(args[2]); var count = args[3].toInt32(); for (var i = 0; i < count; i++) { var name = methods.add(i * 12).readPointer().readCString(); var sig = methods.add(i * 12 + 4).readPointer().readCString(); var fnPtr = methods.add(i * 12 + 8).readPointer(); console.log(" Method: " + name + sig + " at " + fnPtr); } } });

对于复杂的SO库,还可以采用以下增强定位策略:

  • 字符串搜索关键常量(如"aes"、"cbc"等)
  • 交叉引用分析标准加密函数调用
  • 内存特征码匹配(适用于混淆场景)

3. Frida Hook实战技巧

成功定位目标函数后,接下来需要设计精确的Hook脚本来捕获关键参数。针对AES-CBC模式,我们需要重点关注Key和IV的传递方式。

典型AES参数Hook方案

function hook_aes_function() { var target_func = Module.findExportByName("libcrypto.so", "AES_cbc_encrypt"); if (target_func) { Interceptor.attach(target_func, { onEnter: function(args) { console.log("\n[*] AES_cbc_encrypt called"); // 参数1: 输入数据 var in_data = ptr(args[0]); // 参数2: 输出缓冲区 var out_data = ptr(args[1]); // 参数3: 数据长度 var length = args[2].toInt32(); // 参数4: AES_KEY结构体 var aes_key = args[3]; // 参数5: IV向量 var iv = ptr(args[4]); // 参数6: 加密/解密标志 var enc = args[5].toInt32(); // 提取实际Key数据 var key_data = aes_key.add(8).readByteArray(16); console.log("AES Key:", hexdump(key_data)); console.log("IV:", hexdump(iv.readByteArray(16))); } }); } }

在实际项目中,可能会遇到各种复杂情况,下面列出常见问题及解决方案:

问题类型现象表现解决方案
参数混淆参数通过寄存器传递使用Frida的CPUContext访问寄存器
结构体封装Key/IV被包装在自定义结构体中分析内存布局后计算偏移量
动态生成每次调用Key不同跟踪密钥生成函数
反调试检测Hook后进程崩溃先Hook反调试函数

4. 数据验证与结果分析

获取到Key和IV后,需要验证其有效性。可以通过以下方法进行交叉验证:

验证方法一:本地解密测试

from Crypto.Cipher import AES from binascii import unhexlify key = unhexlify("获取到的16字节Key") iv = unhexlify("获取到的16字节IV") cipher = AES.new(key, AES.MODE_CBC, iv) plaintext = cipher.decrypt(加密数据) print("Decrypted:", plaintext)

验证方法二:实时拦截对比

// 在Hook脚本中添加结果验证逻辑 onLeave: function(retval) { var decrypted = ptr(retval).readByteArray(16); console.log("Decrypted result:", hexdump(decrypted)); // 与Java层返回结果对比 }

在实际测试中,可能会遇到填充模式不一致导致解密失败的情况。常见的问题包括:

  • PKCS7填充与ZeroPadding混淆
  • 输出结果包含多余填充字节
  • 编码格式不匹配(Base64/Hex)

注意:某些应用会故意在解密后修改结果,需对比内存中的原始输出和Java层返回结果。

5. 高级Hook技巧与优化

基础Hook技术掌握后,可以进一步优化脚本的稳定性和隐蔽性:

性能优化技巧

  • 使用NativeFunction直接调用目标函数
  • 实现条件过滤避免频繁打印
  • 采用多线程处理大量数据
// 优化后的Hook示例 var aes_func = new NativeFunction( Module.findExportByName("libcrypto.so", "AES_cbc_encrypt"), 'void', ['pointer', 'pointer', 'int', 'pointer', 'pointer', 'int'] ); Interceptor.replace(aes_func, new NativeCallback(function(in_, out, len, key, iv, enc) { if (len == 16) { // 只处理特定长度 console.log("Key captured:", hexdump(key.add(8).readByteArray(16))); } return aes_func(in_, out, len, key, iv, enc); }, 'void', ['pointer', 'pointer', 'int', 'pointer', 'pointer', 'int']));

反检测策略

  • 随机化Hook时机
  • 伪装Frida进程名称
  • 使用inline hook替代导出表Hook
  • 动态修改内存保护属性

6. 自动化Hook框架设计

对于需要批量分析多个加密函数的场景,可以设计自动化Hook框架:

class CryptoHookManager { constructor() { this.hooks = []; this.patterns = { aes: /aes|AES|rijndael/i, des: /des|DES/i, rsa: /rsa|RSA/i }; } setupHooks() { Module.enumerateExportsSync("libcrypto.so").forEach(exp => { for (let algo in this.patterns) { if (this.patterns[algo].test(exp.name)) { this.hookExport(exp.name, algo); break; } } }); } hookExport(name, algo) { let func = Module.findExportByName("libcrypto.so", name); if (func) { Interceptor.attach(func, { onEnter: function(args) { this.algo = algo; console.log(`[${algo}] ${name} called`); }, onLeave: function(retval) { console.log(`[${this.algo}] ${name} returned`); } }); this.hooks.push({name, algo}); } } } let manager = new CryptoHookManager(); manager.setupHooks();

该框架可实现:

  • 自动识别常见加密算法
  • 批量Hook相关函数
  • 分类记录调用信息
  • 支持动态添加新规则

7. 安全防护建议

从防御角度出发,开发者可以采取以下措施增加逆向难度:

防护策略对比表

防护技术实现难度防护效果性能影响
代码混淆
动态加载
完整性校验
白盒加密极高
多态代码极高极高

具体实现建议:

  • 将Key分成多个片段动态组合
  • 使用JNI_OnLoad进行运行时校验
  • 实现自定义内存分配器保护敏感数据
  • 定期更新加密方案和密钥

在最近的一次金融APP测试中,通过组合使用函数粒度Hook和内存访问监控,成功还原了被VMProtect保护的AES密钥。整个过程耗时约8小时,其中大部分时间花费在分析自定义的内存访问模式上。最终发现密钥被拆分成三部分,分别存储在不同线程的TLS区域中,只有特定操作序列才会组合出完整密钥。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/20 20:03:14

终极指南:3步解锁百度网盘SVIP高速下载功能(macOS版)

终极指南&#xff1a;3步解锁百度网盘SVIP高速下载功能&#xff08;macOS版&#xff09; 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘…

作者头像 李华
网站建设 2026/4/20 19:59:15

Pandas实现excel的IF函数功能

Pandas实现excel的IF函数功能1、创建数据框dic {地市: [廊坊,廊坊,廊坊,张家口,张家口,张家口],组号:[1,2,1,2,1,2],数量:[11,12,13,14,15,16]} p_city pd.DataFrame(dic) print(p_city)输出&#xff1a;p_city[编号] np.where(p_city[组号] 1, 男, 女) # print(p_city)输…

作者头像 李华
网站建设 2026/4/20 19:58:26

5分钟搞定:大气层Atmosphere破解系统新手配置全攻略

5分钟搞定&#xff1a;大气层Atmosphere破解系统新手配置全攻略 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 作为Nintendo Switch上最受欢迎的破解系统&#xff0c;大气层Atmosphere 1.…

作者头像 李华
网站建设 2026/4/20 19:56:39

Qwen-Image-2512像素艺术生成代码实例:Python调用FastAPI API完整示例

Qwen-Image-2512像素艺术生成代码实例&#xff1a;Python调用FastAPI API完整示例 1. 引言&#xff1a;当大模型遇见像素艺术 像素艺术&#xff0c;那种由一个个小方块构成的独特美感&#xff0c;总能勾起我们对复古游戏的回忆。但你知道吗&#xff1f;现在不用再手动绘制每一…

作者头像 李华