Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ndk-r23b版本 重编译后无法使用 #6

Closed
SsageParuders opened this issue Feb 17, 2022 · 23 comments
Closed

ndk-r23b版本 重编译后无法使用 #6

SsageParuders opened this issue Feb 17, 2022 · 23 comments

Comments

@SsageParuders
Copy link

SsageParuders commented Feb 17, 2022

您好~在发出这份issues之前,我已经仔细拜读了您在看雪论坛的文章,并且在服务器环境尝试复现,但是我遇到了一些问题,请允许我向您详细说明,希望能获得您的帮助,感谢~


复现环境

  • 服务器:Ubuntu 20.04 x64
  • 目标NDK:23.1.7779620
  • 添加的PASS:Pluto-Obfuscator

操作方式

其实就是按照您在看雪论坛的介绍来走的
已经重复操作3次 应该没有漏掉什么步骤
下面我简单描述一下操作步骤

  • 下载repo
    curl https://storage.googleapis.com/git-repo-downloads/repo > /usr/bin/repo
    chmod a+x /usr/bin/repo
  • repo下载对应版本的源码
    mkdir ndk-llvm && cd ndk-llvm
    repo init -u https://android.googlesource.com/platform/manifest -b llvm-toolchain
    cp $TOOLCHAIN_DIR/manifest_7714059.xml .repo/manifests
    repo init -m manifest_7714059.xml
    repo sync -c
  • 安装/修复必要环境
    sudo apt-get install cmake bison
    find /usr/lib -name libffi.so*
    ln -s /usr/lib/x86_64-linux-gnu/libffi.so.7 /usr/lib/x86_64-linux-gnu/libffi.so.6
  • 开始编译流程
    python toolchain/llvm_android/build.py --no-build linux
  • 添加PASS
    这一步大佬在看雪论坛的文章中 漏掉了一些小步骤
    不过无伤大雅 下面我简单对步骤进行概括
  • 添加/include/llvm/Transforms/Obfuscation <-- 此步大佬遗漏
  • 添加/lib/Transforms/Obfuscation
  • 修改/lib/Transforms/IPO/PassManagerBuilder.cpp三处代码
  • /lib/Transforms/IPO/CMakeLists.txt中添加Obfuscation
  • /lib/Transforms/CMakeLists.txt中添加Obfuscation <--此步大佬遗漏
  • 重新编译
    python toolchain/llvm_android/build.py --no-build linux

得益于大佬您的文章介绍,我的编译流程比较顺利,中间没有因为erro而产生中断


出现的问题

就好像 #5 遇到的问题一样
我使用的是ndk-build脚本, #5 貌似使用的是cmake,不过情况都是一样的
我们自己编译的 ndk-r23,在移植后出现一些报错情况,关键内容如下:

....../build/core/setup-toolchain.mk:111: pipe: No error
....../build/core/prebuilt-library.mk:45: *** Android NDK: Aborting    .  Stop.
....../sources/cxx-stl/llvm-libc++abi/Android.mk:unwind: LOCAL_SRC_FILES points to a missing file 
......Android NDK: Check that /lib/linux/arm/libunwind.a exists  or that its path is correct 

在参考了 #5 以后,我也查看了一下编译产物的格式

  • 这是我们自己编译的产物
    root@vultr:~/ndk-llvm-r416183c1/out/install/windows-x86/clang-dev/bin# file clang*
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     symbolic link to clang.exe
    clang++.exe:      symbolic link to clang.exe
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows
  • 这是从谷歌官网下载的ndk
    ❯ file clang*
    clang++.exe:      PE32+ executable (console) x86-64, for MS Windows
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows

如果可以,我也想看一看大佬编译产物的格式,确认这之间是否存在差异


自己尝试过的研究

我本人使用的是macOS,最初是想要按照大佬的思路去编译mac版本的toolchain。
不过我发现按照谷歌官方对toolchain/llvm_android步骤操作后,有且只有Windows版本和Linux版本的clang-dev。
没有android/toolchain/prebuilts/ndk-darwin/r23中的产物,遂将目光转移到Windows版本的PASS移植。
这里插一嘴,如果大佬知道macOS版本的toolchain如何编译的话,烦请指点。

  1. 既然说按照大佬的文章操作,我这里出现了一点点问题,那么换一个角度。
    我在macOS上按照常规方法操作,将大佬的项目clone下来以后,按照README的说法,使用cmake对大佬的项目进行构建。
    即:添加PASS再编译llvm以后,将bin目录生成的工具替换到ndk中的toolchain里面去。
    同时将编译后的lib64添加到ndk中toolchain的lib64里面去,同时修复头文件缺失问题以后。

    关于llvm编译后生成lib64目录
    如果我们单独在编译llvm时,为了适配ndk,应该对cmake编译添加参数 -DLLVM_LIBDIR_SUFFIX=64 ,即可让lib自动重命名为lib64,以此解决环境依赖问题,详细请参考Google的build.py脚本
    遗憾的是,在移植完成以后,`ndk-build`依然报错,由于未能及时记录报错信息,这里的erro无法进行展示,抱歉。 同时,我观察到,ndk中toolchain的clang-12约100+MB,可是我编译的貌似只有1MB大小,这是否是因为我仅只是clone了大佬的项目,直接进行编译,而没有将他们移植到整个llvm-project中导致的?
  2. 会不会在编译进PASS之前,bin目录的文件格式正常?
    抱着这种想法,我重开项目,并且在没有添加PASS情况下,编译出了out产物。
    很遗憾的是,我发现,对于ndk-r23b来说,即使我们没有添加PASS,他的编译产物格式依然如下:

    root@vultr:~/ndk-llvm-r416183c1/out/install/windows-x86/clang-dev/bin# file clang*
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     symbolic link to clang.exe
    clang++.exe:      symbolic link to clang.exe
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows

    也就是说,我们自己编译的ndk-r23b的toolchain,就是和谷歌官方不一样的文件格式,即使没有添加进PASS

  3. 我的第二个分析,似乎是在说明,我们自己编译的toolchain是错误的,无法使用,但是谷歌官方的教程:Instructions to rebuild a particular toolchain release似乎也就是这样,我们并没有遗漏掉什么。
    不甘心放弃,于是,我对老版本的ndk-22.1.7171670进行编译,发现了有意思的事情。
    对老版本ndk-22.1.7171670进行编译以后,我对编译产物进行file发现:

    root@vultr:~/ndk-llvm-r416183c1/out/install/windows-x86/clang-dev/bin# file clang*
    clang++.exe:      PE32+ executable (console) x86-64, for MS Windows
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows

    按照这种方式,编译的老版本ndk居然是正常的!没有出现所谓的symbolic link to clang.exe
    果断添加PASS重新编译 --> 再次file -- > 文件格式正常! --> 移植ndk -- > 测试ndk-build
    让人欣喜的事情来了,在file文件格式全部正常的情况下,使用ndk-build,编译过程没有任何问题!没有报错!
    到这里,我们至少确认了一件事,那就是,之前的报错就是因为file文件格式不正确导致的
    于是,添加混淆参数,进行混淆编译 --> 未混淆编译产物5kb,混淆后编译产物23kb
    貌似成功了?抱着激动的心情,打开ida,分别对比未混淆和混淆后,让我失望的事情来了,混淆前后在ida中的表现是一样的。
    也就是说,除了文件体积的变化外,文件并没有得到更安全的保护。

  4. 转念一想,大佬您的这款PASS是基于llvm-12编写的,也许他对老版本的ndk所采用的llvm-11是不生效的。
    于是,我换用了heroims大佬的PASS,移植结束以后
    file文件格式依然全部正常,编译流程没有erro <-- 这里再次证明,ndk-r23b的toolchain之所以报错,就是因为file格式问题
    很遗憾的是,虽然编译确实没有报错,混淆前后文件大小确实也产生变化,但是,使用ida进行查看的时候,混淆依然没有生效。

    顺便一提,我们ndk-r23b使用的是clang12,在heroims大佬项目的issues中
    我找到了libunwind.a有关报错的解决方案Why is libunwind required? heroims/obfuscator#7 (comment)
    导致该问题的原因,大概就是谷歌build.py脚本让lib自动重命名为lib64,产生的环境依赖问题
    但由于我们本身就应该是build.py构建的环境,不应该有这种报错才对


