欢迎关注个人的微信公众号《Android安全工程 》(可点击进行扫码关注)。个人微信公众号主要围绕 Android 应用的安全防护和逆向分析, 分享各种安全攻防手段、Hook 技术、ARM 汇编等 Android 相关的知识。
具体的编译NDK的LLVM的流程可参考文章:编译NDK特定的LLVM版本的流程记录
获取 ollvm 混淆部分代码:906K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6A6M7%4u0U0i4K6u0V1j5$3q4K6i4K6u0r3k6X3I4G2N6h3&6V1k6i4t1`.
复制混淆部分 pass 到 llvm12 中:
添加下面这行到 llvm-project\llvm\lib\Transforms\CMakeLists.txt 的第13行:
添加下面这行到 llvm-project\llvm\lib\Transforms\IPO\CMakeLists.txt 的 73 行:
在 llvm-project\llvm\lib\Transforms\IPO\PassManagerBuilder.cpp 导入头文件:
在同一个文件的第 93 行:
在同一个文件的第 569 行:
在 llvm-project\llvm\lib\Transforms\Obfuscation\StringObfuscation.cpp 文件:
在第 10 行把 #include "llvm/IR/CallSite.h" 改为 #include "llvm/IR/AbstractCallSite.h"
在第 15 行加入:
在同一个文件的第 174 处(共三处地方):
在 llvm-project\llvm\lib\Transforms\Obfuscation\Substitution.cpp 文件的第 215 行:
在第 319 行(原 299 行)修改 Substitution::subNeg 函数
在文件 llvm-project\llvm\lib\Transforms\Obfuscation\BogusControlFlow.cpp文件 380 添加:
在同一个文件的 422 行:
在同一个文件的 573 行:
在文件 llvm-project\llvm\include\llvm\InitializePasses.h 的第 453 行添加:
在文件 llvm-project\llvm\lib\Transforms\Obfuscation\Flattening.cpp 的 17 行添加:
在相同文件的 123 修改:
在相同文件的 239 修改:
Android.mk的参数配置(全局):
指定函数(局部):
CMakeLists.txt 的参数配置(全局):
指定函数混淆(局部):
混淆效果:
这里只是参考网上的帖子对 ollvm 整个源码下载,到编译集成到特定的 NDK 版本的过程做一个学习记录,但具体每个 pass 的性能、具体的防护效果、以及可能存在的问题在这里是暂还没深入考究,这个系列待后续继续待补充完善。
同时这块的源码、以及编译产物因体积较大,读者感兴趣可通过关注微信公众号《Android安全工程》回复关键字 ollvm 获取相关下载链接。
106K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1j5H3P5o6y4X3z5e0N6Q4x3V1k6G2L8r3I4$3L8g2)9J5k6o6p5J5i4K6u0W2P5l9`.`.
77dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6&6j5h3&6Y4P5h3W2&6N6e0l9^5i4K6u0r3L8$3I4D9N6X3#2Q4x3X3c8H3M7X3!0B7k6h3y4@1
531K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3N6r3!0G2L8r3y4Z5j5h3W2F1i4K6u0r3L8r3I4$3L8g2)9J5k6s2m8J5L8$3A6W2j5%4b7`.
flounder/llvm/include/llvm/Transforms/Obfuscation -> toolchain/llvm-project/llvm/include/llvm/Transforms/Obfuscation
flounder/llvm/lib/Transforms/Obfuscation -> toolchain/llvm-project/llvm/lib/Transforms/Obfuscation
flounder/llvm/include/llvm/Transforms/Obfuscation -> toolchain/llvm-project/llvm/include/llvm/Transforms/Obfuscation
flounder/llvm/lib/Transforms/Obfuscation -> toolchain/llvm-project/llvm/lib/Transforms/Obfuscation
add_subdirectory(Obfuscation)
add_subdirectory(Obfuscation)
Obfuscation
#include "llvm/Transforms/Obfuscation/BogusControlFlow.h"
#include "llvm/Transforms/Obfuscation/Flattening.h"
#include "llvm/Transforms/Obfuscation/Split.h"
#include "llvm/Transforms/Obfuscation/Substitution.h"
#include "llvm/Transforms/Obfuscation/CryptoUtils.h"
#include "llvm/Transforms/Obfuscation/StringObfuscation.h"
#include "llvm/Transforms/Obfuscation/BogusControlFlow.h"
#include "llvm/Transforms/Obfuscation/Flattening.h"
#include "llvm/Transforms/Obfuscation/Split.h"
#include "llvm/Transforms/Obfuscation/Substitution.h"
#include "llvm/Transforms/Obfuscation/CryptoUtils.h"
#include "llvm/Transforms/Obfuscation/StringObfuscation.h"
// Flags for obfuscation
static cl::opt<std::string> Seed("seed", cl::init(""), cl::desc("seed for the random"));
static cl::opt<std::string> AesSeed("aesSeed", cl::init(""), cl::desc("seed for the AES-CTR PRNG"));
static cl::opt<bool> StringObf("sobf", cl::init(false), cl::desc("Enable the string obfuscation"));
static cl::opt<bool> Flattening("fla", cl::init(false), cl::desc("Enable the flattening pass"));
static cl::opt<bool> BogusControlFlow("bcf", cl::init(false), cl::desc("Enable bogus control flow"));
static cl::opt<bool> Substitution("sub", cl::init(false), cl::desc("Enable instruction substitutions"));
static cl::opt<bool> Split("split", cl::init(false), cl::desc("Enable basic block splitting"));
// Flags for obfuscation
// Flags for obfuscation
static cl::opt<std::string> Seed("seed", cl::init(""), cl::desc("seed for the random"));
static cl::opt<std::string> AesSeed("aesSeed", cl::init(""), cl::desc("seed for the AES-CTR PRNG"));
static cl::opt<bool> StringObf("sobf", cl::init(false), cl::desc("Enable the string obfuscation"));
static cl::opt<bool> Flattening("fla", cl::init(false), cl::desc("Enable the flattening pass"));
static cl::opt<bool> BogusControlFlow("bcf", cl::init(false), cl::desc("Enable bogus control flow"));
static cl::opt<bool> Substitution("sub", cl::init(false), cl::desc("Enable instruction substitutions"));
static cl::opt<bool> Split("split", cl::init(false), cl::desc("Enable basic block splitting"));
// Flags for obfuscation
MPM.add(createSplitBasicBlockPass(Split));
MPM.add(createBogusPass(BogusControlFlow));
MPM.add(createFlatteningPass(Flattening));
MPM.add(createStringObfuscationPass(StringObf));
MPM.add(createSubstitutionPass(Substitution));
MPM.add(createSplitBasicBlockPass(Split));
MPM.add(createBogusPass(BogusControlFlow));
MPM.add(createFlatteningPass(Flattening));
MPM.add(createStringObfuscationPass(StringObf));
MPM.add(createSubstitutionPass(Substitution));
LoadInst *ptr_19 = new LoadInst(gvar->getType()->getArrayElementType(),
gvar, "", false, label_for_body);
ptr_19->setAlignment(Align(8));
...
LoadInst* int8_20 = new LoadInst(ptr_arrayidx->getType()->getArrayElementType(), ptr_arrayidx, "", false, label_for_body);
int8_20->setAlignment(Align(1));
...
void_21->setAlignment(Align(1));
LoadInst *ptr_19 = new LoadInst(gvar->getType()->getArrayElementType(),
gvar, "", false, label_for_body);
ptr_19->setAlignment(Align(8));
...
LoadInst* int8_20 = new LoadInst(ptr_arrayidx->getType()->getArrayElementType(), ptr_arrayidx, "", false, label_for_body);
int8_20->setAlignment(Align(1));
...
void_21->setAlignment(Align(1));
void Substitution::addDoubleNeg(BinaryOperator *bo) {
BinaryOperator *op, *op2 = NULL;
UnaryOperator *op3, *op4;
if (bo->getOpcode() == Instruction::Add) {
op = BinaryOperator::CreateNeg(bo->getOperand(0), "", bo);
op2 = BinaryOperator::CreateNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::Add, op, op2, "", bo);
op = BinaryOperator::CreateNeg(op, "", bo);
bo->replaceAllUsesWith(op);
} else {
op3 = UnaryOperator::CreateFNeg(bo->getOperand(0), "", bo);
op4 = UnaryOperator::CreateFNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::FAdd, op3, op4, "", bo);
op3 = UnaryOperator::CreateFNeg(op, "", bo);
bo->replaceAllUsesWith(op3);
}
}
void Substitution::addDoubleNeg(BinaryOperator *bo) {
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2023-6-23 15:47
被blx2024编辑
,原因: