首页
社区
课程
招聘
[原创]一种将LLVM Pass集成到NDK中的通用方法
发表于: 2022-1-24 23:10 50051

[原创]一种将LLVM Pass集成到NDK中的通用方法

2022-1-24 23:10
50051

关于“如何将自己写的LLVM Pass集成到NDK中”这个问题,目前网上并没有很完美的方法,并且大多数已经过时。经过我的一番折腾,最终摸索出了一种比较简单实用的方法,可供参考。

简单来说,本文要介绍的方法是下载NDK中llvm-android部分的源码,在llvm-android中的llvm-project子项目中加入自己的Pass后与整个项目一起编译,用编译好的文件替换掉NDK中的工具链。
该方法有以下优点:

当然也有缺点:

本文并不是直接将最终的操作方法摆在大家面前,还讲解了为什么要这么操作,因此过程会显得较冗长,需要有一点耐心看下去。

如果是Windows,首先需要准备Linux虚拟机进行交叉编译,因为NDK不支持在Windows上直接编译,我这里使用的是Ubuntu 20.04.3;macOS则不需要。NDK版本我选择的是23.1.7779620
本文以Windows+Linux虚拟机为例讲解,macOS下的操作大同小异。
以下使用的指令全部以root权限执行。

NDK使用的是git-repo这一工具管理,而不是git,所以首先需要安装git-repo

上面这个地址需要科学上网才能访问,我们可以换成国内的清华源:

$NDK_PATH\toolchains\llvm\prebuilt\windows-x86_64\AndroidVersion.txt中查看NDK使用的LLVM版本,在我使用的NDK中,AndroidVersion.txt 的内容是:

https://android.googlesource.com/toolchain/llvm_android/中找到对应版本的 llvm-android 源码:
图片描述
Google的文档中给出了下载 llvm-android 源代码的方法,但这里默认下载的是最新版本:

我们需要做一些操作来换成我们想要的版本,在$NDK_PATH\toolchains\llvm\prebuilt\windows-x86_64目录下找到一个 manifest_xxxx.xml 文件,我这里是 manifest_7714059.xml。执行完下列指令后:

将 manifest_7714059.xml 复制到.repo/mainifests文件夹中(注意.repo是隐藏文件夹,并且从Windows复制到Linux会有格式转换的问题,这里建议使用VSCode的SSH-Remote插件避免上述问题):
图片描述
继续执行:

这里也要把Google的地址换成清华源,替换规则见 Android 镜像使用帮助,替换后完整的指令如下:

并且 manifest_7714059.xml 中的包含地址也要替换,否则即使科学上网,在下载的时候也非常慢:
图片描述
repo sync -c指令会下载一大堆的源代码和预编译文件,需要耗费十来分钟的样子,喝杯茶慢慢等吧。

在编译之前需要提前安装一些环境,否则编译会出错:

如果是在Ubuntu 20.04.3下还需要做一个软链接,否则会报错ImportError: libffi.so.6: cannot open shared object file: No such file or directory。具体操作如下:
图片描述
然后就可以开始愉快且漫长的编译了(大概需要一两个小时,取决于机器性能):

因为我是在Windows环境使用NDK,所以无需编译Linux下的toolchain,这里加上--no-build linux参数。
另外编译的时候最好把虚拟机内存开到8G以上,我开的是8G内存,编译的时候还会因为内存不足时不时中断,如果中断了重新运行编译指令就好。
编译结束后可以在out文件夹中找到编译好的内容:
图片描述

在这里我要推销一下我的项目Pluto-Obfuscator ,如果使用的是OLLVM, Armariris等,需要注意一下版本适配的问题。
此时我们需要向toolchain/llvm-project/llvm/lib/Transforms/Obfuscation/中加入自己的代码:
图片描述
toolchain/llvm-project/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp中加入几段代码:
图片描述
图片描述
修改toolchain/llvm-project/llvm/lib/Transforms/IPO/CMakeLists.txt
图片描述
改好之后重新编译,重新编译的速度会快很多,一分钟左右就能搞定:

编译好后out/install/windows-x86/clang-dev中对应的就是NDK中的toolchains\llvm\prebuilt\windows-x86_64部分:
图片描述
图片描述
少了一些东西,但是无关紧要,我们直接替换就好。

我复制了一份NDK,命名为pluto-r23,并将其中toolchains\llvm\prebuilt\windows-x86_64文件夹里的内容替换成我们刚刚编译的内容:
图片描述
随便写一个Native项目测试:
图片描述
设置NDK地址:
图片描述
加上混淆参数:
图片描述
编译然后查看混淆效果:
图片描述
X86架构和ARM架构均混淆成功:
图片描述
图片描述

curl https://storage.googleapis.com/git-repo-downloads/repo > /usr/bin/repo
chmod a+x /usr/bin/repo
curl https://storage.googleapis.com/git-repo-downloads/repo > /usr/bin/repo
chmod a+x /usr/bin/repo
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > /usr/bin/repo
chmod a+x /usr/bin/repo
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > /usr/bin/repo
chmod a+x /usr/bin/repo
12.0.8
based on r416183c1
12.0.8
based on r416183c1
mkdir llvm-toolchain && cd llvm-toolchain
repo init -u https://android.googlesource.com/platform/manifest -b llvm-toolchain
repo sync -c
mkdir llvm-toolchain && cd llvm-toolchain
repo init -u https://android.googlesource.com/platform/manifest -b llvm-toolchain
repo sync -c
mkdir llvm-toolchain && cd llvm-toolchain
repo init -u
mkdir llvm-toolchain && cd llvm-toolchain

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-3-28 21:41 被34r7hm4n编辑 ,原因:
收藏
免费 14
支持
分享
最新回复 (40)
雪    币: 9004
活跃值: (6220)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2022-1-25 04:13
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2022-1-25 08:58
0
雪    币: 5330
活跃值: (5464)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
ma
2022-1-25 09:53
0
雪    币: 3064
活跃值: (7808)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2022-1-25 12:10
0
雪    币: 657
活跃值: (1572)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6

