百趣云 百趣云的博客

从汇编识别加密算法:常量定位法完全指南

常量定位法:密码学算法的"指纹鉴定"

SO 层逆向最高频的问题是"这段代码用的什么加密算法"。答案几乎总是同一个:搜特征常量。密码学算法的安全性来自密钥,不来自算法结构——所以标准算法内部都嵌着公开的数学常量,这些常量在二进制里就是独一无二的指纹。

本文把主流算法的识别常量汇总成一张速查表,配合搜索方法,30 秒识别一个算法。

速查表:算法 → 特征常量

对称加密

算法特征常量(hex 字节序)
AESS盒 63 7C 77 7B F2 6B 6F C5;逆S盒 52 09 6A D5
SM4S盒 D6 90 E9 FE CC E1;FK A3B1BAC6
TEA 家族delta 0x9E3779B9
DESIP 置换表 58 50 42 34 26 18 10 02
RC4无固定常量(看 256 字节初始化循环结构)

摘要算法

算法特征常量
MD5IV 0x67452301;K表首项 0xD76AA478
SHA-1IV 0x67452301 0xEFCDAB89 0x98BADCFE 0x10325476 0xC3D2E1F0
SHA-256K表首项 0x428A2F98 0x71374491
SM3IV 0x7380166F 0x4914B2B9
HMAC无独有常量(看 ipad 0x36、opad 0x5C 的重复填充)

非对称

算法特征
RSA大数模幂运算结构;公钥 0x10001(65537)
ECC曲线参数(secp256k1 的 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
SM2曲线参数 FFFFFFFE FFFFFFFF ...(国密曲线)

搜索方法:IDA 与命令行

IDA 里Search → Sequence of bytes(Alt+B),输入 hex 字节串。32 位常量注意字节序——0x9E3779B9 在内存小端存储是 B9 79 37 9E,搜索时两种字节序都试。

命令行批量(分析大量 SO 时):

# 用 Python 批量扫
python3 -c "
import sys
data = open(sys.argv[1], 'rb').read()
sigs = {
    'AES': bytes.fromhex('637c777bf26b6fc5'),
    'SM4': bytes.fromhex('d690e9fecce1'),
    'TEA': bytes.fromhex('b979379e'),      # 小端
    'MD5-K': bytes.fromhex('78a46ad7'),    # 小端
    'SHA256-K': bytes.fromhex('982f8a42'), # 小端
}
for name, sig in sigs.items():
    off = data.find(sig)
    if off >= 0:
        print(f'{name} @ 0x{off:x}')
" libtarget.so

精髓一:常量命中后干什么

命中只是起点,接下来要找到使用点

  1. IDA 里对常量地址按 X 查交叉引用
  2. 引用它的函数就是算法实现(或密钥扩展)
  3. 从算法函数再按 X 往上追,找到业务调用层——那里才有 key 和数据的组装

精髓二:常量被隐藏的情况

高级防护会把常量做处理:

  • 运行时计算0x9E3779B9 不直接出现,而是 (0x9E3779B8 + 1) 或两条指令拼出来。对策:搜邻近常量(0x9E3779B8)、或动态分析(hook 内存写)
  • 表加密存储:S 盒加密存,运行时解密。对策:不静态找了,Frida 在算法运行时 dump 内存里的解密后表
  • 自研算法无常量:回到"自定义加密还原"篇的方法论

精髓三:识别后的标准动作

识别出算法后的 checklist:

  1. 对拍验证:用标准实现 + hook 的 key 对已知输入加密,和 App 输出对比——确认算法、模式、key 三要素
  2. 记录证据:算法、常量地址、key 来源、模式,写进逆向笔记(下次版本更新对照用)
  3. 决策路径:标准算法 + 拿到 key = 本地复现;标准算法 + key 难拿 = Frida 直调;非标准 = 自定义加密方法论

总结

  1. 密码学常量即指纹,速查表覆盖主流算法
  2. 搜索注意字节序(小端存储),IDA Alt+B 或脚本批量
  3. 命中后按 X 追使用点,再追业务层拿 key
  4. 常量被隐藏就转动态分析,运行时 dump

交流微信:run1255

By 百趣云 阅读量:5 On