首页
社区
课程
招聘
[原创]Ollvm整合到XCode中的几种方法
发表于: 2025-6-10 21:23 138

[原创]Ollvm整合到XCode中的几种方法

2025-6-10 21:23
138

我是去年10月左右开始研究Ollvm,现将一部分心得分享出来

## 基本概念

LLVM Pass按加载方式分类:

* `静态Pass`,即将Pass逻辑编译到`clang/opt`中,通过给`clang/opt`传递适当参数触发Pass。如果目标语言和编译环境不支持命令行方式指定Pass则可尝试此方式。目前大部分开源Ollvm项目都是此种方式,且一定程度修改了LLVM源码部分

* `动态Pass`,即将Pass逻辑编译为独立动态库,通过给`clang/opt`传递适当参数触发Pass。如果目标语言和编译环境不方便使用自定义`clang/opt`但支持命令行方式指定动态Pass则可尝试此方式,此方式在Pass开发编译调试时优势明显。

## 常见问题

* `动态Pass`和`LLVM`版本要匹配吗?是的,至少大版本要匹配否则大概率崩

* 开发`动态Pass`给`XCode`使用以实现`Ollvm`混淆的思路可行吗?可行

* 直接针对`XCode`的`Apple Clang`开发`动态Pass`可行吗?可行

## XCode使用Pass的方式(以下方式笔者均验证过可行)

* `静态Pass`方式1,编译为`XCode Toolchain`,也是目前大部分开源`Ollvm`项目所采用的方式。不过编译时间久一些且`Toolchain`占用的存储空间也大一些。

* `静态Pass`方式2,直接使用`clang`,在`Xcode`中指定`CC`变量为内嵌`Pass`的`clang`。如果`isysroot`不兼容可能需要在`Other C Flags`中覆盖

* `动态Pass`方式3,在Xcode中指定`CC`变量为开源`clang`(如`brew install llvm@15`),且指定`Other C Flags`指定`-fpass-plugin`为对应`Pass`路径

* `动态Pass`方式4,在`Xcode`中指定`CC`变量为编译脚本,脚本逻辑为"先用`clang -emit-llvm`参数生成`bitcode`,然后运行`opt`执行`Pass`,最后用`clang -c`生成原本要生成的obj文件"。此种方式可以直接使用`Xcode`自带的`Apple clang`,能比较好的兼容`arm64e`架构

* `动态Pass`方式5,直接针对Xcode自带的`Apple clang`开发`动态Pass`,在Xcode中指定`Other C Flags`指定`-fpass-plugin`为Pass路径。此种方式复杂度较高,只适合精通llvm编译的开发者。此种方式可以直接使用`Xcode`自带的`Apple clang`,能比较好的兼容`arm64e`架构

## 针对`AppleClang`开发`动态Pass`

现在来看看最难的部分,如果直接使用`AppleClang`对应版本的开源LLVM开发Pass给`AppleClang`使用是会崩溃的,因为`AppleClang`相对于开源LLVM魔改了很多地方。为了让`AppleClang`能运行起来一个最简单的`Pass`你至少需要如下hacker代码:

```c

class Ollvm : public PassInfoMixin<Ollvm> {

public:

    PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM) {

        M.dump();

#ifdef APPLE_CLANG

        static PreservedAnalyses (*PreservedAnalyses__all)() = 0;

        static PreservedAnalyses (*PreservedAnalyses__none)() = 0;

        if (PreservedAnalyses__all == 0) {

            const char* image = _dyld_get_image_name(0);

            PreservedAnalyses__all = (__typeof(PreservedAnalyses__all)) DobbySymbolResolver(image, 

                "__ZN4llvm6detail9PassModelINS_6ModuleEN12_GLOBAL__N_114NoOpModulePassENS_17PreservedAnalysesENS_15AnalysisManagerIS2_JEEEJEE3runERS2_RS7_");

            PreservedAnalyses__none = (__typeof(PreservedAnalyses__none))DobbySymbolResolver(image, 

                "__ZN4llvm6detail9PassModelINS_6ModuleENS_25InvalidateAllAnalysesPassENS_17PreservedAnalysesENS_15AnalysisManagerIS2_JEEEJEE3runERS2_RS6_");

        }

        return (opc > 0) ? PreservedAnalyses__all() : PreservedAnalyses__none();

#else

        return (opc > 0) ? PreservedAnalyses::all() : PreservedAnalyses::none();

#endif

    };

    static bool isRequired() { return true; }

};

```

以上操作仅仅是让你“入门”,而下一步就是处理`AppleClang`魔改造成的冲突,包括但不限于拆分静态库/自行实现冲突代码,也是个复杂且麻烦的工程了,有兴趣的可以接着研究下去



[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2025-6-10 21:25 被lichaolich编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 4102
活跃值: (3207)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
现在开源的基本都是直接修改llvm编译clang,这种情况跟实际使用差别很大,因为每个编译器的编译参数,内置选项都可能不同,从而导致官方编译器正常编译而自己的编译器会报各种编译问题,再加上windows上基本无法采用动态库加载,这些都大大限制了通用性.我在三年前就采用了 动态Pass方式4,并且是商业使用经过大量真实用户验证,切换之后未遇到任何兼容性问题,之前也打算公开的,但是现在看到作者已经提到了这种方式那么我就详细说明下

目前来看我认为从兼容性,适配难度,易用性都是 动态Pass方式4 最优的,总结以下几点:
1. 几乎兼容所有类型 clang 类型,因为它们都几乎都支持 clang -emit-llvm 包括swift, android-ndk, clang-cl 等等都支持
2. 混淆只处理 bc 或 ll 文件,只需要保证 bitcode兼容即可,通常保证LLVM大版本相同即可,对于不同类型的clang应该找到它对于的开源仓库构建LLVM避免兼容性问题, ll文本模式兼容性更好,它甚至可以向前和向后兼容
3. 通过 wrapper 的方式不需要动态库,因此在静态链接,windows上都可行,可以完美支持 windows,linux,macos
4. 编译过程都使用官方 clang,因此不存在编译参数,默认配置导致的编译问题
5. 混淆之后还可以利用官方 clang 进一步优化bitcode,开源方案混淆通常是在 bitcode pass优化中的最后一个,这导致生成的代码性能略差,以及反编译后混淆特征更明显,只是要注意混淆的效果不要直接被编译器优化掉,例如虚假控制流就很容易被LLVM Pass优化掉
6. 更好的传递混淆参数,开源方案基本都只能通过 -mllvm -fla 或者实现 __attribute__((annotate("fla"))), 这种方式由于混淆是一个单独的工具,因此可以完全控制参数传递方式

简要编译实现过程
原始编译流程
clang -c -x c++ test.cpp -o test.o
混淆流程
clang -c -x c++ test.cpp -emit-llvm -S -o test.ll
obf-tool test.ll -o test.ll
clang -c -x ir test.ll -o test.o

这里的 obf-tool 可以任意基于llvm pass 开发工具,或者直接在 opt 中实现
4天前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
北辰制作 现在开源的基本都是直接修改llvm编译clang,这种情况跟实际使用差别很大,因为每个编译器的编译参数,内置选项都可能不同,从而导致官方编译器正常编译而自己的编译器会报各种编译问题,再加上window ...
大佬是否方便给小白出点教程?
4天前
0
雪    币: 4102
活跃值: (3207)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
mb_cpwlanod 大佬是否方便给小白出点教程?
后续会出教程的,这种方式虽然好但还是有很多细节的地方要处理
4天前
0
游客
登录 | 注册 方可回帖
返回