最后

至此,我已经无计可施,本以为是谷歌ndk在r23版本存在某种问题。
但是转念一想,大佬您已经在和我相同的ndk版本下,实测成功,并且上传了examples。
我认为,是我在某些步骤上的操作有所遗漏或者错误。
希望大佬能够分析一下我的流程有哪些地方存在问题,不胜感激~

@bluesadi
Copy link
Owner

编译结果的格式是没问题的,我这里跟你是一样的,不影响使用:

clang-check.exe:     PE32+ executable (console) x86-64, for MS Windows
clang-cl.exe:        symbolic link to clang.exe
clang++.exe:         symbolic link to clang.exe
clang.exe:           PE32+ executable (console) x86-64, for MS Windows
clang-format.exe:    PE32+ executable (console) x86-64, for MS Windows
clang-tidy.exe:      PE32+ executable (console) x86-64, for MS Windows
dsymutil.exe:        PE32+ executable (console) x86-64, for MS Windows
git-clang-format:    Python script, ASCII text executable
ld64.lld.exe:        symbolic link to lld.exe
ld.lld.exe:          symbolic link to lld.exe
liblldb.dll:         PE32+ executable (DLL) (GUI) x86-64, for MS Windows

至于你提到的错误我没有碰到过,也搞不明白为什么,或许可以试试不加Pass直接编译,看能否正常运行?

@SsageParuders
Copy link
Author

SsageParuders commented Feb 18, 2022

您好,经过排查,这个问题已经被解决。
感谢您的开源,我已经成功在最新的ndk-r23b用上了您的PASS。
(貌似ndk-r24b就要出来了 而且采用的是clang-14,直接跳过了clang-13)
下面,请允许我向您详细阐述导致该问题的因果(原因真是让人无语极了)。
另外,我将在这里上报您的PASS疑似存在的一些小问题,希望修复。


因果分析

  • 直接点明原因:文件格式问题
    问题的关键就出在,我是在Linux服务器环境编译的toolchain。

  • 首先,由于未知原因,Google的toolchain在ndk-r23b版本编译后,bin目录下的产物,有部分不再是PE32+ executable (console) x86-64, for MS Windows而是symbolic link to XXX,这是我们在服务器通过file命令得到的结果。

到这里为止,没有出现任何错误,接下来就是关键。

  • 我像之前的操作一样,打算直接从FinalShell通过ftp下载整个编译产物。
    很巧的是,我的服务器由于网络不够稳定,在此时断开了连接,为了更好的下载编译产物,我使用tar命令对编译产物进行压缩,然后再通过FinalShell下载压缩包。
    tar -zcvf /root/ndk-llvm/out/install/windows-x86/clang-12.tar.gz /root/ndk-llvm/out/install/windows-x86/clang-dev

值得一提的是,macOS有项特殊功能,就是对于软连接的工具,他会在左下角做特殊标记,右点软连接的工具,也有一个选项会叫做显示原项目。在解压了通过压缩包传递的编译产物后,我发现,这份压缩后再传输的编译产物与之前直接通过ftp下载得到的编译产物,有所不同。

  • 区别就在于,压缩包传输的编译产物,bin目录下的工具,有软连接的标识,而直接通过ftp下载的编译产物,软连接标识消失。之前我们在Linux环境下直接对编译产物进行file,结果如下:

    root@vultr:~/ndk-llvm-r416183c1/out/install/windows-x86/clang-dev/bin# file clang*
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     symbolic link to clang.exe
    clang++.exe:      symbolic link to clang.exe
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows

    于是,我再对通过ftp下载的编译产物,在macOS上进行file,发现结果如下:

    ❯ file clang*
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     empty  <-- 软连接作用消失
    clang++.exe:      empty <-- 软连接作用消失
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows

    立马对压缩包传输的编译产物进行file发现,其结果如下:

    ❯ file clang*
    clang++.exe:      PE32+ executable (console) x86-64, for MS Windows
    clang-check.exe:  PE32+ executable (console) x86-64, for MS Windows
    clang-cl.exe:     PE32+ executable (console) x86-64, for MS Windows
    clang-format.exe: PE32+ executable (console) x86-64, for MS Windows
    clang-tidy.exe:   PE32+ executable (console) x86-64, for MS Windows
    clang.exe:        PE32+ executable (console) x86-64, for MS Windows

此时,我意识到,直接ftp下载下来的编译产物,其软连接功能被破坏,如果所料不错,这就是导致我和 #5 出现报错信息的根本原因,至于ndk-r22b不存在这个问题,是因为ndk-r22b本身在Linux下的file信息中,就没有软连接情况,直接ftp下载没有破坏其中关键文件。

于是,我将编译产物压缩包传入Windows,在Windows内解压,对比直接ftp下载的编译产物,发现了其中差别。

  • ftp直接下载的编译产物,在Windows下表现为应用程序,并且是一个大小仅只有0~2kb的,没有任何功能,或者功能残缺的应用程序。
    image
  • 而通过压缩包传输的编译产物,在Windows下表现为.symlink,即使他一样是0~2kb,我认为,这其中性质是不一样的。
    image

确认了问题所在后,我果断将压缩后再传输的编译产物,也就是保有软连接信息的编译产物,往ndk进行移植,果然,一切正常!

这里顺便提一点,请最好不要直接把编译后的产物直接覆盖到ndk的toolchain,经过观察,lib64目录下,依然有一些相关依赖,是谷歌原生toolchain特有的,而我们自行编译的toolchain中,lib64是有部分内容缺失的,这缺失会在某种情况下,导致依赖缺失问题,就比如l/lib64/clang/version/......libs/ibunwind.so,我们是没有的。而据我所知,有关项目会对该依赖存在需求。

因此,在移植的过程中,我建议细致一点,秉持着原生toolchain和我们的重复了,就替换成我们的,原生toolchain存在,而我们没有的,就不去直接覆盖整个目录(覆盖上层目录会导致下层目录中,ndk原有的,而我们没有的,消失不见)

并且,在我将整体处理好后的ndk-r23b,进行压缩,分享给我的好友时,我发现了一个有趣的小现象。
我们将带有.symlink属性的移植好了的ndk,整体打包成压缩包后,再解压的时候。
原先bin目录下,只有0~2kb的.symlink属性的软连接工具,会变成等同于被软连接工具的大小,比如:
image
注意,在被压缩后再解压之前,clang++只是个0~2kb的,对clang软连接的工具。
而将处理好的ndk压缩后再解压以后,clang++就变成了如图所示,大小等同于clang的,真正的Windows的应用程序~~
并且经过实测,功能没有缺失~~


