其他分享
首页 > 其他分享> > ios 中集成ollvm12.x

ios 中集成ollvm12.x

作者:互联网

一. 前言

最近工作中遇到 ios 代码需要做混淆的需求,因此硬着头皮专研怎么将 ollvm 移植到 xcode 中使用。在网上查到的 ios 集成 ollvm的方法大多是说:“将 ollvm4.0 编译结果制作成一个xcode插件”,但这种应该只适用较老的xcode版本,在xcode10以上的版本并不适用。本人需要移植的是 xcode12.4,对应的 clang 版本是12.0.0,因此那种方法并不适用,且经过尝试,确实没有成功(当然也不排除本人操作不当的可能)。

移植环境:

  1. xcode版本:12.4
  2. llvm版本:12.0.0
  3. Mac OS版本:10.15.7 Catalina

二. ollvm移植(mac、linux通用,window上应该也通用)

移植的方法网上比较多,主要是从官网上 ollvm4.0 移植对应的 Obfuscation pass 到高版本 llvm上。如果llvm版本相差太大,可能有的结构体或者方法会有些许改变,编译的时候就会报错,本人的解决方法是将LLVM工程导入到 CLion 中,针对报错的代码,对比高低版本llvm使用的改变(Find in file功能),然后将 Obfuscation pass 中报错代码修正。

1. 导入步骤:

  1. 用 CLion 打开 Obfuscate/llvm/CMakeLists.txt ,选择 open as project;

  2. 在 File | Settings | Build, Execution, Deployment | CMake 的 CMake options 中配置编译选项,Build Type选Release就快一些,编译选项如下:

    # 使用 ninja
    -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=Off
    # 默认使用 make
    -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=Off
    # 如果要移植到的 NDK 或者 xcode 的toolchain中包含 lib64,则还需添加 
    # -DLLVM_LIBDIR_SUFFIX=64
    
  3. 在 File | Settings | Build, Execution, Deployment | Toolchains 中配置 C++编译器是使用 g++还是clang++,C编译器是使用 g 还是 clang,Make是选择 make 还是ninja。这一步其实默认就可以。

cmake 完成后,开始 Build-Build Project 构建工程,如果有报错会在下边栏中给出错误信息和错误代码位置,点过去就可,方便排查错误。另外用CLion的好处还有就是可以跟踪符号,直接点击便可跳转代码。

2. 具体的移植步骤

  1. llvm-project/llvm/include/llvm/Transforms/Obfuscation -----> llvm12_root/ ; (目录层级得一样,下同)
  2. llvm-project/llvm/lib/llvm/Transforms/Obfuscation -----> llvm12_root/ ;
  3. llvm-project/llvm/include/llvm/CryptoUtils.h -----> llvm12_root/ ;
  4. llvm-project/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp 中添加
// Flags for obfuscation
static cl::opt<bool> Flattening("fla", cl::init(false),
                                cl::desc("Enable the flattening pass"));

static cl::opt<bool> BogusControlFlow("bcf", cl::init(false),
                                      cl::desc("Enable bogus control flow"));

static cl::opt<bool> Substitution("sub", cl::init(false),
                                  cl::desc("Enable instruction substitutions"));

static cl::opt<std::string> AesSeed("aesSeed", cl::init(""),
                                    cl::desc("seed for the AES-CTR PRNG"));

static cl::opt<bool> Split("split", cl::init(false),
                           cl::desc("Enable basic block splitting"));

static cl::opt<bool> StringObf("sobf", cl::init(false),
                               cl::desc("Enable the string obfuscation"));

PassManagerBuilder::PassManagerBuilder() {
    OptLevel = 2;
   	...
    CallGraphProfile = true;

	//ollvm add begin
    // Initialization of the global cryptographically
    // secure pseudo-random generator
    if (!AesSeed.empty()) {
        if (!llvm::cryptoutils->prng_seed(AesSeed.c_str()))
            exit(1);
    }
    //ollvm add end
}

void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
    // Load sample profile before running the LTO optimization pipeline.
   	...
    // Infer attributes about declarations if possible.
    PM.add(createInferFunctionAttrsLegacyPass());
	
	//ollvm add begin
    PM.add(createSplitBasicBlock(Split));
    PM.add(createBogus(BogusControlFlow));
    if (Flattening) {
        // Lower switch
        PM.add(createLowerSwitchPass());
    }
    PM.add(createFlattening(Flattening));
    PM.add(createSubstitution(Substitution));
    PM.add(createStringObfuscation(StringObf));
	//ollvm add end
	
    if (OptLevel > 1) {
        ...
    }
    PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true));
}

  1. llvm-project/llvm/lib/Transforms/CMakeLists.txt 中添加:
