使用BinaryNinja分析某外卖libmtguard.so(一)
字数 1245 2025-08-29 08:30:24

BinaryNinja分析libmtguard.so字符串加密与间接跳转混淆

前言

本文详细讲解如何使用BinaryNinja分析某外卖应用的libmtguard.so文件,重点解决两种常见的混淆技术:字符串加密和基于ret的间接跳转。这些技术在安卓native层加固中非常常见,会严重干扰静态分析过程。

字符串加密分析

加密函数识别

在分析目标so文件时,我们发现函数sub_25d14负责字符串解密,其特征如下:

  • 参数

    • 第一个参数(x0):存放解密后的字符串
    • 第二个参数(x1):加密的字符串
    • 第三个参数(x2):密钥
    • 第四个参数(x3):长度
  • 解密逻辑:简单的密文与密钥异或操作

解密脚本编写

由于加密字符串数量众多,需要编写自动化脚本进行批量解密。关键注意事项:

  1. 在执行bl sub_25d14之前不能有其他跳转指令
  2. 第一个参数(x0)必须被正确赋值
  3. 使用Unicorn引擎模拟执行解密过程

示例脚本结构:

def decrypt_string(bv, addr):
    # 初始化Unicorn引擎
    mu = Uc(UC_ARCH_ARM64, UC_MODE_ARM)
    
    # 设置内存和寄存器状态
    # ...
    
    # 模拟执行解密函数
    mu.emu_start(decrypt_func_addr, decrypt_func_end)
    
    # 读取解密后的字符串
    decrypted = mu.mem_read(decrypted_ptr, length)
    return decrypted

基于ret的间接跳转分析

间接跳转函数分析

函数sub_25d44负责间接跳转,IDA中表现为大量爆红区域。BinaryNinja的Low Level IL分析显示其逻辑:

  1. 从x30(链接寄存器)指向的地址加载数据到w0
  2. 使用zx.q(w0)将w0扩展为64位
  3. 左移2位
  4. 计算跳转地址:x30 + (w0 << 2)
  5. 最终跳转地址为x30加上计算出的偏移

跳转目标计算示例

以JNI_OnLoad为例:

  1. 通过bl指令将x30设置为0x249c8
  2. x0被赋值为3
  3. 计算跳转地址:0x249c8 + (3 << 2) = 0x249c8 + 0xC = 0x249D4

去混淆脚本编写

编写deindbr函数进行patch处理:

  1. 获取所有跳转到0x25d44的引用
  2. 获取所有跳板(如b 0x249c4)的引用
  3. 模拟执行计算实际跳转地址
  4. 将跳转地址patch到跳板位置

关键注意事项:

  • B指令构造:跳转地址需要减去当前指令地址,因为B指令是相对跳转
  • 计算公式:目标地址 = (当前指令地址 + 8) + (立即数 * 4)
  • 处理异常情况:过滤br寄存器类型的引用

示例脚本结构:

def deindbr(bv):
    # 获取所有跳转到间接跳转函数的引用
    refs = get_call_references(bv, 0x25d44)
    
    for ref in refs:
        # 获取跳板地址
        trampoline_addr = get_trampoline(ref)
        
        # 模拟执行计算跳转目标
        target = simulate_jump(bv, ref)
        
        # 构造并patch B指令
        patch_b_instruction(bv, trampoline_addr, target)

多次运行脚本

由于BinaryNinja不会像IDA那样一次性反编译所有代码,可能需要多次运行脚本直到没有新的地址被patch。

结果验证

完成patch后:

  1. JNI_OnLoad等函数的执行流已恢复
  2. IDA中仅剩br寄存器类型的混淆(将在后续文章中分析)
  3. 可以正常进行后续分析

总结

BinaryNinja配合Unicorn引擎能有效处理native层混淆:

  1. 字符串加密:通过模拟执行解密函数批量恢复字符串
  2. 间接跳转:通过分析跳转逻辑并patch跳板指令恢复执行流
  3. 后续工作:需要恢复符号信息,结合Frida、unidbg等工具进行更深入的分析

这种方法比传统IDA分析更加灵活高效,特别适合处理现代安卓应用中的复杂混淆技术。

BinaryNinja分析libmtguard.so字符串加密与间接跳转混淆 前言 本文详细讲解如何使用BinaryNinja分析某外卖应用的 libmtguard.so 文件,重点解决两种常见的混淆技术:字符串加密和基于ret的间接跳转。这些技术在安卓native层加固中非常常见,会严重干扰静态分析过程。 字符串加密分析 加密函数识别 在分析目标so文件时,我们发现函数 sub_25d14 负责字符串解密,其特征如下: 参数 : 第一个参数(x0):存放解密后的字符串 第二个参数(x1):加密的字符串 第三个参数(x2):密钥 第四个参数(x3):长度 解密逻辑 :简单的密文与密钥异或操作 解密脚本编写 由于加密字符串数量众多,需要编写自动化脚本进行批量解密。关键注意事项: 在执行 bl sub_25d14 之前不能有其他跳转指令 第一个参数(x0)必须被正确赋值 使用Unicorn引擎模拟执行解密过程 示例脚本结构: 基于ret的间接跳转分析 间接跳转函数分析 函数 sub_25d44 负责间接跳转,IDA中表现为大量爆红区域。BinaryNinja的Low Level IL分析显示其逻辑: 从x30(链接寄存器)指向的地址加载数据到w0 使用 zx.q(w0) 将w0扩展为64位 左移2位 计算跳转地址: x30 + (w0 << 2) 最终跳转地址为x30加上计算出的偏移 跳转目标计算示例 以JNI_ OnLoad为例: 通过 bl 指令将x30设置为 0x249c8 x0被赋值为3 计算跳转地址: 0x249c8 + (3 << 2) = 0x249c8 + 0xC = 0x249D4 去混淆脚本编写 编写 deindbr 函数进行patch处理: 获取所有跳转到 0x25d44 的引用 获取所有跳板(如 b 0x249c4 )的引用 模拟执行计算实际跳转地址 将跳转地址patch到跳板位置 关键注意事项: B指令构造 :跳转地址需要减去当前指令地址,因为B指令是相对跳转 计算公式: 目标地址 = (当前指令地址 + 8) + (立即数 * 4) 处理异常情况:过滤 br 寄存器类型的引用 示例脚本结构: 多次运行脚本 由于BinaryNinja不会像IDA那样一次性反编译所有代码,可能需要多次运行脚本直到没有新的地址被patch。 结果验证 完成patch后: JNI_ OnLoad等函数的执行流已恢复 IDA中仅剩 br 寄存器类型的混淆(将在后续文章中分析) 可以正常进行后续分析 总结 BinaryNinja配合Unicorn引擎能有效处理native层混淆: 字符串加密 :通过模拟执行解密函数批量恢复字符串 间接跳转 :通过分析跳转逻辑并patch跳板指令恢复执行流 后续工作 :需要恢复符号信息,结合Frida、unidbg等工具进行更深入的分析 这种方法比传统IDA分析更加灵活高效,特别适合处理现代安卓应用中的复杂混淆技术。