当前PASS存在的问题

  1. Trap Angr功能存在问题,编译时提示:

    报错日志
    [armeabi-v7a] Executable     : Inject
     ld: error: undefined symbol: rand
     >>> referenced by PtraceInject.cpp
     >>>               ./obj/local/armeabi-v7a/objs/Inject/PtraceInject.o:(genrand.6408c38e44e96567)
     >>> referenced by PtraceInject.cpp
     >>>               ./obj/local/armeabi-v7a/objs/Inject/PtraceInject.o:(genrand.b6cf3c495bc5c85a)
     >>> referenced by PtraceInject.cpp
     >>>               ./obj/local/armeabi-v7a/objs/Inject/PtraceInject.o:(genrand.214a0237b0e3b1f5)
     >>> referenced 38 more times
     clang++: error: linker command failed with exit code 1 (use -v to see invocation)
     make: *** [C:/WorkSpace/android-ndk-r23b-obfuscator/build//../build/core/build-binary.mk:728: obj/local/armeabi-v7a/Inject] Error 1
     make: Leaving directory 'C:/WorkSpace/混淆样品/测试源码/Demo/outputs'
  2. 随机控制流存在问题

    最开始我随便开启了几个混淆参数,运行正常,ida打开查看,混淆成功。
    但是当我对编译产物进行测试时,发现编译产物无法按照混淆前一样,正常运行。
    经过排查,确认问题是出在随机控制流上面,其他混淆方法进行混淆后,全部执行正常。

    Trap Angr的问题不同的是,随机控制流在编译时不存在报错现象。
    ida查看编译产物确实也发现了一定的变化,但奇怪的是,混淆产物居然比起混淆前,更小巧了?
    我的测试样品是一份Inject,混淆前是22kb,随机控制流之后居然是17kb?
    ida视图确实发生变化,然而编译产物已经无法正常运行,表现情况为卡死。
    其他混淆模式,经测试,结果正常。


最后

如上所述的两个bug,也不知道是我自身问题,还是大佬您的PASS有所疏忽。
希望大佬有时间的话,可以排查一番。
如果需要我的测试样品,大佬请在issues告知,我将配合上传混淆样品。
(实际上,他只是一个普通的ptrace Inject注入器罢了)


另外,由于我的主环境是macOS,可是buily.py编译出来的只有Linux和Windows环境的toolchain。
在翻看了一下Google开源代码树后,我貌似依然没有找到如何编译darwin-x86_64版本的toolchain的方案。
如果大佬知道如何编译macOS版本的toolchain,烦请指点,不胜感激~


@SsageParuders
Copy link
Author

SsageParuders commented Feb 19, 2022

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。
需要在macOS上编译(依赖xcode的SDK环境)。
build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。
不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。
我将自行研究,因为剩下的内容与本项目无关~


更新补充,以供后人参考:
不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。
举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。
必须得要降级到SDK11版本,方可成功。


不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。


后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。
编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。
image
时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。
后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

@androiddisk
Copy link

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~

更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。

不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。

后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

老师 可以分享下 -Xclang -load -Xclang path/to/passName.so 你改好的-Xclang -load -Xclang path/to/passName.so 的源码不哇 。 我以前是用的https://www.leadroyal.cn/p/1008/ 一样的方案。但是这个项目怎么改成 单独编译so的 无从下手呢

@SsageParuders
Copy link
Author

SsageParuders commented Mar 7, 2022

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~
更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。
不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。
后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

老师 可以分享下 -Xclang -load -Xclang path/to/passName.so 你改好的-Xclang -load -Xclang path/to/passName.so 的源码不哇 。 我以前是用的https://www.leadroyal.cn/p/1008/ 一样的方案。但是这个项目怎么改成 单独编译so的 无从下手呢

您好,很高兴可以为您服务。


事实上,在学习LLVM的Pass时,我也多次拜读LeadroyaL大佬的文章。
非常感谢这位前辈留给后人宝贵的经验,至于我所使用的Pass,自然也就是这位前辈提供的Pass。
GitHub地址为: https://github.com/LeadroyaL/llvm-pass-tutorial


这里需要提醒的是,你应该在CMakeLists.txt中将lib修改为lib64(这是来自谷歌build.py的设定)。
并在编译前定义好LLVM_HOME 环境变量,该环境变量应指向编译好了以后的输出产物路径。


另外,建议初次尝试时,先不编译三款Pass,只编译一个简单的skeleton
该款Pass比较简单,各版本LLVM均可编译成功,不存在适配问题,功能是在编译时,打印symbols,因此效果比较直观。
如此,我们可以确定这种方案的可行性。


值得一提的是,我建议在CMakeLists.txt中,指定编译器为我们编译好后的ndk-toolchain中的clang/llvm。
也就是让他自举编译,然则容易出现问题。


最后,由于LeadroyaL的Pass是基于LLVM-10版本的,对于其他版本的LLVM存在适配问题,需要自行修复。
这也就是我为什么建议你初次尝试的时候,先不编译其他三款Pass,只编译最简单的Demo的原因了。
修复过程可以参考heroims大佬的PASS


由于我这里已经删除相关代码,所以抱歉,无法直接提供有效帮助。
希望这些可以帮助到您~

@androiddisk
Copy link

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~
更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。
不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。
后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

老师 可以分享下 -Xclang -load -Xclang path/to/passName.so 你改好的-Xclang -load -Xclang path/to/passName.so 的源码不哇 。 我以前是用的https://www.leadroyal.cn/p/1008/ 一样的方案。但是这个项目怎么改成 单独编译so的 无从下手呢

您好,很高兴可以为您服务。

事实上,在学习LLVM的Pass时,我也多次拜读LeadroyaL大佬的文章。 非常感谢这位前辈留给后人宝贵的经验,至于我所使用的Pass,自然也就是这位前辈提供的Pass。 GitHub地址为: https://github.com/LeadroyaL/llvm-pass-tutorial

这里需要提醒的是,你应该在CMakeLists.txt中将lib修改为lib64(这是来自谷歌build.py的设定)。 并在编译前定义好LLVM_HOME 环境变量,该环境变量应指向编译好了以后的输出产物路径。

另外,建议初次尝试时,先不编译三款Pass,只编译一个简单的skeleton。 该款Pass比较简单,各版本LLVM均可编译成功,不存在适配问题,功能是在编译时,打印symbols,因此效果比较直观。 如此,我们可以确定这种方案的可行性。

值得一提的是,我建议在CMakeLists.txt中,指定编译器为我们编译好后的ndk-toolchain中的clang/llvm。 也就是让他自举编译,然则容易出现问题。

最后,由于LeadroyaL的Pass是基于LLVM-10版本的,对于其他版本的LLVM存在适配问题,需要自行修复。 这也就是我为什么建议你初次尝试的时候,先不编译其他三款Pass,只编译最简单的Demo的原因了。 修复过程可以参考heroims大佬的PASS

由于我这里已经删除相关代码,所以抱歉,无法直接提供有效帮助。 希望这些可以帮助到您~

感谢您的 回复。

我有点疑问,请您解答下。
根据教程https://www.leadroyal.cn/p/1008/
中写到
export LLVM_HOME=/home/leadroyal/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64
我理解的是 LLVM_HOME 指向的是 谷歌ndk的 toolchains/llvm/prebuilt/linux-x86_64 路径

您说是指向输出产物路径。 不对吧,

mkdir build && cd build export LLVM_HOME=xxx/toolchains/llvm/prebuilt/linux-x86_64 cmake .. && time cmake --build .

输出路径不应该在当前目录嘛

@androiddisk
Copy link

set(ENV{LLVM_DIR} $ENV{LLVM_HOME}/lib/cmake/llvm)

这个代码您说lib改为lib64么 但是 {LLVM_HOME}/lib64/cmake/llvm 这个路径不存在呢

@SsageParuders
Copy link
Author

set(ENV{LLVM_DIR} $ENV{LLVM_HOME}/lib/cmake/llvm)

这个代码您说lib改为lib64么 但是 {LLVM_HOME}/lib64/cmake/llvm 这个路径不存在呢

对,我口中的输出产物路径,就是你说的那个意思,没表达清楚,抱歉了。
事实上,如果稍作思考,应该不难理解LLVM_HOME 变量应该指向的是我们自己编译的ndk-toolchain-llvm输出产物路径。
也就是:xxx/toolchains/llvm/prebuilt/linux-x86_64/


至于说修改liblib64,如果你要编译的是ndk当中的llvm,这一步是绝对必然的。
详细可以参考leadroyal前辈的文章:
image
如果你要编译的不是ndk当中的llvm,那么确实不存在lib64目录。


lib64/cmake/llvm目录是存在的,如图所示:
image
该目录在我们编译的ndk-toolchain-llvm输出产物路径中。
即:xxx/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm

@androiddisk
Copy link

set(ENV{LLVM_DIR} $ENV{LLVM_HOME}/lib/cmake/llvm)

这个代码您说lib改为lib64么 但是 {LLVM_HOME}/lib64/cmake/llvm 这个路径不存在呢

对,我口中的输出产物路径,就是你说的那个意思,没表达清楚,抱歉了。 事实上,如果稍作思考,应该不难理解LLVM_HOME 变量应该指向的是我们自己编译的ndk-toolchain-llvm输出产物路径。 也就是:xxx/toolchains/llvm/prebuilt/linux-x86_64/

至于说修改liblib64,如果你要编译的是ndk当中的llvm,这一步是绝对必然的。 详细可以参考leadroyal前辈的文章: image 如果你要编译的不是ndk当中的llvm,那么确实不存在lib64目录。

lib64/cmake/llvm目录是存在的,如图所示: image 该目录在我们编译的ndk-toolchain-llvm输出产物路径中。 即:xxx/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm

非常感谢 确实lib64我没配置对

@HuErr
Copy link

HuErr commented Mar 28, 2022

fatal error: 'z3++.h' file not found ,请教下这个问题是怎么弄的了,添加cmake 中添加了还是不行。

@SsageParuders
Copy link
Author

SsageParuders commented Mar 28, 2022

fatal error: 'z3++.h' file not found ,请教下这个问题是怎么弄的了,添加cmake 中添加了还是不行。

我当时编译这份pass的时候,他还没有添加z3依赖,所以不存在这个问题。


另外,我试过多次,在ndk高版本中添加ollvm/Pluto后。
编译复杂一点的native项目,貌似会报错,错误来自于clang/clang++。
由于水平有限,无法定位问题所在,盲猜是ollvm/Pluto和ndk中llvm的某种冲突导致的。
后来我移植了goron那款pass,表现还算不错,你也可以去试试。


我最近有空的话,去看看最新的Pluto在ndk中表现形式如何。
到时候如果解决了这个问题,我再来给您答复~~

@bluesadi
Copy link
Owner

bluesadi commented Apr 6, 2022

fatal error: 'z3++.h' file not found ,请教下这个问题是怎么弄的了,添加cmake 中添加了还是不行。

See #12

@HNU-Microsoft-Douzi
Copy link

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~

更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。

不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。

后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

hi,pro,在macOs上编译时遇到了一样的问题,macOs 12.1对应的xcode版本是xcode13,本地编译toolchain似乎会遇到xcode的兼容性问题,看到你这边回复时间是2个月前,那么你的mac版本大概率也是12+的,想问下你的系统版本和xcode版本是?

@SsageParuders
Copy link
Author

SsageParuders commented May 11, 2022

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~
更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。
不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。
后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

hi,pro,在macOs上编译时遇到了一样的问题,macOs 12.1对应的xcode版本是xcode13,本地编译toolchain似乎会遇到xcode的兼容性问题,看到你这边回复时间是2个月前,那么你的mac版本大概率也是12+的,想问下你的系统版本和xcode版本是?

macOS:12.2.1
和你安装的xcode版本没太大关系,我一直是xcode最新版本...

/Library/Developer/CommandLineTools/SDKs

和你下载的CommandLineTools的SDK版本有关系,上述目录下有MacOs的SDK,你需要修改默认的SDK版本
把软连接指向一下就好了,我编译ndk-r23b的时候,所用的SDK版本为11.3

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

突然想起来了,xcode现在默认也会自带Command Line Tools的,你可能需要切换一下CommandLineTools

sudo xcode-select -s /Library/Developer/CommandLineTools   

@HNU-Microsoft-Douzi
Copy link

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~
更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。
不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。
后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

hi,pro,在macOs上编译时遇到了一样的问题,macOs 12.1对应的xcode版本是xcode13,本地编译toolchain似乎会遇到xcode的兼容性问题,看到你这边回复时间是2个月前,那么你的mac版本大概率也是12+的,想问下你的系统版本和xcode版本是?

macOS:12.2.1 和你安装的xcode版本没太大关系,我一直是xcode最新版本...

/Library/Developer/CommandLineTools/SDKs

和你下载的CommandLineTools的SDK版本有关系,上述目录下有MacOs的SDK,你需要修改默认的SDK版本 把软连接指向一下就好了,我编译ndk-r23b的时候,所用的SDK版本为11.3

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

突然想起来了,xcode现在默认也会自带Command Line Tools的,你可能需要切换一下CommandLineTools

sudo xcode-select -s /Library/Developer/CommandLineTools   

牛的,感谢老哥,你这里发起的issue对我编译整个llvm有很大帮助~

@kotori2
Copy link
Contributor

kotori2 commented Jun 1, 2022

感谢楼上大佬们分享经验,我这边尝试使用了NDK 24.0.8215888 (LLVM 14.0.1) 和最新的commit b79a9d7 编译了一份,虽然pass对应的flag应用了,但是似乎并没有任何效果。
我的patch大概长这样:

diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt
index dda5f6de11e3..a001a7ca9b48 100644
--- a/llvm/lib/Transforms/CMakeLists.txt
+++ b/llvm/lib/Transforms/CMakeLists.txt
@@ -9,3 +9,4 @@ add_subdirectory(Hello)
 add_subdirectory(ObjCARC)
 add_subdirectory(Coroutines)
 add_subdirectory(CFGuard)
+add_subdirectory(Obfuscation)
diff --git a/llvm/lib/Transforms/IPO/CMakeLists.txt b/llvm/lib/Transforms/IPO/CMakeLists.txt
index 2392b13b33a0..d4b4f5e6e555 100644
--- a/llvm/lib/Transforms/IPO/CMakeLists.txt
+++ b/llvm/lib/Transforms/IPO/CMakeLists.txt
@@ -71,4 +71,5 @@ add_llvm_component_library(LLVMipo
   TransformUtils
   Vectorize
   Instrumentation
+  Obfuscation
   )
diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
index aa916345954d..e03b96a09afb 100644
--- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
+++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
@@ -52,6 +52,8 @@
 #include "llvm/Transforms/Vectorize/SLPVectorizer.h"
 #include "llvm/Transforms/Vectorize/VectorCombine.h"
 
+#include "llvm/Transforms/Obfuscation/PassRegistry.h"
+
 using namespace llvm;
 
 namespace llvm {
@@ -656,6 +658,9 @@ void PassManagerBuilder::populateModulePassManager(
   // is handled separately, so just check this is not the ThinLTO post-link.
   bool DefaultOrPreLinkPipeline = !PerformThinLTO;
 
+  // Add custom obfuscation passes to PassManager
+  registerAllPasses(MPM);
+
   MPM.add(createAnnotation2MetadataLegacyPass());
 
   if (!PGOSampleUse.empty()) {

此外还添加了
/include/llvm/Transforms/Obfuscation /lib/Transforms/Obfuscation/include/Eigen

测试代码:

#include <cstdio>
#include <cstring>

int main() {
    char a[100];
    memset(a, 0, 100);
    scanf("%s", a);
    return 0;
}

编译命令:

PS C:\Users\[username]\AppData\Local\Android\Sdk\ndk\24.0.8215888-pluto\toolchains\llvm\prebuilt\windows-x86_64\bin> ./aarch64-linux-android32-clang++.cmd .\test.cpp -o test -O2 -mllvm -mba -mllvm -mba-prob=100 -mllvm -fla -mllvm -gle

IDA结果(似乎就没有任何变化……):
image

logs with -opt-bisect-limit=-1

BISECT: running pass (1) Annotation2MetadataPass on [module]
BISECT: running pass (2) ForceFunctionAttrsPass on [module]
BISECT: running pass (3) InferFunctionAttrsPass on [module]
BISECT: running pass (4) LowerExpectIntrinsicPass on main
BISECT: running pass (5) SimplifyCFGPass on main
BISECT: running pass (6) SROA on main
BISECT: running pass (7) EarlyCSEPass on main
BISECT: running pass (8) OpenMPOptPass on [module]
BISECT: running pass (9) IPSCCPPass on [module]
BISECT: running pass (10) CalledValuePropagationPass on [module]
BISECT: running pass (11) GlobalOptPass on [module]
BISECT: running pass (12) PromotePass on main
BISECT: running pass (13) DeadArgumentEliminationPass on [module]
BISECT: running pass (14) InstCombinePass on main
BISECT: running pass (15) SimplifyCFGPass on main
BISECT: running pass (16) InvalidateAnalysisPass<llvm::AAManager> on main
BISECT: running pass (17) InlinerPass on (main)
BISECT: running pass (18) InlinerPass on (main)
BISECT: running pass (19) PostOrderFunctionAttrsPass on (main)
BISECT: running pass (20) OpenMPOptCGSCCPass on (main)
BISECT: running pass (21) SROA on main
BISECT: running pass (22) EarlyCSEPass on main
BISECT: running pass (23) SpeculativeExecutionPass on main
BISECT: running pass (24) JumpThreadingPass on main
BISECT: running pass (25) CorrelatedValuePropagationPass on main
BISECT: running pass (26) SimplifyCFGPass on main
BISECT: running pass (27) InstCombinePass on main
BISECT: running pass (28) LibCallsShrinkWrapPass on main
BISECT: running pass (29) TailCallElimPass on main
BISECT: running pass (30) SimplifyCFGPass on main
BISECT: running pass (31) ReassociatePass on main
BISECT: running pass (32) LoopSimplifyPass on main
BISECT: running pass (33) LCSSAPass on main
BISECT: running pass (34) SimplifyCFGPass on main
BISECT: running pass (35) InstCombinePass on main
BISECT: running pass (36) LoopSimplifyPass on main
BISECT: running pass (37) LCSSAPass on main
BISECT: running pass (38) SROA on main
BISECT: running pass (39) MergedLoadStoreMotionPass on main
BISECT: running pass (40) GVN on main
BISECT: running pass (41) SCCPPass on main
BISECT: running pass (42) BDCEPass on main
BISECT: running pass (43) InstCombinePass on main
BISECT: running pass (44) JumpThreadingPass on main
BISECT: running pass (45) CorrelatedValuePropagationPass on main
BISECT: running pass (46) ADCEPass on main
BISECT: running pass (47) MemCpyOptPass on main
BISECT: running pass (48) DSEPass on main
BISECT: running pass (49) LoopSimplifyPass on main
BISECT: running pass (50) LCSSAPass on main
BISECT: running pass (51) SimplifyCFGPass on main
BISECT: running pass (52) InstCombinePass on main
BISECT: running pass (53) GlobalOptPass on [module]
BISECT: running pass (54) GlobalDCEPass on [module]
BISECT: running pass (55) EliminateAvailableExternallyPass on [module]
BISECT: running pass (56) ReversePostOrderFunctionAttrsPass on [module]
BISECT: running pass (57) Float2IntPass on main
BISECT: running pass (58) LowerConstantIntrinsicsPass on main
BISECT: running pass (59) LoopSimplifyPass on main
BISECT: running pass (60) LCSSAPass on main
BISECT: running pass (61) LoopDistributePass on main
BISECT: running pass (62) InjectTLIMappings on main
BISECT: running pass (63) LoopVectorizePass on main
BISECT: running pass (64) LoopLoadEliminationPass on main
BISECT: running pass (65) InstCombinePass on main
BISECT: running pass (66) SimplifyCFGPass on main
BISECT: running pass (67) SLPVectorizerPass on main
BISECT: running pass (68) VectorCombinePass on main
BISECT: running pass (69) InstCombinePass on main
BISECT: running pass (70) LoopUnrollPass on main
BISECT: running pass (71) WarnMissedTransformationsPass on main
BISECT: running pass (72) InstCombinePass on main
BISECT: running pass (73) LoopSimplifyPass on main
BISECT: running pass (74) LCSSAPass on main
BISECT: running pass (75) AlignmentFromAssumptionsPass on main
BISECT: running pass (76) LoopSinkPass on main
BISECT: running pass (77) InstSimplifyPass on main
BISECT: running pass (78) DivRemPairsPass on main
BISECT: running pass (79) SimplifyCFGPass on main
BISECT: running pass (80) CGProfilePass on [module]
BISECT: running pass (81) GlobalDCEPass on [module]
BISECT: running pass (82) ConstantMergePass on [module]
BISECT: running pass (83) RelLookupTableConverterPass on [module]
BISECT: running pass (84) AnnotationRemarksPass on main
BISECT: running pass (85) Add __emutls_[vt]. variables for emultated TLS model on module (.\test.cpp)
BISECT: running pass (86) Simplify the CFG on function (main)
BISECT: running pass (87) Loop Data Prefetch on function (main)
BISECT: running pass (88) Merge contiguous icmps into a memcmp on function (main)
BISECT: running pass (89) Expand memcmp() to load/stores on function (main)
BISECT: running pass (90) Constant Hoisting on function (main)
BISECT: running pass (91) Partially inline calls to library functions on function (main)
BISECT: running pass (92) CodeGen Prepare on function (main)
BISECT: running pass (93) AArch64 Promote Constant on module (.\test.cpp)
BISECT: running pass (94) AArch64 Instruction Selection on function (main)
BISECT: running pass (95) AArch64 Local Dynamic TLS Access Clean-up on function (main)
BISECT: running pass (96) Early Tail Duplication on function (main)
BISECT: running pass (97) Optimize machine instruction PHIs on function (main)
BISECT: running pass (98) Merge disjoint stack slots on function (main)
BISECT: running pass (99) Remove dead machine instructions on function (main)
BISECT: running pass (100) AArch64 Condition Optimizer on function (main)
BISECT: running pass (101) AArch64 Conditional Compares on function (main)
BISECT: running pass (102) AArch64 Conditional Branch Tuning on function (main)
BISECT: running pass (103) Early If-Conversion on function (main)
BISECT: running pass (104) AArch64 Store Pair Suppression on function (main)
BISECT: running pass (105) AArch64 SIMD instructions optimization pass on function (main)
BISECT: running pass (106) Early Machine Loop Invariant Code Motion on function (main)
BISECT: running pass (107) Machine Common Subexpression Elimination on function (main)
BISECT: running pass (108) Machine code sinking on function (main)
BISECT: running pass (109) Peephole Optimizations on function (main)
BISECT: running pass (110) Remove dead machine instructions on function (main)
BISECT: running pass (111) AArch64 Dead register definitions on function (main)
BISECT: running pass (112) Two-Address instruction pass on function (main)
BISECT: running pass (113) Machine Instruction Scheduler on function (main)
BISECT: running pass (114) Stack Slot Coloring on function (main)
BISECT: running pass (115) Machine Copy Propagation Pass on function (main)
BISECT: running pass (116) Machine Loop Invariant Code Motion on function (main)
BISECT: running pass (117) AArch64 Redundant Copy Elimination on function (main)
BISECT: running pass (118) A57 FP Anti-dependency breaker on function (main)
BISECT: running pass (119) Fixup Statepoint Caller Saved on function (main)
BISECT: running pass (120) PostRA Machine Sink on function (main)
BISECT: running pass (121) Shrink Wrapping analysis on function (main)
BISECT: running pass (122) Control Flow Optimizer on function (main)
BISECT: running pass (123) Tail Duplication on function (main)
BISECT: running pass (124) Machine Copy Propagation Pass on function (main)
BISECT: running pass (125) AArch64 load / store optimization pass on function (main)
BISECT: running pass (126) PostRA Machine Instruction Scheduler on function (main)
BISECT: running pass (127) Branch Probability Basic Block Placement on function (main)

不知道是哪个地方改漏了呢?

@SsageParuders
Copy link
Author

@kotori2


您好,因为最近比较忙,您在这个issues新提交的问题刚刚才发现,没能及时回复,非常抱歉。


背景

我查了一下资料,您这份移植的pass实际上是没有任何问题的,这个现象主要是LLVM14的版本变化。
在LLVM14中,默认已经不再使用传统的Legacy Pass Manager,而是采用了新的PASS管理器。
而在该项目的LLVM12版本中,PASS采用的是Legacy Pass Manager,因此才会出现移植无效的情况。
根据官方文档来说,未来的LLVM15版本,可能彻底移除Legacy Pass Manager的支持。


解决方案

解决方案有两种

  1. 更换Legacy Pass ManagerNew Pass Manager
    可以参考llvm-pass-tutorial的最新几次commit
    参考leadroyal前辈的教程
  2. 使用Pass的时候传入-flegacy-pass-manager参数,来使之前的Legacy Pass Manager生效启用
  3. 在编译LLVM的时候启用CMake参数-DLLVM_ENABLE_NEW_PASS_MANAGER=OFF禁用New Pass Manager
  4. 对于opt调试可动态加载的Pass插件,需要传入-enable-new-pm=0参数。
    关闭新的PASS管理器,启用传统的PASS管理器,如图所示:
    image

参考链接1: Google的一个讨论
参考链接2: LLVM官方文档
参考链接3: heroims前辈的博客
参考链接4: leadroyal前辈的解释

@chen362
Copy link

chen362 commented Jul 20, 2022

chen@chen-virtual-machine:~/桌面/ploto/jni$ ndk-build1
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile++ : hello <= hello.cpp
Android (dev, based on r416183c2) clang version 12.0.9 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)
Target: aarch64-none-linux-android21
Thread model: posix
InstalledDir: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin
Found candidate GCC installation: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9.x
Selected GCC installation: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9.x
Candidate multilib: .;@m64
Selected multilib: .;@m64
(in-process)
"/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++.real" -cc1 -triple aarch64-none-linux-android21 -emit-obj --mrelax-relocations -mnoexecstack -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hello.cpp -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=non-leaf -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu generic -target-feature +neon -target-abi aapcs -mllvm -aarch64-fix-cortex-a53-835769=1 -fallow-half-arguments-and-returns -fno-split-dwarf-inlining -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -v -ffunction-sections -fdata-sections -resource-dir /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9 -dependency-file /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o.d -MT /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o -MP -D _FORTIFY_SOURCE=2 -D NDEBUG -I /home/chen/桌面/ploto/jni -D ANDROID -isysroot /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1 -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/local/include -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9/include -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/include -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include -O2 -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -Wformat -Werror=format-security -fdeprecated-macro -fdebug-compilation-dir /home/chen/桌面/ploto/jni -ferror-limit 19 -stack-protector 2 -fno-rtti -fno-signed-char -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -mllvm -mba -mllvm -mba-prob=100 -mllvm -fla -mllvm -gle -mllvm -bcf -mllvm -sub -mllvm -trap-angr -mllvm -trap-angr-times=3 -mllvm -trap-angr-prob=60 -o /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o -x c++ /home/chen/桌面/ploto/jni/hello.cpp
clang -cc1 version 12.0.9 based upon LLVM 12.0.9git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/include"
#include "..." search starts here:
#include <...> search starts here:
/home/chen/桌面/ploto/jni
/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1
/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/local/include
/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9/include
/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android
/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include
End of search list.
[arm64-v8a] Executable : hello
[arm64-v8a] Install : hello => libs/arm64-v8a/hello

你好 我使用的LLVM12版本 也/include/llvm/Transforms/Obfuscation /lib/Transforms/Obfuscation 和 /include/Eigen 全部添加
编译也没有报错

但是使用NDK-build 编译的话 加密效果挺好 但是-MBA -bcf -fla 目测无法生效 求解 还是说最新版本的pluto就是这样?

我使用clang编译的话可以混淆全开 但是-sub失效 main菜单出现 还有稳定性不妥?

请问我哪个方面出问题了 能否在ndk-build的情况下 混淆全开 ?

@kotori2
Copy link
Contributor

kotori2 commented Jul 21, 2022

@SsageParuders 感谢大佬的耐心解答!

@SsageParuders
Copy link
Author

chen@chen-virtual-machine:~/桌面/ploto/jni$ ndk-build1 Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16. [arm64-v8a] Compile++ : hello <= hello.cpp Android (dev, based on r416183c2) clang version 12.0.9 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee) Target: aarch64-none-linux-android21 Thread model: posix InstalledDir: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin Found candidate GCC installation: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9.x Selected GCC installation: /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9.x Candidate multilib: .;@m64 Selected multilib: .;@m64 (in-process) "/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++.real" -cc1 -triple aarch64-none-linux-android21 -emit-obj --mrelax-relocations -mnoexecstack -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hello.cpp -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=non-leaf -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu generic -target-feature +neon -target-abi aapcs -mllvm -aarch64-fix-cortex-a53-835769=1 -fallow-half-arguments-and-returns -fno-split-dwarf-inlining -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -v -ffunction-sections -fdata-sections -resource-dir /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9 -dependency-file /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o.d -MT /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o -MP -D _FORTIFY_SOURCE=2 -D NDEBUG -I /home/chen/桌面/ploto/jni -D ANDROID -isysroot /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1 -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/local/include -internal-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9/include -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/include -internal-externc-isystem /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include -O2 -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -Wformat -Werror=format-security -fdeprecated-macro -fdebug-compilation-dir /home/chen/桌面/ploto/jni -ferror-limit 19 -stack-protector 2 -fno-rtti -fno-signed-char -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -mllvm -mba -mllvm -mba-prob=100 -mllvm -fla -mllvm -gle -mllvm -bcf -mllvm -sub -mllvm -trap-angr -mllvm -trap-angr-times=3 -mllvm -trap-angr-prob=60 -o /home/chen/桌面/ploto/obj/local/arm64-v8a/objs/hello/hello.o -x c++ /home/chen/桌面/ploto/jni/hello.cpp clang -cc1 version 12.0.9 based upon LLVM 12.0.9git default target x86_64-unknown-linux-gnu ignoring nonexistent directory "/home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/include" #include "..." search starts here: #include <...> search starts here: /home/chen/桌面/ploto/jni /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1 /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/local/include /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/12.0.9/include /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android /home/chen/ollvm12/android-ndk-r23c-linux/android-ndk-r23c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include End of search list. [arm64-v8a] Executable : hello [arm64-v8a] Install : hello => libs/arm64-v8a/hello

你好 我使用的LLVM12版本 也/include/llvm/Transforms/Obfuscation /lib/Transforms/Obfuscation 和 /include/Eigen 全部添加 编译也没有报错

但是使用NDK-build 编译的话 加密效果挺好 但是-MBA -bcf -fla 目测无法生效 求解 还是说最新版本的pluto就是这样?

我使用clang编译的话可以混淆全开 但是-sub失效 main菜单出现 还有稳定性不妥?

请问我哪个方面出问题了 能否在ndk-build的情况下 混淆全开 ?

系Pluto本身存在某些问题,待修复

@anjiuzhe
Copy link

anjiuzhe commented Feb 15, 2023

set(ENV{LLVM_DIR} $ENV{LLVM_HOME}/lib/cmake/llvm)

这个代码您说lib改为lib64么 但是 {LLVM_HOME}/lib64/cmake/llvm 这个路径不存在呢

对,我口中的输出产物路径,就是你说的那个意思,没表达清楚,抱歉了。 事实上,如果稍作思考,应该不难理解LLVM_HOME 变量应该指向的是我们自己编译的ndk-toolchain-llvm输出产物路径。 也就是:xxx/toolchains/llvm/prebuilt/linux-x86_64/

至于说修改liblib64,如果你要编译的是ndk当中的llvm,这一步是绝对必然的。 详细可以参考leadroyal前辈的文章: image 如果你要编译的不是ndk当中的llvm,那么确实不存在lib64目录。

lib64/cmake/llvm目录是存在的,如图所示: image 该目录在我们编译的ndk-toolchain-llvm输出产物路径中。 即:xxx/toolchains/llvm/prebuilt/linux-x86_64/lib64/cmake/llvm

大佬,你好,lib64/cmake/llvm这个目录为啥在我下载的ndk里面没有,也是Mac平台,通过Android Studio下载的,我的路径是/Users/bdd/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/lib64,里面找不到你说的目录。

image

@anjiuzhe
Copy link

@Dfault0
Copy link

Dfault0 commented Oct 30, 2023

经过对build.py的阅读,如需编译macOS版本的toolchain,无法在Linux环境下进行交叉编译。 需要在macOS上编译(依赖xcode的SDK环境)。 build.py会以当前平台为默认目标,从而编译出macOS版本的toolchain。 不过在我实测的过程中,遇到了macOS环境污染导致的一些冲突问题。 我将自行研究,因为剩下的内容与本项目无关~
更新补充,以供后人参考: 不同的ndk_toolchain编译的环境,所需要的xcode的SDK版本也不同。 举个例子,编译ndk-r23b,无法使用SDK12+版本,会报错。 必须得要降级到SDK11版本,方可成功。
不过在实际移植PASS的过程中,我遇到了CryptoUtils.h中的报错。

Unknown endianness of the compilation platform, check this header aes_encrypt.h

系MacBookPro设备构架与宏定义的冲突,修改宏定义即可解决问题。
后又尝试利用已经编译好了的,完整的ndk-toolchain-llvm环境。 编译单独的pass模块,通过添加编译参数,让ndk加载pass。

-Xclang -load -Xclang path/to/passName.so

经过测试,方案可行。 image 时间有限,暂时只测试了macOS环境,理论上Linux和Windows环境一样可以。 后来者可以通过编译时载入该方案单独编译出来的模块,实现对ndk无污染,轻量便捷的加载pass。

hi,pro,在macOs上编译时遇到了一样的问题,macOs 12.1对应的xcode版本是xcode13,本地编译toolchain似乎会遇到xcode的兼容性问题,看到你这边回复时间是2个月前,那么你的mac版本大概率也是12+的,想问下你的系统版本和xcode版本是?

macOS:12.2.1 和你安装的xcode版本没太大关系,我一直是xcode最新版本...

/Library/Developer/CommandLineTools/SDKs

和你下载的CommandLineTools的SDK版本有关系,上述目录下有MacOs的SDK,你需要修改默认的SDK版本 把软连接指向一下就好了,我编译ndk-r23b的时候,所用的SDK版本为11.3

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

突然想起来了,xcode现在默认也会自带Command Line Tools的,你可能需要切换一下CommandLineTools

sudo xcode-select -s /Library/Developer/CommandLineTools   

环境:macos 13.2
NDK 版本:23.1.7779620
源码外编译参考:https://github.com/LeadroyaL/llvm-pass-tutorial
您好,我使用源码外编译pluto,能够编译成功,并且集成到NDK中使用-Xclang -load -Xclang x.so 并添加编译命令-mllvm -bcf,编译失败,恳请大佬批评指正,非常感谢

我修改了注册pass的文件:

#include "include/PassRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "include/BogusControlFlow.h"
#include "include/Flattening.h"
#include "include/FlatteningEnhanced.h"
#include "include/GlobalsEncryption.h"
#include "include/HelloWorld.h"
#include "include/MBAObfuscation.h"
#include "include/RandomControlFlow.h"
#include "include/SplitBasicBlock.h"
#include "include/Substitution.h"
#include "include/TrapAngr.h"
#include "include/VariableSubstitution.h"
#include "llvm/Transforms/Utils.h"
#include "include/GlobalsEncryption.h"

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace llvm;

static cl::opt<bool>
    RunHelloWorld("hlw", cl::init(false),
                  cl::desc("PlutoObfuscator - HelloWorld Pass"));

static cl::opt<bool>
    RunFlattening("fla", cl::init(false),
                  cl::desc("PlutoObfuscator - Flattening Pass"));

static cl::opt<bool>
    RunFlatteningEnhanced("fla-ex", cl::init(false),
                          cl::desc("PlutoObfuscator - FlatteningEnhanced"));

static cl::opt<bool>
    RunBogusControlFlow("bcf", cl::init(false),
                        cl::desc("PlutoObfuscator -  BogusControlFlow Pass"));

static cl::opt<bool>
    RunSubstitution("sub", cl::init(false),
                    cl::desc("PlutoObfuscator - Substitution Pass"));

static cl::opt<bool>
    RunGlobalsEncryption("gle", cl::init(false),
                         cl::desc("PlutoObfuscator - GlobalsEncryption Pass"));

static cl::opt<bool> RunVariableSubstitution(
    "vsb", cl::init(false),
    cl::desc("PlutoObfuscator - VariableSubstitution Pass"));

static cl::opt<bool>
    RunRandomControlFlow("rcf", cl::init(false),
                         cl::desc("PlutoObfuscator - RandomControlFlow Pass"));

static cl::opt<bool> RunTrapAngr("trap-angr", cl::init(false),
                                 cl::desc("PlutoObfuscator - TrapAngr Pass"));

static cl::opt<bool>
    RunMBAObfuscation("mba", cl::init(false), 
                      cl::desc("PlutoObfuscator -  MBAObfuscation Pass"));

void llvm::registerModulePasses(legacy::PassManagerBase &MPM) {
    MPM.add(createGlobalsEncryptionPass(RunGlobalsEncryption));
    // MPM.add(createFlatteningEnhancedPass(RunFlatteningEnhanced));
}

void llvm::registerFunctionPasses(legacy::PassManagerBase &FPM) {
    FPM.add(createHelloWorldPass(RunHelloWorld));
    FPM.add(createSplitBasicBlockPass());
    FPM.add(createLowerSwitchPass());
    FPM.add(createFlatteningPass(RunFlattening));
    FPM.add(craeteBogusControlFlow(RunBogusControlFlow));
    FPM.add(createSubstitutionPass(RunSubstitution));
    FPM.add(createVariableSubstitutionPass(RunVariableSubstitution));
    // FPM.add(createRandomControlFlow(RunRandomControlFlow));
    // FPM.add(createTrapAngrPass(RunTrapAngr));
    FPM.add(createMBAObfuscationPass(RunMBAObfuscation));
    // FPM.add(createMBAObfuscationPass(RunGlobalsEncryption));
}

static void registerPlutoModulePass(const PassManagerBuilder &,
                              legacy::PassManagerBase &PM) {
//    PM.add(createFunctionWrapperPass(true)); /*broken*/
    PM.add(createGlobalsEncryptionPass(RunGlobalsEncryption));

}

static void registerPlutoFunctionPass(const PassManagerBuilder &,
                              legacy::PassManagerBase &PM) {
    PM.add(createHelloWorldPass(RunHelloWorld));
    PM.add(createSplitBasicBlockPass());
    PM.add(createLowerSwitchPass());
    PM.add(createFlatteningPass(RunFlattening));
    PM.add(craeteBogusControlFlow(RunBogusControlFlow));
    PM.add(createSubstitutionPass(RunSubstitution));
    PM.add(createVariableSubstitutionPass(RunVariableSubstitution));
    // FPM.add(createRandomControlFlow(RunRandomControlFlow));
    // FPM.add(createTrapAngrPass(RunTrapAngr));
    PM.add(createMBAObfuscationPass(RunMBAObfuscation));
    // FPM.add(createMBAObfuscationPass(RunGlobalsEncryption));
}

static RegisterStandardPasses
        RegisterMyPass(PassManagerBuilder::EP_EnabledOnOptLevel0,
                       registerPlutoModulePass);
static RegisterStandardPasses
        RegisterMyPass0(PassManagerBuilder::EP_OptimizerLast,
                        registerPlutoModulePass);
static RegisterStandardPasses
        RegisterMyPass1(PassManagerBuilder::EP_EarlyAsPossible,
                        registerPlutoFunctionPass);

然后集成到ndk中使用:

        externalNativeBuild {
            cmake {
                cppFlags " -Xclang -load -Xclang /Users/xxx/work/ollvm/code_for_obfuscator/llvm-pass-tutorial/llvm-build/ollvm-pluto/libLLVMObfuscation.so -mllvm -gle"            
                }
        }

结果报错如下:

[CXX1429] error when building with cmake using /Users/xxx/src/main/cpp/CMakeLists.txt: -- Android: Targeting API '24' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64'
-- Android: Selected unified Clang toolchain
-- The C compiler identification is Clang 12.0.8
-- The CXX compiler identification is Clang 12.0.8
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - failed
-- Check for working CXX compiler: /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++
-- Check for working CXX compiler: /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ - broken
-- Configuring incomplete, errors occurred!
See also "/Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a/CMakeFiles/CMakeOutput.log".
See also "/Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a/CMakeFiles/CMakeError.log".

C++ build system [configure] failed while executing:
    /Users/xxx/Library/Android/sdk/cmake/3.22.1/bin/cmake \
      -H/Users/xxx/src/main/cpp \
      -DCMAKE_SYSTEM_NAME=Android \
      -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
      -DCMAKE_SYSTEM_VERSION=24 \
      -DANDROID_PLATFORM=android-24 \
      -DANDROID_ABI=arm64-v8a \
      -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
      -DANDROID_NDK=/Users/xxx/Library/Android/sdk/ndk/23.1.7779620 \
      -DCMAKE_ANDROID_NDK=/Users/xxx/Library/Android/sdk/ndk/23.1.7779620 \
      -DCMAKE_TOOLCHAIN_FILE=/Users/xxx/Library/Android/sdk/ndk/23.1.7779620/build/cmake/android.toolchain.cmake \
      -DCMAKE_MAKE_PROGRAM=/Users/xxx/Library/Android/sdk/cmake/3.22.1/bin/ninja \
      "-DCMAKE_CXX_FLAGS=-Xclang -load -Xclang /Users/xxx/work/ollvm/code_for_obfuscator/llvm-pass-tutorial/llvm-build/ollvm-pluto/libLLVMObfuscation.so -mllvm -hlw" \
      -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/xxx/build/intermediates/cxx/Debug/5n5x50t7/obj/arm64-v8a \
      -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/Users/xxx/build/intermediates/cxx/Debug/5n5x50t7/obj/arm64-v8a \
      -DCMAKE_BUILD_TYPE=Debug \
      -B/Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a \
      -GNinja
  from /Users/xxx
CMake Error at /Users/xxx/Library/Android/sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message):
  The C++ compiler

    "/Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a/CMakeFiles/CMakeTmp
    
    Run Build Command(s):/Users/xxx/Library/Android/sdk/cmake/3.22.1/bin/ninja cmTC_4e675 && [1/2] Building CXX object CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o
    FAILED: CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o 
    /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android24 --sysroot=/Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot   -Xclang -load -Xclang /Users/xxx/work/ollvm/code_for_obfuscator/llvm-pass-tutorial/llvm-build/ollvm-pluto/libLLVMObfuscation.so -mllvm -hlw  -O2 -g -DNDEBUG -fPIE -MD -MT CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o -MF CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o.d -o CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o -c /Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
    dyld[87693]: missing symbol called
    PLEASE submit a bug report to https://github.com/android-ndk/ndk/issues and include the crash backtrace, preprocessed source, and associated run script.
    Stack dump:
    0.	Program arguments: /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android24 --sysroot=/Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Xclang -load -Xclang /Users/xxx/work/ollvm/code_for_obfuscator/llvm-pass-tutorial/llvm-build/ollvm-pluto/libLLVMObfuscation.so -mllvm -hlw -O2 -g -DNDEBUG -fPIE -MD -MT CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o -MF CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o.d -o CMakeFiles/cmTC_4e675.dir/testCXXCompiler.cxx.o -c /Users/xxx/.cxx/Debug/5n5x50t7/arm64-v8a/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
    1.	<eof> parser at end of file
    Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
    0  clang-12                 0x00000001018b1a9c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
    1  clang-12                 0x00000001018b0cdc llvm::sys::RunSignalHandlers() + 128
    2  clang-12                 0x00000001018286d0 llvm::CrashRecoveryContext::HandleExit(int) + 116
    3  clang-12                 0x00000001018288b0 llvm::CrashRecoveryContext::RunSafelyOnThread(llvm::function_ref<void ()>, unsigned int) + 348
    4  libsystem_platform.dylib 0x000000018f1942a4 _sigtramp + 56
    5  dyld                     0x000000018eeb1a00 abort_with_payload_wrapper_internal + 104
    6  dyld                     0x000000018eeb1a34
    7  dyld                     0x000000018ee400a4 dyld4::CacheFinder::~CacheFinder() + 0
    8  dyld                     0x000000018ee7427c dyld4::APIs::_tlv_atexit(void (*)(void*), void*) + 0
    9  libLLVMObfuscation.so    0x0000000104c874bc registerPlutoFunctionPass(llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&) + 220
    10 clang-12                 0x0000000101445960 llvm::PassManagerBuilder::addExtensionsToPM(llvm::PassManagerBuilder::ExtensionPointTy, llvm::legacy::PassManagerBase&) const + 156
    11 clang-12                 0x0000000101445b2c llvm::PassManagerBuilder::populateFunctionPassManager(llvm::legacy::FunctionPassManager&) + 56
    12 clang-12                 0x0000000101ab4f18 clang::EmbedBitcode(llvm::Module*, clang::CodeGenOptions const&, llvm::MemoryBufferRef) + 40272
    13 clang-12                 0x0000000101aaac80 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >) + 11192
    14 clang-12                 0x0000000101aa843c clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >) + 884
    15 clang-12                 0x0000000101c775d4 clang::EmitObjAction::EmitObjAction(llvm::LLVMContext*) + 1616
    16 clang-12                 0x00000001029f1ccc clang::ParseAST(clang::Sema&, bool, bool) + 416
    17 clang-12                 0x0000000101e6ecb0 clang::FrontendAction::Execute() + 60
    18 clang-12                 0x0000000101e1aa24 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 384
    19 clang-12                 0x0000000101ebd808 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 364
    20 clang-12                 0x0000000100856288 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 880
    21 clang-12                 0x0000000100854060 main + 5160
    22 clang-12                 0x0000000101d4d9a0 clang::driver::JobList::clear() + 1492
    23 clang-12                 0x0000000101828614 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) + 204
    24 clang-12                 0x0000000101d4cf90 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, bool*) const + 260
    25 clang-12                 0x0000000101d2cd7c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const + 168
    26 clang-12                 0x0000000101d2d09c clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*> >&) const + 88
    27 clang-12                 0x0000000101d3c86c clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*> >&) + 176
    28 clang-12                 0x000000010085352c main + 2292
    29 dyld                     0x000000018ee3be50 start + 2544
    clang-12: error: clang frontend command failed with exit code 134 (use -v to see invocation)
    Android (7714059, based on r416183c1) clang version 12.0.8 (https://android.googlesource.com/toolchain/llvm-project c935d99d7cf2016289302412d708641d52d2f7ee)
    Target: aarch64-none-linux-android24
    Thread model: posix
    InstalledDir: /Users/xxx/Library/Android/sdk/ndk/23.1.7779620/toolchains/llvm/prebuilt/darwin-x86_64/bin
    clang-12: note: diagnostic msg: 
    ********************
    
    PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
    Preprocessed source(s) and associated run script(s) are located at:
    clang-12: note: diagnostic msg: /var/folders/vk/p3665v4j5_l3194pb3w5lqdc0000gp/T/testCXXCompiler-3e2833.cpp
    clang-12: note: diagnostic msg: /var/folders/vk/p3665v4j5_l3194pb3w5lqdc0000gp/T/testCXXCompiler-3e2833.sh
    clang-12: note: diagnostic msg: Crash backtrace is located in
    clang-12: note: diagnostic msg: /Users/xxx/Library/Logs/DiagnosticReports/clang-12_<YYYY-MM-DD-HHMMSS>_<hostname>.crash
    clang-12: note: diagnostic msg: (choose the .crash file that corresponds to your crash)
    clang-12: note: diagnostic msg: 
    
    ********************
    ninja: build stopped: subcommand failed.
    
    

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:12 (project)

@SsageParuders @androiddisk

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants