保姆级教程:从Hook NewStringUTF开始,一步步逆向App登录的DES和MD5算法
2026/6/11 8:41:58 网站建设 项目流程

逆向工程实战:从Hook到算法还原的完整工作流

在移动应用安全分析领域,逆向工程是一项关键技能。对于Android开发者而言,理解应用底层的加密机制不仅能提升自身的安全意识,还能帮助发现潜在漏洞。本文将聚焦一个典型场景:如何逆向分析App登录流程中的DES和MD5算法。

1. 逆向工程基础准备

逆向分析需要一套完整的工具链和基础环境配置。对于Android平台,我们需要准备以下核心工具:

  • Frida:动态插桩框架,支持运行时函数Hook
  • IDA Pro:静态反编译工具,用于分析so文件
  • adb:Android调试桥,用于设备连接
  • Burp Suite:网络抓包工具,分析通信协议

环境配置建议使用Python 3.8+环境,安装Frida工具包:

pip install frida-tools adb push frida-server /data/local/tmp/ adb shell chmod +x /data/local/tmp/frida-server

提示:在实际操作前,建议在测试设备或模拟器上进行,避免违反任何使用条款。

2. 快速定位加密函数

2.1 网络抓包初步分析

首先通过抓包工具捕获登录请求,观察关键参数。典型登录请求可能包含:

参数名示例值说明
usernametestuser明文用户名
passwordFfQn1pwmgRY=加密后的密码
signa1b2c3d4e5f6...请求签名

2.2 Hook关键JNI函数

在Android中,Java与Native层交互通常通过JNI实现。我们可以HookNewStringUTF函数来定位加密逻辑:

function hookNewStringUTF() { const libart = Process.findModuleByName("libart.so"); const symbols = libart.enumerateSymbols(); let targetFunc = null; symbols.forEach(sym => { if(sym.name.includes("NewStringUTF") && !sym.name.includes("Check")) { targetFunc = sym.address; } }); Interceptor.attach(targetFunc, { onEnter: function(args) { console.log("NewStringUTF called with:", args[1].readCString()); console.log("Backtrace:\n", Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n")); } }); }

执行后会输出调用堆栈,从中可以定位到具体的so模块和函数偏移地址。

3. DES加密算法分析

3.1 静态分析so文件

将目标so文件导入IDA Pro,定位到之前Hook发现的函数偏移位置。常见的DES加密特征包括:

  • 初始置换表(IP)和逆初始置换表(IP^-1)
  • 16轮Feistel网络结构
  • 子密钥生成算法

在反汇编代码中查找这些特征,可以快速确认加密算法类型。

3.2 动态验证加密过程

结合Frida进行动态验证:

function traceDES() { const targetFunc = Module.findExportByName("libNativeHelper.so", "sub_1234"); Interceptor.attach(targetFunc, { onEnter: function(args) { console.log("Input data:", hexdump(args[0], { length: args[1].toInt32() })); console.log("Key:", hexdump(args[2], { length: 8 })); console.log("IV:", hexdump(args[3], { length: 8 })); }, onLeave: function(retval) { console.log("Output:", hexdump(retval, { length: 8 })); } }); }

通过对比输入输出,可以验证加密模式和填充方式。常见的DES配置包括:

参数典型值
模式CBC
填充PKCS5
密钥长度8字节
IV8字节

4. MD5签名算法解析

4.1 识别MD5特征

MD5算法在so中通常有以下特征:

  • 初始化常量:0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476
  • 64元素的正弦函数表
  • 四轮主循环结构

在IDA中搜索这些常量可以快速定位MD5实现位置。

4.2 还原签名逻辑

通过动态分析可以还原签名拼接规则:

function traceMD5() { const md5Func = Module.findExportByName("libNativeHelper.so", "MD5_Update"); Interceptor.attach(md5Func, { onEnter: function(args) { const input = args[1].readUtf8String(args[2].toInt32()); console.log("MD5 input:", input); } }); }

典型的签名拼接方式可能如下:

  1. 按特定顺序拼接参数(如字母序)
  2. 添加固定盐值
  3. 进行MD5哈希计算

5. 逆向工程进阶技巧

5.1 对抗反调试措施

在实际分析中,应用可能会检测调试器。常见对抗手段包括:

  • 检测/proc/self/status中的TracerPid
  • 检查进程名是否包含frida等关键字
  • 检测异常端口开放情况

绕过示例代码:

function antiAntiDebug() { const fopen = Module.findExportByName("libc.so", "fopen"); Interceptor.replace(fopen, new NativeCallback(function(path, mode) { if(path.readUtf8String().includes("status")) { const fakeFile = Memory.allocUtf8String("/data/fake_status"); return fopen(fakeFile, mode); } return fopen(path, mode); }, "pointer", ["pointer", "pointer"])); }

5.2 自动化分析脚本

为提高效率,可以编写自动化分析脚本:

import frida import sys def on_message(message, data): print(message) device = frida.get_usb_device() pid = device.spawn(["com.target.app"]) session = device.attach(pid) with open("hook_script.js") as f: script = session.create_script(f.read()) script.on("message", on_message) script.load() device.resume(pid) sys.stdin.read()

6. 实际案例分析

以一个实际App为例,完整分析流程如下:

  1. 抓包发现password参数为Base64编码
  2. Hook NewStringUTF定位到加密函数
  3. 静态分析发现DES特征表
  4. 动态Hook验证CBC模式和PKCS5填充
  5. 通过字符串搜索定位到MD5初始化常量
  6. Hook MD5相关函数还原拼接规则

关键发现:

  • DES密钥硬编码在so中
  • IV使用固定值0xEFCDAB9078563412
  • 签名拼接顺序:username+password+timestamp+salt

7. 安全建议与最佳实践

基于分析结果,开发者可以改进应用安全:

  • 避免硬编码密钥,使用动态获取方式
  • 增加签名时效性验证
  • 混淆关键算法实现
  • 实现完整性校验防止so注入

逆向工程是一项需要耐心和技巧的工作。在实际项目中,我经常发现加密参数拼接顺序会成为突破口,建议重点关注参数处理逻辑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询