首页 > 系统相关 >WINDOWS 环境下编译 OLLVM 替换到 NDK 环境

WINDOWS 环境下编译 OLLVM 替换到 NDK 环境

时间:2023-07-14 14:12:12浏览次数:53  
标签:NDK llvm WINDOWS clang 编译 exe OLLVM mllvm

编译 OLLVM

环境准备

这里使用的是AGP 7.2.2NDK 25.2.9519653llvm 14.0.7cmake 3.22.1python39

git

用来下载源码

python

搞到这一步环境变量里应该已经有python了吧

NDK

AGP 的 7.2.2 版本默认使用的 NDK 版本为21.4.7075529,对应的 LLVM 为9.0.9

ndk

需要根据实际情况选择 NDK 对应的 LLVM 版本,编译 OLLVM,LLVM 版本号可以通过Sdk_DIR\ndk\$version\toolchains\llvm\prebuilt\windows-x86_64\AndroidVersion.txt文件看到,如SDK Manager 中的最新版本25.2.9519653为:

14.0.7
based on r450784d1
for additional information on LLVM revision and cherry-picks, see clang_source_info.md

在 module 的build.gradle中指定 NDK 版本

android {
    ndkVersion "25.2.9519653"
}

OLLVM

可以在 github/heroims/obfuscator 仓库的分支中找到对应的移植源码,

heroims

13x14x版本也可以在 github/yangyiyu08/ollvm-project 仓库的对应分支中获取。14x版本还可以直接在 Releases 中下载作者编译好的文件,跳过编译的步骤。但这个文件在我的环境下会有NDK编译错误的情况,我自己编译出来的文件运行正常。

这里使用NDK 25.2.9519653,需要下载 14x 的源码。

CMAKE

AGP 的 7.2.2 版本默认使用的 cmake 版本为3.18.1,在指定 NDK 版本到 25.2.9519653 后,会在编译时提示需要升级到 3.19 版本以上的信息。所以这里在编译前就通过 SDK Manager 下载 3.22.1 版本,并把所在目录添加到环境变量

同时在build.gradleCMakeLists中修改工程的 cmake 版本。

开始编译

在源码的目录执行以下命令构建 cmake 配置
cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF -DLLVM_ENABLE_NEW_PASS_MANAGER=OFF

对应的参数:

-G Ninja: 使用 ninja 进行编译源码
-DLLVM_ENABLE_PROJECTS="clang": 启用clang,有多个选择 但我们只需要clang,官方文档有说明
-DCMAKE_BUILD_TYPE=Release: 构建 release 版本,比 debug 版本编译快很多
-DLLVM_INCLUDE_TESTS=OFF: 关闭 llvm 的头文件测试,也是为了加快编译速度
-DLLVM_ENABLE_NEW_PASS_MANAGER=OFF: 这个非常重要,llvm-12.x 开始默认使用 newPM进行编译源码,导致 ollvm 不起作用!因此,需要加上这个参数禁用掉 newPM。(在每个编译时增加flag -flegacy-pass-manager 让 llvm 不走 newPM 编译也可以,但没必要)

执行以上命令后若提示 Configuration done. 则配置成功。接下来执行以下命令开始编译:
cmake --build build -j16

其中-j16为指定的线程数,需要根据 CPU 调整。然后等待编译完成

waiting...

编译完成

编译完成后打开build/bin目录,找到clang.execlang++.execlang-cl.exe,可以看到三个文件的MD5是相同的。

certutil

编译后的文件大小为 137MB,对比 NDK 目录下的 clang.exe 仅有 88.6MB。编译后的文件可以通过strip clang.exe命令剥离可执行文件减小到 113MB。

替换到 NDK 环境

备份与替换

首先打开当前 NDK 的 llvm 目录,将clang.execlang++.execlang-cl.exe备份,然后把上一步编译后的文件复制到当前目录。

bak

复制 lib 库

