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(与clang和llvm无关)

在新一点的 NDK 里,是没有各个平台独立的库文件和头文件的,使用的是公共的部分和差异的部分,这个技术叫什么我忘记了,反正和旧版的不一样,可能老玩家都踩过这个坑。

话不多说,读者自己去搞吧,基本操作

https://developer.android.com/ndk/guides/standalone_toolchain

这里官网的介绍里,中文和英文的命令参数完全不一样,不知道是不是没有及时更新还是什么,根据情况自己操作吧。我随便找了个低版本的 android,用的是 arm。

新版的 NDK 里,默认使用的就是clang了,不是 gcc,不需要额外设定什么东西。

成功后大概如下图,记得把那个 bin 加到 PATH 里。

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

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

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

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

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

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

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

 

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

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

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二者没什么区别,下文内容是表象,实质请看第九篇文章=======


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code