大佬您好,在向您进行学习的过程中,遇到了一些小问题

已提交至GitHub的issues

也希望有关大佬可以指点一二

2022-2-17 17:02
0
雪    币: 4752
活跃值: (2923)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7

哥们,你既下载了源码、修改了llvm源码、编译了llvm、还替换了NDK,和大家公开的方案区别就在 “下载源码”和 “编译llvm” 的过程不一样吧。

我的优点我也列出来了:
不需要编译llvm
仅依赖NDK,不需要额外的其他环境
不会遇到配置引起的符号NotFound问题
不污染NDK

因此,我没有明白你哪来的自信说我方案的不优雅。

最后于 2022-2-18 10:04 被LeadroyaL编辑 ,原因:
2022-2-18 10:03
2
雪    币: 463
活跃值: (2696)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
8
感谢分享,这个思路就是重新编译一份完整的llvm,leadroyal的方案是直接使用ndk环境做pass,对ndk环境的破坏来看,可能leadroyal的更好点。但是重新编译完整llvm,目前也没有出现什么问题。
2022-2-18 10:10
1
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
9
LeadroyaL 哥们,你既下载了源码、修改了llvm源码、编译了llvm、还替换了NDK,和大家公开的方案区别就在 “下载源码”和 “编译llvm” 的过程不一样吧。我的优点我也列出来了:不需要编译 ...
冒犯到你不好意思,我并没有要贬低什么的意思,只是与其他方法做一个对比。原文已经删除。
2022-2-18 11:31
0
雪    币: 657
活跃值: (1572)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
Ssage泓清 大佬您好,在向您进行学习的过程中,遇到了一些小问题已提交至GitHub的issues也希望有关大佬可以指点一二

issues问题已经解决,建议使用服务器环境对楼主方法进行复现的朋友 

严格注意文件格式问题,否则在移植ndk-r23b版本的过程中 

很可能出现因为文件格式损坏而导致的报错~ 详细请参考issues

最后于 2022-2-18 20:50 被Ssage泓清编辑 ,原因:
2022-2-18 20:49
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
11
Ssage泓清 Ssage泓清 大佬您好,在向您进行学习的过程中,遇到了一些小问题已提交至GitHub的issues也希望有关大佬可以指点一二 issues问题 ...
感谢你的详细解释。TrapAngr和RandomControlFlow都需要插入rand函数,应该是这个原因导致在ARM下编译失败,我之后会排查一下。
2022-2-18 21:53
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
整合后用
       
python toolchain/llvm_android/build.py --no-build linux

出现的错误

已经安装了libz3-dev

/home/x/ollvm/llvm-toolchain/out/llvm-project/llvm/include/llvm/Transforms/Obfuscation/MBAUtils.h:1:10: fatal error: 'z3++.h' file not found
#include "z3++.h"
2022-3-11 15:10
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
13
mb_ipugnluu 整合后用 python toolchain/llvm_android/build.py --no-build linux 出现的错误 已经安装了libz3-dev /home ...
安装依赖
sudo apt install libz3-dev 
2022-3-11 15:15
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
34r7hm4n 安装依赖 sudo apt install libz3-dev
已经安装过了
但是还是报错
2022-3-11 15:22
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
libz3-dev 已经是最新版 (4.8.7-4build1)
2022-3-11 15:23
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
16
mb_ipugnluu 已经安装过了 但是还是报错
可能在NDK的环境下会有问题,我之后去试试
2022-3-11 15:52
1
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
34r7hm4n 可能在NDK的环境下会有问题,我之后去试试
大佬加油
2022-3-11 17:17
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
34r7hm4n 可能在NDK的环境下会有问题,我之后去试试
大佬,有解决办法吗
2022-3-13 10:15
0
雪    币: 181
活跃值: (2943)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
请教下
直接mac编译https://github.com/bluesadi/Pluto-Obfuscator master分支后,移植到ndk 23.1.7779620后
报错ld: error: unable to find library -latomic
find了一下这个文件,没有可用的呀
2022-3-20 17:07
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
20
mb_ipugnluu 大佬,有解决办法吗
最近有点忙,会尽快解决的
2022-3-26 22:40
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
34r7hm4n 最近有点忙,会尽快解决的
加油
2022-3-28 22:11
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
22
mb_ipugnluu libz3-dev 已经是最新版 (4.8.7-4build1)
已修复:
见 https://github.com/bluesadi/Pluto-Obfuscator/issues/12
2022-4-6 22:13
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
34r7hm4n 已修复: 见 https://github.com/bluesadi/Pluto-Obfuscator/issues/12
楼主,你源码里面有个MBAUtils copy.cpp的文件没删除,如果没删除的话,编译必报错
2022-4-10 22:33
0
雪    币: 14303
活跃值: (10779)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
24
mb_ipugnluu 楼主,你源码里面有个MBAUtils copy.cpp的文件没删除,如果没删除的话,编译必报错
这个可以删掉
2022-4-10 23:25
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
NDK23 版本 ub系统 下 编译完成  MBA fla gle 无法启用  ( 最新版本Pluto 
2022-7-20 22:59
0
游客
登录 | 注册 方可回帖
返回
//