此时编译会出现找不到libunwind等库的错误,错误信息显示目录文件不存在

  CMake Error at SDK_DIR/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCCompiler.cmake:69 (message):
    The C compiler
  
      "SDK_DIR/ndk/25.2.9519653/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe"
  
    is not able to compile a simple test program.
  
    It fails with the following output:
  
      Change Dir: APPLICATION_DIR/app/.cxx/RelWithDebInfo/703a16l3/arm64-v8a/CMakeFiles/CMakeTmp
      
      Run Build Command(s):SDK_DIR\\cmake\3.22.1\bin\ninja.exe cmTC_c87d1 && [1/2] Building C object CMakeFiles/cmTC_c87d1.dir/testCCompiler.c.o
      [2/2] Linking C executable cmTC_c87d1
      FAILED: cmTC_c87d1 
      cmd.exe /C "cd . && SDK_DIR\\ndk\25.2.9519653\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe --target=aarch64-none-linux-android26 --sysroot=SDK_DIR/ndk/25.2.9519653/toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments CMakeFiles/cmTC_c87d1.dir/testCCompiler.c.o -o cmTC_c87d1  -latomic -lm && cd ."
      ld: error: unable to find library -latomic
      ld: error: cannot open SDK_DIR/ndk/25.2.9519653/toolchains/llvm/prebuilt/windows-x86_64/lib/clang/14.0.0/lib/linux/libclang_rt.builtins-aarch64-android.a: No such file or directory
      ld: error: unable to find library -l:libunwind.a
      ld: error: cannot open SDK_DIR/ndk/25.2.9519653/toolchains/llvm/prebuilt/windows-x86_64/lib/clang/14.0.0/lib/linux/libclang_rt.builtins-aarch64-android.a: No such file or directory
      ld: error: unable to find library -l:libunwind.a
      clang: error: linker command failed with exit code 1 (use -v to see invocation)
      ninja: build stopped: subcommand failed.
      
      
  
    
  
    CMake will not be able to correctly generate this project.
  Call Stack (most recent call first):
    CMakeLists.txt:10 (project)

需要把SDK_DIR/ndk/25.2.9519653/toolchains/llvm/prebuilt/windows-x86_64/lib64/目录下的calng目录,复制到/lib目录中,并把clang/14.0.7修改为14.0.0

这里的14.0.0是根据错误日志中出现的路径提取出来的,在控制台中输入clang -v查看当前 clang 的版本,按照日志中出现或当前使用的 clang 版本调整。

clang

至此,NDK 中 集成 OLLVM 已经完成了。接下来是配置和使用 OLLVM。

配置 OLLVM

这部分网上参考的文档很多,这里也只是简单介绍一下参数

参数

参数 说明
-mllbm -sub 激活指令替换
-mllvm -sub_loop=3 如果激活了传递,则在函数上应用3次。默认值:1
-mllvm -bcf 激活虚假控制流程
-mllvm -bcf_loop=3 如果激活了传递,则在函数上应用3次。默认值:1
-mllvm -bcf_prob=40 如果激活了传递,基本块将以40%的概率进行模糊处理。默认值:30
-mllvm -fla 激活控制流扁平化
-mllvm -split 激活基本块分割。在一起使用时改善展平
-mllvm -split_num=3 如果激活了传递,则在每个基本块上应用3次。默认值:1

拓展参数

heroims在移植 OLLVM 时,集成了Armariris的字符串混淆功能。

参数 说明
-mllvm -sobf 编译时候添加选项开启字符串加密
-mllvm -seed= 指定随机数生成器种子

使用

可以在build.gradle中进行配置,如:

android {
    defaultConfig {
        extrnalNativeBuild {
            cmake {
                cppFlags '-mllvm -fla'
            }
        }
    }
}

也可以在CMakeLists中进行配置,如:

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mllvm -fla -mllvm -sub -mllvm -sobf")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -fla -mllvm -sub -mllvm -sobf")

输出比对

以配置了-fvisibility=hidden -ffunction-sections -fdata-sections 的获取 updatemark 为例,源码为:

static jstring getUpdate(JNIEnv *env, jobject clazz) {
    struct stat sb{};
    int updates = 0;
    int updatens = 0;
    if (stat("/data/data", &sb) == -1) {
        //获取失败
    } else {
        updatens = (int) sb.st_atim.tv_nsec;
        updates = (int) sb.st_atim.tv_sec;
    }
    std::string idRes = std::to_string(updates) + "." + std::to_string(updatens);
    return env->NewStringUTF(idRes.c_str());
}

before

before

after

after

遇到的问题

虚假控制流程的问题

实际编译的过程中,增加了-mllvm -bcf参数后,编译超过半个小时还是没有完成,移除后正常编译。
搜索了相关的问题后,发现可能是 ndk 的编译器优化 flag 在 release 时是 -O2 导致的。

This is specifically an issue with llvm / android-ndk when compiling with thumb mode. You'll either need to disable thumb compilation (annoying) or patch the llvm to not generate this type of instructions; it's not actually an obfuscator-llvm issue.

Potentially try upgrading your ndk as well, though I'm doubtful that will fix this issue. If I have extra time later I can try to find the patch I needed to create for llvm to specifically work around this issue.

但在我这边,debug 依然是没有响应,只能是去掉-bcf

