美文网首页
如何使用OLLVM和常规方法实现Android SO文件混淆以提

如何使用OLLVM和常规方法实现Android SO文件混淆以提

作者: Allenlll | 来源:发表于2024-08-15 14:23 被阅读0次

一、引言

在移动应用开发中,应用的安全性越来越受到关注。特别是在Android应用中,SO(Shared Object)文件往往会保存一些需要加密的关键数据,如API密钥、应用密钥等。如果这些重要的信息没有经过适当的混淆和保护,极容易被恶意第三方通过逆向工程手段破解,进而导致一系列安全问题。

对SO文件进行混淆和保护与对Java和Kotlin代码进行混淆一样重要。混淆不仅可以增加破解难度,还可以有效地保护应用内部的核心算法和功能逻辑。本篇文章将探讨如何利用CMake常规方法和开源的OLLVM工具对SO文件进行混淆,以提高应用安全性。同时,我们也将对两种方法的混淆效果进行验证和对比,并探讨如何解决集成过程中的常见问题。

二、常规混淆方法

在对SO文件进行混淆保护时,我们常使用一些配置参数来编译和链接代码,以提升其安全性。以下是一些常用的CMake参数及其功能:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -fvisibility=hidden -fstack-protector-strong -fPIE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fvisibility=hidden -fstack-protector-strong -fPIE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s -Wl,-z,relro,-z,now -pie")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s -Wl,-z,relro,-z,now -pie")
  • -02:
    进行较高级别的优化,既能提升代码执行效率,又不会显著增加编译时间。
  • -fvisibility=hidden:
    将符号默认可见性设为隐藏,避免外部重复定义或滥用内部API。
  • -fstack-protector-strong:
    防止栈溢出攻击,通过在函数的返回地址前插入保护符。
  • -fPIE 和 -pie:
    启用位置无关代码,使执行文件在内存中随处可加载,增加攻击难度。
  • -s:
    去除符号表和重定位信息,减小生成文件的大小。
  • -Wl,-z,relro,-z,now:
    relro(可重定位读写部分)和 now(完全重定位保护),这些参数进一步加强执行时的安全性。
    为了验证这些参数的效果,我们使用IDA(Interactive Disassembler)对未混淆和混淆后的SO文件进行了分析。
未混淆SO文件

在不使用上述参数进行混淆的情况下,我们将生成的SO文件导入到IDA中,如下图所示:


17237769872916.png

可以明显看到字符串和native方法,信息一览无遗,极易被逆向工程人员识别和破解。

使用常规参数混淆后的SO文件

当我们在CMake中添加上述混淆参数后,重新生成SO文件并在IDA中进行查看,发现以下变化:


17237770373346.png

尽管SO文件的大小有所减小,但混淆效果并不显著。字符串和native方法仍然容易被识别,代码行数虽然减少,但不足以达到预期的混淆效果。

通过上述比较,我们可以看出单纯依靠这些常规方法进行混淆效果有限。为进一步提高SO文件的混淆效果,我们接下来将介绍一种更为有效的开源工具——OLLVM。

三、OLLVM介绍

OLLVM(Obfuscator with LLVM)是基于LLVM(Low Level Virtual Machine)的一个开源混淆器。它通过对程序代码进行变形和混淆,使得逆向工程变得更加困难,从而显著增强了程序的安全性和保护机制。相比于传统的混淆方法,OLLVM提供了一些高级的混淆技术,使其成为保护SO文件的重要工具。

OLLVM的主要功能包括:

  • 控制流扁平化(-mllvm -fla):通过扁平化控制流,使代码的执行路径变得复杂且难以理解,从而增加逆向工程的难度。

  • 指令替换(-mllvm -sub):用等效但不同的指令序列替换原有指令,增加代码阅读和分析的复杂度。

  • 虚假控制流程(-mllvm -bcf):在代码中插入虚假的控制流和逻辑,使得代码看起来混乱且难以推理。

  • 字符串加密(-mllvm -sobf):对字符串进行加密处理,防止字符串在二进制文件中被轻易识别和解析。

通过结合使用这些功能,OLLVM能够大幅提升SO文件的防护能力,使其更加难以被破解。接下来,我们将深入探讨如何使用OLLVM对SO文件进行混淆,并验证其效果。

四、使用OLLVM进行混淆

接下来我们将介绍如何使用OLLVM对SO文件进行混淆,包括下载、编译、配置并验证其效果。

  • 下载和编译OLLVM
    首先,从GitHub下载OLLVM的源码,并进行编译:
$ git clone -b llvm-9.0.1 https://github.com/heroims/obfuscator
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_CREATE_XCODE_TOOLCHAIN=ON ../obfuscator/
$ make -j7

  • 配置OLLVM
    编译完成后,将生成的build/bin目录拷贝到Android/sdk/ndk/xx.x.xxxxxx/toolchains/ollvm/prebuilt/darwin-x86_64/bin,并替换原有的bin文件夹(注意:是替换,而不是覆盖)。具体步骤如下:
$ cp -r build/bin /path/to/Android/sdk/ndk/xx.x.xxxxxx/toolchains/ollvm/prebuilt/darwin-x86_64/
  • 解决编译报错

在使用OLLVM进行编译时,可能会遇到缺少头文件的问题。根据提示信息,拷贝缺少的头文件到相应目录中。通常需要从build/lib/clang/9.0.0/include/目录复制以下文件:
stdarg.h
stddef.h
_stddef_max_align_t.h
float.h
stdbool.h
将以上文件复制到ndk目录/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include文件夹下。不同的NDK版本可能会有不同的头文件需求,请根据具体错误提示进行操作。

完成这些步骤后,OLLVM已经配置完毕。接下来,在Android Studio中选择Build --> Refresh Linked C++ Projects,然后再次运行程序,验证编译是否通过。

  • 在CMakeLists.txt中应用OLLVM混淆配置

在CMakeLists.txt文件中增加以下配置,用以应用OLLVM的混淆功能:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mllvm -sub -mllvm -sobf -mllvm -fla -mllvm -bcf")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -sub -mllvm -sobf -mllvm -fla -mllvm -bcf")

这些参数分别启用了OLLVM的指令替换、字符串加密、控制流扁平化和虚假控制流程功能。

  • 混淆效果验证
    混淆后的SO文件在IDA中查看效果如下图所示:


    1723777310240.png

可以看出,代码结构变得更加复杂,明文字符串也被加密,显著提升了代码的混淆效果和安全性。

五、结合使用OLLVM和常规混淆方法

虽然使用OLLVM进行混淆显著提高了SO文件的安全性,但我们发现包的大小却大幅增加。经过混淆处理后,SO文件的大小从原先的210KB增长到了1.2MB,这对应用的整体性能和分发带来了不小的负担。

为了解决包大小的问题,可以结合使用OLLVM和常规的混淆配置。具体的CMake配置如下所示:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -fvisibility=hidden -fstack-protector-strong -fPIE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fvisibility=hidden -fstack-protector-strong -fPIE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s -Wl,-z,relro,-z,now -pie")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s -Wl,-z,relro,-z,now -pie")

这些配置参数的功能在前文已经进行详细介绍,应用它们不仅有助于提升代码的可读性和安全性,还能减少最终生成的SO文件的大小。

通过重新编译,我们发现SO文件的包大小问题得到了明显改善。最终生成的SO文件不仅保留了OLLVM带来的高级混淆效果,同时也得到了合理的优化和压缩,大小回到了较为理想的范围。

六、结论

通过本文的探讨,我们了解了如何使用OLLVM和常规方法对Android SO文件进行混淆和保护。常规方法易于配置,且对包大小控制良好,但混淆效果有限。OLLVM则提供了更高级的混淆技术,显著提升安全性,但会导致包大小增加。

结合使用OLLVM和常规混淆方法,可以同时实现强大的混淆效果和适当的包大小控制。这种组合方式,不仅提升了代码的安全性和复杂性,还保持了应用的整体性能。通过这些方法,Android应用可以更好地抵御逆向工程和恶意攻击,从而提高整体安全性。

相关文章

  • Android NDK混淆

    项目原因研究Android的So库代码混淆,增加IDA工具查看的复杂度。简单接触了ollvm 混淆组件。网上查看了...

  • Android/iOS C++ 打包

    Android so:单文件示例多文件示例 iOS:.a库framework混淆

  • OLLVM 快速学习

    近来,ollvm在国内移动安全,尤其是安全加固上的使用越来越广泛,ollvm的混淆和反混淆也被视为比较高等的知识之...

  • 在Android.bp文件中如何引用编译好的so库

    在Android.bp文件中如何引用编译好的so库 以Android系统的keystore服务代码的Android...

  • Android NDK开发中jni配置及调用GPIO

    一直以来做项目都是直接加载生成好的so文件,然后调用相关的封装方法来实现外接硬件的调用。平常我们使用android...

  • 经验总结 - 收藏集 - 掘金

    安卓开发:使用双进程守护和进程提权来实现服务进程保活 - Android - 掘金在 如何让我们的Android应...

  • so库中JNI方法混淆

    so库中JNI方法混淆 关于如何配置NDK环境和测试C++方法是否调用成功,请参照@callxkj的简书 ...

  • Android 如何编译和使用外部so文件

    [TOC] 故事场景 android通常使用别人的轮子是直接依赖别人的aar,但是如果别人扔给你一个so和一个.h...

  • Linux下查找和安装依赖的.so文件

    以解决Webex在Linux下运行问题为例说明查找和安装依赖的.so文件方法: 查找依赖的.so文件 安装.so查...

  • Keep混淆

    keep注解 支持变量、方法、构造方法、类、注解 混淆文件proguard-rules.pro android代码...

网友评论

      本文标题:如何使用OLLVM和常规方法实现Android SO文件混淆以提

      本文链接:https://www.haomeiwen.com/subject/nirekjtx.html