某手__ns_sig3逆向分析
字数 1754 2025-08-30 06:50:12

某手__ns_sig3逆向分析教学文档

1. Java层分析

1.1 源码追踪

  1. 在源码中搜索发现__NS_sig3存储在HashMap中,对应键值为b4
  2. b4由函数b()生成
  3. 尝试Hook java.util.HashMap失败(可能被检测),转为直接反编译代码追踪

1.2 关键调用链

atlasSign() → d() → c() → a4.g().a()
  • a4.g().a()返回b的属性f25022a,即__ns_sig3的字节流
  • 中间关键调用:com.kuaishou.android.security.internal.dispatch.e.a(this.f24952a).g().f(a4, "0335")

1.3 Native层入口

最终调用链:

JNICLibrary.doCommandNative(i4, objArr)
  • 这是一个native函数
  • 通过Hook确认其返回__ns_sig3

1.4 定位so库

  1. 通过日志信息定位库名为f23969b
  2. Hook确认库加载过程

2. SO层分析

2.1 去花指令处理

  1. 识别花指令特征:

    • 非标准函数栈操作
    • 使用STRLDP指令传递寄存器值
    • 通过BR跳转到计算地址
  2. 手动Patch方法:

    • 将干扰指令NOP掉
    • 直接修改为跳转到目标地址
  3. 编写脚本批量去花:

    # IDA去花脚本示例
    def nop_range(start, end):
        for i in range(start, end):
            PatchByte(i, 0x90)
    
    # 应用脚本后重新分析程序
    

2.2 Unidbg准备

  1. 初始模板遇到初始化校验问题
  2. 通过Hook doCommandNative获取初始化参数
  3. 补全必要环境:
    // Unidbg初始化示例
    public void callInit() {
        List<Object> list = new ArrayList<>();
        list.add(vm.getJNIEnv());
        list.add(0);
        module.callFunction(emulator, 0x10000, list.toArray());
    }
    

2.3 固定结果分析

  1. 发现结果不固定,怀疑与时间戳相关
  2. 定位到gettimeofday系统调用
  3. 修改Unidbg源码固定时间:
    // 修改UnixSyscallHandler.java
    @Override
    public long gettimeofday(UnixEmulator emulator, Timeval tv, Timezone tz) {
        if (tv != null) {
            tv.set(1748752323, 214000); // 固定时间戳
        }
        return 0;
    }
    
  4. 固定后得到稳定结果:bbaadaf9b2c786b6f3f3f0f19de705a7293cd381eee2ecfa

2.4 关键字节生成分析

  1. 通过Trace从结果反推:

    • 搜索结果字节0xbb0xaa
    • 定位到关键汇编指令:
      ldrb w1, [x21], #1
      eor w11, w11, w12
      
  2. 发现24字节结果生成逻辑:

    • 从内存地址加载原始字节
    • 0xfa进行异或得到最终结果
    • 第24字节直接使用0xfa
  3. 伪代码表示:

    for (int i = 0; i < 23; i++) {
        *(result + i) = *(src + i) ^ 0xFA;
    }
    *(result + 23) = 0xFA;
    

2.5 CRC32校验

  1. 定位到CRC32运算:

    • 多项式:0x04C11DB7
    • 标准CRC32算法
  2. 影响范围:

    • URL参数影响13-16字节
    • 时间戳影响5-8字节及17-19字节

2.6 白盒AES分析

  1. 定位关键数据:

    • 输入:8a536e06f438b1929bd7015fc1d17f70f4a76e00ec0b4fd1c58e44fef47efeafe0ed8ea4aab0c1d5f4519f8d19c4948f
    • 操作地址:0x404e4e40
  2. 识别AES特征:

    • ECB模式(无IV)
    • 标准PKCS7填充
    • 10轮加密
  3. 密钥推导:

    • 使用PhoenixAES工具推导最后一轮密钥
    • 逆向推导种子密钥
  4. 验证:

    • 使用推导出的密钥进行标准AES-ECB加密
    • 结果与so输出一致

2.7 HMAC-SHA256分析

  1. 输入处理:

    • URL对象作为输入
    • 使用两个64字节盐值(类似HMAC的ipad和opad)
  2. 关键特征:

    • 盐值分别异或0x360x5c
    • 标准HMAC-SHA256算法
  3. 验证:

    import hmac
    import hashlib
    
    # 示例验证
    key = b'...'  # 提取的盐值
    message = b'urlObj'
    hmac.new(key, message, hashlib.sha256).hexdigest()
    

3. 完整流程总结

  1. 输入处理

    • 接收URL对象和时间戳
    • 通过HMAC-SHA256生成中间值
  2. 白盒AES加密

    • 使用固定密钥对中间值进行AES-ECB加密
    • 生成48字节数据
  3. CRC32校验

    • 对部分数据进行CRC32运算
    • 影响最终结果的13-16字节
  4. 异或处理

    • 前23字节与0xFA异或
    • 第24字节固定为0xFA
  5. 输出

    • 生成24字节的__ns_sig3

4. 关键技术点

  1. 逆向技巧

    • 从Java层到Native层的完整调用链追踪
    • 通过Hook和反编译结合分析
    • 结果反推生成逻辑
  2. 密码学分析

    • 白盒AES识别与密钥提取
    • HMAC-SHA256算法识别
    • CRC32校验分析
  3. 反调试对抗

    • 花指令识别与去除
    • Unidbg环境补全
  4. 调试技巧

    • Trace代码定位关键点
    • 内存写入监控
    • 寄存器状态分析

5. 参考工具

  1. 逆向工具

    • IDA Pro 7.0+
    • JADX/GDA
    • Frida
  2. 辅助工具

    • Unidbg
    • PhoenixAES
    • CyberChef
  3. 参考文章

    • 花指令处理分析
    • 龙哥去花文章
    • 杨如画大佬的逆向文章
    • 季冬大佬的技术分享
某手__ ns_ sig3逆向分析教学文档 1. Java层分析 1.1 源码追踪 在源码中搜索发现 __NS_sig3 存储在HashMap中,对应键值为 b4 b4 由函数 b() 生成 尝试Hook java.util.HashMap 失败(可能被检测),转为直接反编译代码追踪 1.2 关键调用链 a4.g().a() 返回 b 的属性 f25022a ,即 __ns_sig3 的字节流 中间关键调用: com.kuaishou.android.security.internal.dispatch.e.a(this.f24952a).g().f(a4, "0335") 1.3 Native层入口 最终调用链: 这是一个native函数 通过Hook确认其返回 __ns_sig3 1.4 定位so库 通过日志信息定位库名为 f23969b Hook确认库加载过程 2. SO层分析 2.1 去花指令处理 识别花指令特征: 非标准函数栈操作 使用 STR 和 LDP 指令传递寄存器值 通过 BR 跳转到计算地址 手动Patch方法: 将干扰指令NOP掉 直接修改为跳转到目标地址 编写脚本批量去花: 2.2 Unidbg准备 初始模板遇到初始化校验问题 通过Hook doCommandNative 获取初始化参数 补全必要环境: 2.3 固定结果分析 发现结果不固定,怀疑与时间戳相关 定位到 gettimeofday 系统调用 修改Unidbg源码固定时间: 固定后得到稳定结果: bbaadaf9b2c786b6f3f3f0f19de705a7293cd381eee2ecfa 2.4 关键字节生成分析 通过Trace从结果反推: 搜索结果字节 0xbb 、 0xaa 等 定位到关键汇编指令: 发现24字节结果生成逻辑: 从内存地址加载原始字节 与 0xfa 进行异或得到最终结果 第24字节直接使用 0xfa 伪代码表示: 2.5 CRC32校验 定位到CRC32运算: 多项式: 0x04C11DB7 标准CRC32算法 影响范围: URL参数影响13-16字节 时间戳影响5-8字节及17-19字节 2.6 白盒AES分析 定位关键数据: 输入: 8a536e06f438b1929bd7015fc1d17f70f4a76e00ec0b4fd1c58e44fef47efeafe0ed8ea4aab0c1d5f4519f8d19c4948f 操作地址: 0x404e4e40 识别AES特征: ECB模式(无IV) 标准PKCS7填充 10轮加密 密钥推导: 使用PhoenixAES工具推导最后一轮密钥 逆向推导种子密钥 验证: 使用推导出的密钥进行标准AES-ECB加密 结果与so输出一致 2.7 HMAC-SHA256分析 输入处理: URL对象作为输入 使用两个64字节盐值(类似HMAC的ipad和opad) 关键特征: 盐值分别异或 0x36 和 0x5c 标准HMAC-SHA256算法 验证: 3. 完整流程总结 输入处理 : 接收URL对象和时间戳 通过HMAC-SHA256生成中间值 白盒AES加密 : 使用固定密钥对中间值进行AES-ECB加密 生成48字节数据 CRC32校验 : 对部分数据进行CRC32运算 影响最终结果的13-16字节 异或处理 : 前23字节与 0xFA 异或 第24字节固定为 0xFA 输出 : 生成24字节的 __ns_sig3 4. 关键技术点 逆向技巧 : 从Java层到Native层的完整调用链追踪 通过Hook和反编译结合分析 结果反推生成逻辑 密码学分析 : 白盒AES识别与密钥提取 HMAC-SHA256算法识别 CRC32校验分析 反调试对抗 : 花指令识别与去除 Unidbg环境补全 调试技巧 : Trace代码定位关键点 内存写入监控 寄存器状态分析 5. 参考工具 逆向工具 : IDA Pro 7.0+ JADX/GDA Frida 辅助工具 : Unidbg PhoenixAES CyberChef 参考文章 : 花指令处理分析 龙哥去花文章 杨如画大佬的逆向文章 季冬大佬的技术分享