so层字符串加密解决方案

[复制链接]
查看1329 | 回复1 | 2025-7-6 14:56:02 | 显示全部楼层 |阅读模式

立即注册,突破游客限制,与技术大牛交流切磋,畅享海量资源,让你的技术之路不再孤单!

您需要 登录 才可以下载或查看,没有账号?立即注册

×
背景
随着安全对抗的日益升级,在进行 native 层逆向分析时,我们经常会遇到目标 so 文件中的字符串被加密的情况。由于字符串是定位关键代码的重要手段,因此对加密字符串进行解密还原显得尤为重要。本文将介绍几种常见的字符串加密破解方法,并结合实际案例进行讲解。
追踪所有返回的字符串
某些字符串混淆方案会在运行时调用字符串解密函数,将解密后的字符串以 C 指针的形式返回给调用者。然而,这些解密函数可能较难快速定位。因此,我们可以通过 Frida 对模块中的所有函数进行 hook,在函数返回时使用 readCString() 尝试输出结果。
优点:
  • 如果运气好,可以直接看到一些敏感的关键字符串,从而快速定位关键函数。
缺点:
  • 可能导致 APP 崩溃,追踪过程不够稳定。
  • 输出数据较多,有效信息难以筛选。
具体流程:
  • 运行脚本 toolchain_collect_ret_insn.py 。
  • 选择“是”:在 IDB 所在目录生成对所有函数的 ret 指令处进行 hook 的脚本。
  • 选择“否”:仅生成导出函数的 ret 指令处的 hook 脚本。
    截图202507061445188206.png
    4.对生成的脚本进行简单调整后即可使用。
    截图202507061445527881.png
    效果示例:
    截图202507061446154994.png
    定位高频调用函数
    思路
    某些字符串混淆方案会在运行时频繁调用固定的字符串解密函数。由于一个 so 文件通常包含数百甚至上千个字符串,这些解密函数的调用次数往往远高于普通功能函数。通过统计所有函数的交叉引用次数并按从高到低排序,可以快速定位这些字符串解密函数。此外,这种方法还可以用于定位字符串的构造函数,作为去混淆的关键点。
    优点
    稳定性较高,只需针对少量函数进行 hook。
    干扰数据较少。
    适用于基于堆和基于栈的字符串加密方案。
    缺点:
    需要手动排查并定位字符串解密函数。
    使用方法:
    运行脚本 top_xrefs.py,输入需要查看的调用次数最多的 N 个函数。
    截图202507061446401472.png
    示例结果:
    xxard:
    截图202507061447005156.png
    字符串解密实现:
    截图202507061447191493.png
    xxsec:
    截图202507061447415710.png
    xxny:
    截图202507061448013264.png
    trace Jni 的字符串相关函数
    思路:
    在 native 层通过 Java 传递字符串参数或返回 Java 类型的字符串时,通常会调用 NewString、NewStringUTF、GetStringUTFChars 等 JNI 接口。我们可以通过 hook 这些接口来追踪字符串。
    优点:
    • 产生的无关数据较少。
    缺点:
    • 输出数据量较少,通常难以定位关键函数。
    具体实现:
    1、使用 deathmemory 大佬的开源项目 FridaContainer 进行 JNI trace:
    1. FCAnd.jni.hookJNI('NewString', {
    2.     onEnter: function (args) {
    3.         try {
    4.             var str = args[1].readCString();
    5.             console.log('NewString ' + ' str: ' + str);
    6.         } catch (error) {
    7.    
    8.         }
    9.     }
    10. });
    11. FCAnd.jni.hookJNI('NewStringUTF', {
    12.     onEnter: function (args) {
    13.         try {
    14.             var str = args[1].readCString();
    15.             console.log('NewStringUTF ' + ' str: ' + str  );
    16.         } catch (error) {
    17.    
    18.         }
    19.     }
    20. });
    21. FCAnd.jni.hookJNI('GetStringUTFChars', {
    22.     onLeave: function (retval) {
    23.         try {
    24.             var str = retval.readCString();
    25.             console.log('GetStringUTFChars ' + ' str: ' + str  );
    26.         } catch (error) {
    27.    
    28.         }
    29.     }
    30. });
    复制代码
    2、使用大佬的开源项目 https://github.com/w296488320/JnitraceForCpp

    内存dump
    思路:
    某些 so 文件使用开源的 OLLVM 进行字符串加密,其特点是在 init 函数中将字符串解密回 data 段。我们可以通过 Frida dump 工具直接从内存中提取解密后的字符串。
    优点:
    • 对于字符串回填到 data 段的保护方式,能够高效去混淆。
    缺点:
    • 无法处理基于堆或栈的字符串加密。
    具体流程:
    • 启动 APP,触发关键逻辑,确保目标模块加载到内存。
    • 使用 Frida dump 工具从内存中提取解密后的 so 文件。
    • 将 fix_convey_str_list.py 脚本拷贝到 IDA 插件目录,重启 IDA 生效。
    • 在 IDA 中加载 dump 的 so 文件,使用插件导出解析的字符串列表。

      截图202507061449279538.png
      5.导出字符串列表后,将其重新导入非 dump 的 so 文件中进行分析。
      截图202507061449457228.png
      内存扫描
      思路:
      针对基于堆的字符串加密方案,动态申请内存保存解密后的字符串,并将字符串指针保存在全局变量中。我们可以编写 IDA 脚本扫描 data 和 bss 段的内存空间,尝试读取字符串指针并输出解密后的字符串。
      优点:
      • 对动态分配内存的字符串加密方案效果显著。
      缺点:
      • 无法处理基于栈的字符串加密。
      具体流程:
      • 使用 toolchain_trace_dyn_dec_str.py 脚本生成 Frida js 脚本,修改 Module.findBaseAddress 中的模块名。
      • 启动 APP,触发关键逻辑,等待字符串解密后frida加载脚本进行 dump。
        截图202507061450052005.png
        1.保存 dump 的字符串信息到文件中,使用 IDA 脚本 toolchain_trace_dyn_dec_str.py 补充信息回到 IDB 文件中。

        截图202507061450532018.png
        由于有的地址是bss段的,没有在文件中分配实际的空间,因此不能直接 patch 对应地址的内容。 我这里的解决思路是在对应地址下个断点,并添加一个注释,这样通过断点窗口就可以方便的进行 字符串查找了…… Ctrl+ALT+B 打开断点界面,右击选择Columns仅展示 comment(同样Ctrl+F搜索字符串即可):
        截图202507061451326223.png
        在汇编窗口上可以看到字符串备注:
        截图202507061451508990.png
        总结
        本文围绕 native 层字符串加密的逆向破解方法展开,结合实际案例详细介绍了多种应对策略,包括追踪返回字符串、定位高频调用函数、JNI 字符串追踪、内存 dump 和内存扫描等技术手段。通过这些方法,可以有效应对不同类型的字符串加密方案,为逆向分析提供强有力的支持。希望本文的分享能为读者在实际工作中提供启发和帮助。

        截图202507061453272651.png
        脚本资源.zip (76.29 KB, 下载次数: 5, 售价: 5 金钱)



这个人还没有签名
Poonshinglam | 2025-8-14 08:12:50 | 显示全部楼层
金币只有充值才能获取吗
这个人还没有签名
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文推荐
热门排行