(十四)Android NDK混淆
1、ollvm下载编译
我的是macbook环境。
参考obfuscator官网:https://github.com/obfuscator-llvm/obfuscator/wiki
执行下面的命令下载并编译:
$ git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/
$ make -j7
cmake找不到的话,上cmake.org官网下载,并设置环境变量。
编译成功后,生成的文件主要在build/bin 和 build/lib 这2个文件夹。
2、整合到NDK
网上别人有介绍在NDK目录手动创建llvm之类的新文件夹,拷贝build/bin 和 build/lib2个文件夹,有编译问题,懒得去折腾。
我的做法是:
找到Android SDK目录中的 ../ndk-bundle/toolchains/llvm 文件夹,先备份下llvm文件夹,然后将obfuscator编译好的build/bin 和 build/lib2个文件夹直接拷贝到../llvm/prebuilt/darwin-x86_64/文件夹下,直接覆盖替换。
使用最新的Android Studio编辑器,编译so库已经集成cmake,不需要去修改config.mk 与 setup.mk也是正常的。
我没按这个步骤,编译通过后直接拷贝bin目录下clang、clang++、clang-format、clang-4.0拷贝到 android-ndk-r16b/toolchains/llvm/prebuilt/linux-x86_64/bin(覆盖前请自行备份)
3、使用OLLVM
先尝试在自己so库工程的CMakeList.txt中加入:
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -fla")SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mllvm -fla")
Release编译修改成下面的配置:
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mllvm -fla")SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mllvm -fla")
再使用IDA工具查看so文件,发现函数内的代码有产生混淆修改。
这里介绍下OLLVM的混淆参数,上面的官网github的wiki有说明这些参数:
1、-fla :for the control flow flattening pass
2、-sub :for the instruction substitution pass
3、-bcf : for the bogus control flow pass
-fla:
表示使用控制流平展模式,最直观的感受就是简单的if-else语句,被嵌套成了while-switch语句,出现了很多干扰无用的分支,增加阅读难度。
-mllvm -fla: activates control flow flattening
-mllvm -split: activates basic block splitting. Improve the flattening when applied together.
-mllvm -split_num=3: if the pass is activated, applies it 3 times on each basic block. Default: 1
-sub:
表示使用指令替换模式,主要是将正常的运算操作(+,-,&,|等)替换成功能相等但表述更复杂的形式。
比如,对于表达式 a = b + c,它的等价式可以有 a = – ( -b – c), a = b – (-c) 或 a = -(-b) + c 等,原表达式可以替换成任意相等式,或者通过随机数在多个相等式中做选择。
SUB模式目前只支持整数运算操作,支持 + , – , & , | 和 ^ 操作,还是比较局限的。编译时,使用 -mllvm -sub 参数即可。下面参数可与-mllvm -sub参数配合使用。
-mllvm -sub: activate instructions substitution
-mllvm -sub_loop=3: if the pass is activated, applies it 3 times on a function. Default: 1
-bcf:
表示使用控制流伪造模式,也是对程序的控制流做操作。BCF模式会在原代码块的前后随机插入新的代码块,新插入的代码块不是确定的,然后新代码块再通过条件判断跳转到原代码块中。
更要命地是,原代码块可能会被克隆并插入随机的垃圾指令。这么多不确定性,就导致对同一份代码多次做BCF模式的混淆时,得到的是不同的混淆效果。可见,BCF混淆模式还是很强大的,不同于FLA那种较确定的混淆模式。使用BCF模式编译时配置参数 -mllvm -bcf即可,此外,BCF模式还支持其它几个参数,下面参数与-mllvm -bcf参数配合使用。
-mllvm -perBCF=20: 对所有函数都混淆的概率是20%,默认100%
-mllvm -bcf: activates the bogus control flow pass
-mllvm -bcf_loop=3: 对函数做3次混淆,默认1次
-mllvm -bcf_prob=40: 代码块被混淆的概率是40%,默认30%
备注:
参数前都需要有-mllvm,比如,CMakeList.txt中添加:
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -fla -mllvm -bcf -mllvm -sub ")
有的时候,由于效率或其他原因的考虑,我们只想给指定的函数混淆,OLLVM也提供了对这一特性的支持。比如,想对函数func()使用bcf混淆,只需要给函数func()增加bcf属性即可。
int func() __attribute__ ((__annotate__ (("bcf"))))
fla,sub和bcf三个属性可以搭配使用。如果不想对func()函数使用bcf属性,那标记为“nobcf”即可。
4、混淆代码中的字符串常量
上海交大密码与计算机安全实验室GoSSIP小组开源了他们设计的基于LLVM 4.0的孤挺花混淆框架,实现了一个用于字符串加密的pass。
字符串加密的pass位于如下目录:
Armariris/include/llvm/Transforms/Obfuscation/StringObfuscation.h
Armariris/lib/Transforms/Obfuscation/StringObfuscation.cpp
提取出该文件,放到OLLVM相同目录下,并将头文件也复制到对应目录下.
在Obfuscation下的cmakelists.txt将StringObfuscation.cpp添加到编译库中,
add_llvm_library(LLVMObfuscation
CryptoUtils.cpp
Substitution.cpp
StringObfuscation.cpp
BogusControlFlow.cpp
Utils.cpp
SplitBasicBlocks.cpp
Flattening.cpp
)
最后只需要在Transforms/IPO下的PassManagerBuilder.cpp将字符串加密的编译选项添加进去即可
1. 在PassManagerBuilder.cpp中添加引用:
#include "llvm/Transforms/Obfuscation/StringObfuscation.h"
2. 在PassManagerBuilder.cpp中的合适的地方插入以下加粗的两条函数声明,即编译时的编译参数-mllvm -sobf:
static cl::optEnableMLSM("mlsm", cl::init(true), cl::Hidden, cl::desc("Enable motion of merged load and store"));
static cl::opt Seed("seed", cl::init(""),cl::desc("seed for the random"));
static cl::opt StringObf("sobf", cl::init(false),cl::desc("Enable the string obfuscation"));
3. 在PassManagerBuilder::PassManagerBuilder()构造函数中添加随机数因子的初始化:
加粗的那一行代码就是了。
void PassManagerBuilder::populateModulePassManager(
legacy::PassManagerBase &MPM) {
...
MPM.add(createForceFunctionAttrsLegacyPass());
MPM.add(createStringObfuscation(StringObf));
MPM.add(createSplitBasicBlock(Split));
...
}
参数用法:
编译时候添加选项开启字符串加密: -mllvm -sobf
开启控制流扁平化: -mllvm -fla
开启指令替换: -mllvm -sub
指定随机数生成器种子: -mllvm -seed=0xdeadbeaf
最后命令调用:
#SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mllvm -sobf")
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mllvm -sobf")
IDA查看so库,可以看到常量字符串被混淆成乱码了。
5、OLLVM 5.0版本的参考:
https://github.com/qtfreet00/llvm-obfuscator
(十四)Android NDK混淆的更多相关文章
- Android学习之基础知识十四 — Android特色开发之基于位置的服务
一.基于位置的服务简介 LBS:基于位置的服务.随着移动互联网的兴起,这个技术在最近的几年里十分火爆.其实它本身并不是什么时髦的技术,主要的工作原理就是利用无线电通讯网络或GPS等定位方式来确定出移动 ...
- Android笔记二十四.Android基于回调的事件处理机制
假设说事件监听机制是一种托付式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器全然消失了,当用户在GUI控件上激发某个事件时,控 ...
- Android笔记(六十四) android中的动画——补间动画(tweened animation)
补间动画就是只需要定义动画开始和结束的位置,动画中间的变化由系统去补齐. 补间动画由一下四种方式: 1.AplhaAnimation——透明度动画效果 2.ScaleAnimation ——缩放动画效 ...
- Android核心分析之二十四Android GDI之显示缓冲管理
Android GDI之屏幕设备管理-动态链接库 万丈高楼从地起,从最根源的硬件帧缓冲区开始.我们知道显示FrameBuffer在系统中就是一段内存,GDI的工作就是把需要输出的内容放入到该段内存的某 ...
- Android核心分析之十四Android GWES之输入系统
Android输入系统 依照惯例,在研究Android输入系统之前给出输入系统的本质描述:从哲学的观点来看,输入系统就是解决从哪里来又将到哪里去问题.输入的本质上的工作就是收集用户输入信息 ...
- Android进阶(二十四)Android UI---界面开发推荐颜色
Android UI---界面开发推荐颜色 在Android开发过程中,总要给app添加一些背景,个人认为使用纯色调便可以达到优雅的视觉效果. 补充一些常用的颜色值:colors.xml < ...
- Android进阶(十四)Android Adapter详解
Android Adapter详解 Android是完全遵循MVC模式设计的框架,Activity是Controller,layout是View.因为layout五花八门,很多数据都不能直接绑定上去, ...
- Android之旅十四 android中的xml文件解析
在我们做有关android项目的时候,肯定会涉及到对xml文件的解析操作.以下给大家介绍一下xml文件的解析.包括DOM.SAX.Pull以及曾经我们用到的DOM4J和JDOM: 要解析的XML文件: ...
- !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
http://hujiaweibujidao.github.io/blog/2013/11/18/android-ndk-and-opencv-development-3/ Android Ndk a ...
随机推荐
- 第五章 局域网的ARP 欺骗
@ARP欺骗 arp欺骗仅限于局域网. arp欺骗虽然仅限于局域网,但却能让我们掌握网络的布局,以及如何通信:所以,我觉得这个章节非常有用. 监控本机流量 kali linux默认是不转发ip,如果我 ...
- DOTS原则和愿景
Unity Data Oriented Tech Stack基于一系列原则.这些原则为我们正在努力实现的目标提供了良好的背景.一些原则清楚地反映在代码中.其他则只是我们为自己设定的目标. 默认情况下的 ...
- php代码调试的重要性
从去年开始做PHP,基本上有的集成环境用了一个遍,XAMPP,WAMP,phpStudy.都是部署一个环境,就在环境下的默认访问目录去创建项目运行.用PHPStorm一直没能在本地做过什么调试.要么不 ...
- C#开发者必须知道的13件事情
1.开发流程 程序的Bug与瑕疵往往出现于开发流程当中.只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题. 标准化代码书写 标准化代码书写可以使代码更加易于维护,尤其是在代码由 ...
- CJL.0.1.js
/*! * Cloudgamer JavaScript Library v0.1 * Copyright (c) 2009 cloudgamer * Blog: http://cloudgamer.c ...
- fastadmin添加定时任务
安装定时任务插件后 需要在crontab -e 中添加一条记录 * * * * * /usr/bin/php /var/www/yoursitepath/public/index.php /addon ...
- php遇到Allowed memory size of 134217728 bytes exhausted问题解决方法
终端报出了Allowed memory size of 134217728 bytes exhausted错误,而且重启电脑再次执行仍然是一样.上网查了查,是因为php默认内存限制是128M,所以需要 ...
- CentOS7.1 VNC Server服务配置
一.安装VNC相关包 yum -y install tigervnc tigervnc-server tigervnc-server-module 二.复制配置模板文件为vncserver@:1.se ...
- 洛谷 题解 P1353 【[USACO08JAN]跑步Running】
动态规划 状态 dp[i][j]表示第i分钟疲劳值为j的最大值 初始 全部都为一个最小值"0" 转移 考虑休息和走 如果当前疲劳值比时间要大,显然不可能出现这种情况 如果比时间小 ...
- (一)Spring概念
目录 Spring是开源的轻量级框架 Spring核心 Spring是一站式的框架 Spring版本 Spring是开源的轻量级框架 开源是什么,不用多说: 轻量级:Spring框架的使用,不需要依赖 ...