CMAKELIST 的 Release 不生效问题

CMAKE_C_FLAGSCMAKE_C_FLAGS_DEBUG配置的参数都可以正常生效,但CMAKE_C_FLAGS_RELEASE配置无法在 release 时生效。只能配置在CMAKE_C_FLAGS中,然后在 CMakeLists 中判断当前环境是否为 DEBUG。

参考资料

标签:NDK,llvm,WINDOWS,clang,编译,exe,OLLVM,mllvm
From: https://www.cnblogs.com/maiiiii/p/17553519.html

相关文章

  • QGIS在Windows上下载安装与建立空间数据库连接
    场景PostGIS在Windows上的下载与安装:PostGIS在Windows上的下载与安装_霸道流氓气质的博客在上面安装postGIS成功的基础上,怎样下载安装QGIS并建立与空间数据库的连接。QGIS简介QGIS(原称QuantumGIS)是一个用户界面友好的开源桌面端软件,支持数据的可视化、管理、编辑、分析以及印刷地......
  • windows服务器不能下载apk格式文件
    随着智能手机的普及,越来越多的人使用手机上网,很多网站也应手机上网的需要推出了网站客户端,.apk文件就是安卓(Android)的应用程序后缀名,默认情况下,使用IIS作为Web服务器的无法下载此文件,那么怎么才能让IIS支持.apk文件的下载呢? IIS服务器不能下载.apk文件的原因:iis的默认MIME类型......
  • windows Mysql 压缩包版本 安装
    Mysql现如今的版本都有安装版,但是我需要老的Mysql版本(5.7),恰好下载的是压缩版本,这里记录下过程安装Mysql压缩包版本,解压后得到一个文件夹,我是x64的,我放在了C:\ProgramFiles下然后将C:\ProgramFiles\mysql\bin放进系统环境变量,这样就可以在cmd窗口使用msql的命令了管理员......
  • 树莓派3b安装ubuntu16.04,配置ssh和vnc(windows)
    1.系统安装  首先下载想要使用的系统版本,笔者选择的是32位Ubuntu16.04  下载RaspberryPi OS  首先格式化TF卡  然后加载镜像:“使用自定义镜像”,选择下载的16.04镜像  选择SD卡,然后在右下角设置中开启SSH(虽然最后也没用好像),最后点击烧录。烧录完成后进入boot......
  • Windows11美化Powershell
    1.前言稍微美化了一下win11的powershell,在此记录下免得以后忘记了流程。美化方案是:PowerShell7+OhMyPosh时间:2023-07-132.安装PowerShell7PowerShell7是目前win下比较新的一个shell工具,个人感觉要比WindowsPowerShell(PowerShell5),命令提示符(cmd)这些好用......
  • Windows电脑环境变量(用户变量、系统变量)的修改
      本文介绍在Windows10操作系统中,进行用户变量、系统变量等两种环境变量的新建、修改与删除的详细方法。  在很多时候,我们需要对Windows电脑的环境变量加以修改,例如安装一些专业软件、配置一些代码环境等等;这里就具体介绍一下这一操作的方法。  首先,我们按下Windows徽标......
  • WPF获取MainWindows实例
    WPF获取MainWindow实例在其他类中获取MainWindow实例,获取其控件,改变其控件属性等,代码如下:_mainWindow=Application.Current.Windows.Cast<Window>().FirstOrDefault(Window=>WindowisMainWindow)asMainWindow;例如在ConfigureViewModel中改变MainWindow中的某个TextB......
  • 【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Win
    问题描述PHP的WebJob,通过artisan来配置路径启动PHP任务,相关启动脚本如下:artisan_path="d:\\home\\site\\wwwroot";cd${artisan_path}echo"\n"pwdphpartisanschedule:run但是,在运行的时候遇见报错:[07/06/202301:57:31>0f21a2:INFO]/d/home/site/wwwroo......
  • Windows服务开发实践
    Windows服务开发知识学习实践步骤(1)在VisualStudio创建项目时,选择创建Windows服务项目模板(2)项目创建成功后的界面如下图。项目会自动生成一个Service1.cs文件,我们可以对他重命名FirstService.cs 点击添加安装程序后,右侧解决方案出现了ProjectInstaller.cs,双击该文件,可看到......
  • 移动windows中的目录
    win10用一段时间后c盘的installer目录和temp目录特别大,我的达到了7G和14G,用以下方法能将其挪到其他盘:OK,I'vetakentheriskanditwasworthit-everythingworksnormally,butIhavefreedthe17GBonmySSDnow.Basically,thestepsare:RestartyourPC,press......