编译带有 Pluto-Obfuscator 的 NDK

折腾着玩。

因为一些原因,需要使用带混淆的 NDK。在 NDK r21 版本的时候,还可以直接编译 OLLVM 9.0.1 然后用 clang 的几个可执行文件替换 NDK 下的同名文件,不过 NDK r21 不支持 API 30 之后的版本,需要升级到 NDK r23。这时候以前直接替换的方法无法正常编译 Native 项目,因此需要换一种方法。

这里使用的是 Pluto-Obfuscator 作为基础。根据作者自述,是可以成功将混淆 Pass 集成到 NDK 中的。不过因为后来更新的缘故,原有的方法有一些步骤需要进行改动,在这里记录一下。

从拉取 NDK 源代码到第一次编译结束的步骤与原文相同,主要是后面集成 Pass。作者将原来的多个头文件合成了一个 PassManagerBuilder.h,这样相比以前一个一个添加会方便很多。

首先将 llvm/include/llvm/Transforms/Obfuscation 文件夹整个复制到 NDK 源码目录中的 toolchain/llvm-project/llvm/include/llvm/Transforms 文件夹,然后打开 toolchain/llvm-project/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp 文件,进行下面几处更改并保存。

// 引入头文件,加在所有 include 最后
#include "llvm/Transforms/Obfuscation/PassRegistry.h"

// 在 300 行附近,找到 populateFunctionPassManager 函数
void PassManagerBuilder::populateFunctionPassManager(
    legacy::FunctionPassManager &FPM) {
  addExtensionsToPM(EP_EarlyAsPossible, FPM);
  
  registerFunctionPasses(FPM); // Add this line
  // ...
}

// 在 520 行附近,找到 populateModulePassManager 函数
void PassManagerBuilder::populateModulePassManager(
    legacy::PassManagerBase &MPM) {
  // Whether this is a default or *LTO pre-link pipeline. The FullLTO post-link
  // is handled separately, so just check this is not the ThinLTO post-link.
  bool DefaultOrPreLinkPipeline = !PerformThinLTO;

  registerModulePasses(MPM); // Add this line
  //...
}

llvm/lib/Transforms/Obfuscation 文件夹整个复制到 NDK 源码目录中的 toolchain/llvm-project/llvm/lib/Transforms 文件夹中。

修改 toolchain/llvm-project/llvm/lib/Transforms/IPO/CMakeLists.txt 文件,在最后加上 Obfuscation

add_llvm_component_library(LLVMipo
  AlwaysInliner.cpp
  Annotation2Metadata.cpp
  ArgumentPromotion.cpp
  Attributor.cpp
  AttributorAttributes.cpp
  BarrierNoopPass.cpp
  BlockExtractor.cpp
  CalledValuePropagation.cpp
  ConstantMerge.cpp
  CrossDSOCFI.cpp
  DeadArgumentElimination.cpp
  ElimAvailExtern.cpp
  ExtractGV.cpp
  ForceFunctionAttrs.cpp
  FunctionAttrs.cpp
  FunctionImport.cpp
  GlobalDCE.cpp
  GlobalOpt.cpp
  GlobalSplit.cpp
  HotColdSplitting.cpp
  IPO.cpp
  IROutliner.cpp
  InferFunctionAttrs.cpp
  InlineSimple.cpp
  Inliner.cpp
  Internalize.cpp
  LoopExtractor.cpp
  LowerTypeTests.cpp
  MergeFunctions.cpp
  OpenMPOpt.cpp
  PartialInlining.cpp
  PassManagerBuilder.cpp
  PruneEH.cpp
  SampleContextTracker.cpp
  SampleProfile.cpp
  SampleProfileProbe.cpp
  SCCP.cpp
  StripDeadPrototypes.cpp
  StripSymbols.cpp
  SyntheticCountsPropagation.cpp
  ThinLTOBitcodeWriter.cpp
  WholeProgramDevirt.cpp

  ADDITIONAL_HEADER_DIRS
  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms
  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/IPO

  DEPENDS
  intrinsics_gen
  omp_gen

  COMPONENT_NAME
  IPO

  LINK_COMPONENTS
  AggressiveInstCombine
  Analysis
  BitReader
  BitWriter
  Core
  FrontendOpenMP
  InstCombine
  IRReader
  Linker
  Object
  ProfileData
  Scalar
  Support
  TransformUtils
  Vectorize
  Instrumentation
  Obfuscation
  )

修改 toolchain/llvm-project/llvm/lib/Transforms/CMakeList.txt 文件,在最后加上 add_subdirectory(Obfuscation)

add_subdirectory(Utils)
add_subdirectory(Instrumentation)
add_subdirectory(AggressiveInstCombine)
add_subdirectory(InstCombine)
add_subdirectory(Scalar)
add_subdirectory(IPO)
add_subdirectory(Vectorize)
add_subdirectory(Hello)
add_subdirectory(HelloNew)
add_subdirectory(ObjCARC)
add_subdirectory(Coroutines)
add_subdirectory(CFGuard)
add_subdirectory(Obfuscation)

llvm/include/Eigen 文件夹整个复制到 toolchain/llvm-project/llvm/include 中。

完成以上步骤之后,即可继续执行重新编译命令:

python toolchain/llvm_android/build.py --no-build linux

最终在 out/install/windows-x86/clang-dev 中可以找到编译结果,按照原文的步骤进行文件替换即可。

在使用 NDK 进行开发的时候,有一个问题需要注意,展平控制流(Flattening 和 FlatteningEnhanced)在某些情况下并不能正常工作,也就是说,无论是 -fla 还是 -fla-ex 都有可能导致编译失败。另外,虚假控制流(Bogus Control Flow, -bcf 选项)存在某些问题会导致编译卡死,不知道是不是我自编译的二进制有问题。

最后附上编译完的二进制文件,方便有需要的人使用(仅在 NDK r23 下测试通过):OneDrive

为了编译个这玩意儿专门开了个 16 核 32GB RAM 256GB 磁盘的腾讯云,虽然是按量付费但还是很心疼啊。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