llvm学习(四):移植到 Android,让 NDK 加载我们的 Pass

emmmmm 搞了一天的移植和交叉编译,是真真的脑阔疼,本来想把这部分内容放在后面,但好不容易折腾出来,趁热写掉吧。不出意外的话,全网首发?突然感觉高大上了起来有木有!

2018.11.10更新,请直接跳到文末第九段。

2019.3.21再次更新,本文内容很多都是弯路,请选择性阅读,建议看第九篇文章。

2019年10月26日17:21:10:因为 NDKr19提供了更优雅的实现,本文已失效,将来会有更优秀的文章更新,下文请选择性阅读。

2019年11月15日15:47:10:删除本文大部分内容。覆盖NDK的clang请阅读第九篇文章,最优雅的方式请阅读第十一篇文章《史上最优雅的NDK加载pass方案》

一、背景

操作系统:MacOS NDK 版本:当时最新版,r18 其他环境与前几篇一模一样(毕竟我只有这一台电脑) 背景是这样,前段时间pass 写的差不多了,平时都是用 Mac 的 clang,编译出 Mac 上的可执行文件(大概叫 Mach-O),运行查看结果;今天计划移植到 Android 上看看效果,本来以为不会出啥大事,结果便花了一整天的时间在搞这玩意。我不是安全工程师了,请叫我编译工程师。。。 网上流行的方法都是使用重新编译 clang 的方式,至少我查到的是这样子的,非常不优雅,看着很难受,但没有前人搞过啊,问了身边的小伙伴,确实是按照网上常见的方式做的,于是只能硬着头皮上了。。 本文记录一下踩过的坑和正确的移植方式。

二、NDK 基本操作,创建 standard toolchain(新版 NDK 已经没有这种操作了,已删除)

三、失败的尝试:直接加载我们的 Pass(防止误导,已删除)

四、失败的尝试:覆盖 toolchain 里的可执行文件 clang(防止误导,已删除)

五、失败尝试:覆盖 toolchain 里真正的 clang(防止误导,已删除)

六、失败的尝试:编译toolchain 里一模一样的 clang(防止误导,已删除)

七、成功的尝试(防止误导,已删除)

八、总结(防止误导,已删除)

=========上文全是弯路,直接给一个最终方案吧,错误的路上走了好远=======

九、直接覆盖 NDK 里的 LLVM(小于等于ndk-r18)

对,看起来很暴力,但很有效。

1
2
3
4
5
➜  tmp cd $ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/
➜ darwin-x86_64 rm -rf bin lib64 libexec share
➜ darwin-x86_64 cp -r $LLVM_HOME/* .
➜ darwin-x86_64 cd .....
➜ ndk-bundle build/tools/make-standalone-toolchain.sh --platform=android-16 --install-dir=/tmp/my-android-toolchain

【2019.2.13更新:ndk-r19使用了llvm8.0,与7.0不同的是,8.0的库文件目录是lib64,7.0的库文件目录是lib,不能瞎 jb 换。(这个结论是错的)】

【2019.3.21更新:ndk-r18只有lib64,ndk-r19有lib和lib64,多出来一个lib目录,经考证,lib目录存放交叉编译时其他平台的一些文件,不能删掉。所以临时的解决方案是:将 $LLVM/HOME/lib 里的内容全部复制到里面去。以及,请阅读本系列第九篇文章。

十、ndk-clang 和my-clang到底有什么区别?(防止误导,已删除)

=======2019.3.21二者没什么区别,下文内容是表象,实质请看第九篇文章=======