add_subdirectory(Obfuscation)
  1. llvm-project/llvm/lib/Transforms/IPO/CMakeLists.txt 中添加:

    add_llvm_component_library(
    ...
    Obfuscation
      )
    

    llvm12中已经弃用 LLVMBuild.txt,这一项本来是加在 llvm-project/llvm/lib/Transforms/IPO/LLVMBuild.txt 中,现在改到加在这里。
    移植的 ollvm12.x (兼 Armariris 字符串加密)已上传至:https://github.com/Chenyangming9/llvm-project/tree/release/ollvm12.x

三. ollvm 整合到工具链中使用

不管是哪个平台,最好先事先看下原来的llvm的版本 (命令:clang --version),然后将ollvm移植到对应的llvm版本中。

1. Android NDK

git clone ollvm代码地址
mkdir llvm_root/build_release # CLion中默认生成在 cmake-build-release 或 cmake-build-debug
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='clang'  -DLLVM_INCLUDE_TESTS=OFF -DLLVM_LIBDIR_SUFFIX=64 ../llvm #大多的NDK中有 lib64,所以添加-DLLVM_LIBDIR_SUFFIX=64,xcode中没有,不用加。为什么加 -DLLVM_ENABLE_PROJECTS='clang',因为 Obfuscation pass会编译进 clang,所以要加该项
ninja -j7 
# 如果有命令找不到,则按照 官网 [https://releases.llvm.org/12.0.0/docs/GettingStarted.html](https://releases.llvm.org/12.0.0/docs/GettingStarted.html) 中说明配置

编译完成后,将 llvm_root/build_release 中 bin 、include、lib、lib64 覆盖拷贝到 android-ndk/toolchains/llvm/prebuilt/linux-x86_64 中即可。

2. xcode 中集成

(1)编译

git clone ollvm代码地址
mkdir llvm_root/build_release # CLion中默认生成在 cmake-build-release 或 cmake-build-debug
cmake -DLLVM_CREATE_XCODE_TOOLCHAIN=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='clang' -DLLVM_INCLUDE_TESTS=OFF ../llvm #大多的NDK中有 lib64,所以添加-DLLVM_LIBDIR_SUFFIX=64,xcode中没有,不用加。为什么加 -DLLVM_ENABLE_PROJECTS='clang',因为 Obfuscation pass会编译进 clang,所以要加该项
make install-xcode-toolchain -j10
# 编译完成后生成的工具链位于 /usr/local/Toolchains,将其移动到 /Library/Developer/ 目录
sudo mv /usr/local/Toolchains /Library/Developer/

DLLVM_CREATE_XCODE_TOOLCHAIN 选项参考:https://llvm.org/docs/CMake.html#llvm-related-variables

说明: 之前尝试使用 -G “Xcode”,则可以在 xcode 中打开工程,但报错如下:

CMake Error in utils/benchmark/CMakeLists.txt:
The custom command generating
/usr/local/Toolchains/LLVM12.0.0.xctoolchain
is attached to multiple targets:
install-xcode-toolchain
install-xcode-toolchain-stripped
but none of these is a common dependency of the other(s). This is not
allowed by the Xcode "new build system".

找不到解决方法,就弃用了,哎。

(3)xcode 中使用

打开后 xcode 后,在 Xcode-Preferences-Components-Toolchains看到生成好的工具链,如下图:
在这里插入图片描述
或者:Xcode-Toolchains中查看到,如下图:
在这里插入图片描述
更换工具链,在以上两个位置都可以更换。使用新工具链编译 Xcode 项目,报错unknown argument: ‘-index-store-path’,需要到项目 Build Settings 关闭 Index-While-Building,应该是这个参数在开源的 LLVM 项目中没有实现。如下:
在这里插入图片描述
关闭该选项,如下图:在这里插入图片描述
添加 ollvm 编译选项,-mllvm -fla -mllvm -sub -mllvm -bcf -mllvm -sobf
在这里插入图片描述

(4)xcode 中混淆后的效果

混淆前:
在这里插入图片描述
混淆后:
在这里插入图片描述
如果文章不错,也请多支持,如果有不对的地方,也请多指正~

四. 参考

  1. llvm 官网
  2. [iOS 逆向 13] 代码混淆

标签:集成,llvm,cl,xcode,ios,add,ollvm,ollvm12,DLLVM
来源: https://blog.csdn.net/Denny_Chen_/article/details/122480182