OLLVM快速学习
近来,ollvm在国内移动安全,尤其是安全加固上的使用越来越广泛,ollvm的混淆和反混淆也被视为比较高等的知识之一,让很多人感到无从下手,望尘莫及。如果你在google上搜索ollvm,你会发现第一页都是中文的搜索结果。其实,llvm和ollvm在国外是比较传统的东西,说到底也只是C++代码,难度大概等同于ART系统源码的程度。
本篇文章目地是为了从另一个从未出现的角度来让一个完全不懂llvm的新手快速上手ollvm,大神请直接跳过。
注意:本文因角度不同,若引起误会,纯属个人理解不同,本人不会作出任何解释,请谅解。
1. 快速理解llvm、clang和ollvm的概念
我们不使用网上那些冗杂的阐述,一句话概括,llvm是一个完整的编译器架构,作用可以理解为制作一个编译器,llvm先将源码生成为与目标机器无关的LLVMIR代码,然后把LLVMIR代码先优化,再向目标机器的汇编语言而努力。经典编译器都可以分为前端、中层优化和后端:
我们从上图也理解了clang,是前端的一个套件,但在实际使用时,你会感觉到,我们只可以感受到clang,也只是在使用clang,因为编译的时候,是调用clang或clang++来编译源码。Ollvm呢?是基于LLVM的代码分支的代码混淆,对谁混淆?什么时候混淆?在中间表示IR层,通过编写pass(英文翻译:经过,自己理解,也不需要知道其正规的概念)来混淆IR,这样目标机器的汇编语言也就被混淆了:
当然,这里需要知道的是,即使不用ollvm,LLVM本身也是有很多pass的,我们这样简单的理解,LLVMIR本身是一种与目标机器无关的虚拟化代码,而在转化为真实汇编代码时,肯定要删除一些虚拟的东西,自然也需要pass。这样,我们就用不到200字的阐述完成了网上很多长篇大论才能达到的理解。
2、llvm与ollvm在移动加固的发展
在开始制作安卓vmp时,llvm其实是被我们暂时放弃的一个方案。因为从smali上想可以使用llvm,还必须先克服smali到底怎么成为C/C++,当时他被提及,很大原因是安卓系统后端使用了llvm,但其实ART下和llvm关系已经不大了。当时都急于上架vmp,因此大部分都是采用折衷策略,如自定义dex结构、置换指令等。随着发展,smali2c渐渐成熟,可以smali2c了,自然ollvm是必然的一个选择。但一个新的问题出现了,就像很多加固网站,需要提供源码,或编译过程中的中间文件,说到底还是源码加固。
所以想做二进制加固的ollvm分支,需要注意一下。想做到二进制加固,没有一个自己的反汇编解析引擎是不可能的,目前用capstone比较多。但要真正做自己的二进制VMP加固,首先你得有一个反汇编引擎能把指令抽出来,同时转为了自己的虚拟指令,如果接上了llvm,最完美的方案就是把LLVMIR给虚拟为自己的虚拟指令,这个难度相当于把.netframwork的IL指令给虚拟了。可以先逃避了这两个问题,ARM指令得到后,利用简单的函数式指令解析来完成这个虚拟过程。我们认为,如果只有LLVMIR,如ollvm,是没有虚拟的,只是混淆。
3、利用beyondcompare+sourceinsight4的ollvm快速上手
Ollvm如果你去网上搜索资料学习,大概是这么几种文章:“LLVM编译器架构王者-编写简单的C虚拟编译器”、“ollvm+ndk编译环境的搭建”、“从0开始学习LLVM”、“LLVM PASS的完整编写”,当然这些文章都很不错。但对于一个新手来说,看了和没看其实区别不大。因为我们要学习ollvm,必须先抓住关键,到底一个llvm是如何变为ollvm,这是最简单,最直观的学习方式。
我们去下载一份llvm4.0源码(官网http://releases.llvm.org/4.0.1/llvm-4.0.1.src.tar.xz)和ollvm源码(https://github.com/obfuscator-llvm/obfuscator/tree/llvm-4.0),之所以使用4.01,因为4.0.0是2017.03的,而4.01相对时期接近一点。然后拉入beyondcompare,这里把会话设置取消勾选“比较时间戳”,以及把比较设置为“仅文件”,时间戳因为比较时间不是我们的重点,而之所以不采用原先的文件结构比较,是因为两者都有一些空文件夹,没有比较的意义。如图:
看来主要的差别就在这些文件夹里了。先看最外层的CMakeLists.txt(整个工程使用cmake编译)等3个文件:基本都是加入了产品的一些信息和协议:
主要是其他四个文件夹:
utils文件夹:主要是Revision的细微差别
tools文件夹:ollvm中有clang文件夹,也可以看出clang是作为工具在llvm中存在,而llvm中并没有此文件夹,在llvm官网中clang是作为单独源码而存在
include文件夹(整个文件夹内都是.h文件夹):
Ollvm多了llvm\Transforms\obfuscation文件夹,可以看出ollvm添加了一些功能头文件,一共6个文件。其中有5个我们可以理解为具体参数功能,fla 参数表示使用控制流平展(Control Flow Flattening)模式,sub参数表示使用指令替换(Instructions Substitution)模式,bcf参数表示使用控制流伪造(Bogus Control Flow)模式,aesSeed参数表示aes加密随机种子,split参数表示分离代码块,我们常用的是sub\bcf\fla。混淆参数代码我们在接下来分析,先看Utils.h文件
Utils.h(功能箱):
其实这里也可以看出来,ollvm基于了llvm,使用了llvm的头文件,这些头文件也在该include文件夹。
lib文件夹(\lib\Transforms):
这里稍微麻烦点,我们还是从最外层的两个文件分析,主要添加了obfuscation目录的编译和构建:
CMakeLists.txt:
LLVMBuild.txt:
再来看IPO文件夹的两个文件:
LLVMBuild.txt:
PassManagerBuilder.cpp(从文件名可以看出,pass管理生成,ollvm就是写pass),我们分三部分解析:
导入ollvm特有的头文件
添加混淆参数flag:
首先进行全局aes(aesSeed)随机种子密码初始化,接着把ollvm混淆功能函数(split\fla\bcf\sub)添加进去,而添加的这些函数,都可以在上面include文件夹的头文件找到,
BogusControlFlow.h、Flattening.h、Substitution.h、CryptoUtils.h等。
以BogusControlFlow为例来看:
再以CryptoUtils为例来看:
最后以Split为例来看:
Split.h(分离基础块,这里可能对于BasicBlock基础块不太明白,就简单理解为代码块,也可以推测LLVM基于的是模块):
如果存在一些疑惑,请仔细对比一看,是不是全部对上了?
最后一个文件夹,obfuscation文件夹,里面就是具体的CPP代码了,是不是要加点,然后,,,
当然我们现在还是没有接触到具体的代码,但对于以上的逻辑分析清楚特别重要,为以后我们自己的pass添加铺路。下面以BogusControlFlow.cpp为例,来看看pass的编写。
********************************************************
我们使用sourceinsight4可以非常清晰的看到该代码的逻辑组成
先回到BogusControlFlow.h,看到了pass.h
接着来到BogusControlFlow.cpp的llvm pass代码处,而createBogus函数,我们在前面的PassManagerBuilder.cpp是见到过的。
往下跟,BogusControlFlow是一个结构体,跟到runOnFunction,
runOnFunction调用了bogus函数
bogus调用了addBogusFlow函数
addBogusFlow函数意为添加假流程,看来这里就是比较核心的函数实现了
其实英文写的都是非常清楚的,现在翻译挺智能的,意思为:
这里意思大概应该结合着前面学习都理解了,除了phi节点,对数据结构有点了解的朋友都知道节点,节点就有前驱和后续节点,直接看代码理解,
但在真实代码中,phi并不存在,因此我们要继续消除phi,这也是转为真实指令的重要一步,对于以上代码,我们可以如下消除:
bb就是我们刚刚见到的BasicBlock,这样我们就消除了phi节点,同时更进一步理解了addBogusFlow函数的意思,LLVM中使用reg2mem pass来对phi进行消除。至此,一切又回到了我们最初对LLVM的介绍。
七少月 2018.04
图片处理真麻烦,直接上网盘:链接:https://pan.baidu.com/s/1O1y9Kdax9w_5m6CeiX7cZw密码: kh96
OLLVM快速学习的更多相关文章
- 60分钟Python快速学习(给发哥一个交代)
60分钟Python快速学习 之前和同事谈到Python,每次下班后跑步都是在听他说,例如Python属于“胶水语言啦”,属于“解释型语言啦!”,是“面向对象的语言啦!”,另外没有数据类型,逻辑全靠空 ...
- LinqPad工具:帮你快速学习Linq
LinqPad工具:帮你快速学习Linq 参考: http://www.cnblogs.com/li-peng/p/3441729.html ★:linqPad下载地址:http://www.linq ...
- 快速学习C语言一: Hello World
估计不会写C语言的同学也都听过C语言,从头开始快速学一下吧,以后肯定能用的上. 如果使用过其它类C的语言,如JAVA,C#等,学C的语法应该挺快的. 先快速学习并练习一些基本的语言要素,基本类型,表达 ...
- 【Java线程池快速学习教程】
1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...
- 【Java的JNI快速学习教程】
1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...
- 快速学习bootstrap前台框架
W3c里的解释 使用bootstrap需要注意事项 1. 在html文件第一行要加上<!doctype html>[s1] 2. 导入bootstrap.min.css文件 3. 导 ...
- C#快速学习笔记(译)
下面是通过代码快速学习C#的例子. 1.学习任何语言都必定会学到的hello,world! using System; public class HelloWorld { public static ...
- Dapper快速学习
Dapper快速学习 我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db,而且市面上的orm框架有很多,其中有一个框架 叫做dap ...
- ASP.NET快速学习方案(.NET菜鸟的成长之路)
想要快速学习ASP.NET网站开发的朋友可以按照下面这个学习安排进度走.可以让你快速入门asp.net网站开发!但也局限于一般的文章类网站!如果想学习更多的技术可以跟着我的博客更新走!我也是一名.NE ...
随机推荐
- 【转载】VirtualBox 扩展增强包安装
1 扩展包作用 鼠标可自动在虚拟机和物理机中切换状态,而不用按快捷键解除独占功能 安装了扩展包后,可以解决 virtualbox 中 更改 ubuntu 分辨率无效的问题 2 原文地址 星朝 - Vi ...
- 为什么大多数IOC容器使用ApplicationContext,而不用BeanFactory
1. 引言 Spring框架附带了两个IOC容器– BeanFactory 和 ApplicationContext. BeanFactory是IOC容器的最基本版本,ApplicationConte ...
- WSL-Ubuntu18.04 磁盘迁移 与 ns3-gym 安装
WSL 安装 win10 版本应大于或等于 1903 win10 设置页面 输入 控制面板 并点击进入 找到 程序和功能 并打开 找到 启动或关闭 Windows 功能 并打开 向下拉 勾选 适用于L ...
- 经典c程序100例==81--90
[程序81] 题目:809*??=800*??+9*??+1 其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数.求??代表的两位数,及809*??后的结果. 1.程序分析: 2.程 ...
- Redis 数据结构之字符串的那些骚操作
Redis 字符串底层用的是 sds 结构,该结构同 c 语言的字符串相比,其优点是可以节省内存分配的次数,还可以... 这样写是不是读起来很无聊?这些都是别人咀嚼过后,经过一轮两轮三轮的再次咀嚼,吐 ...
- 如何测量Ceph OSD内存占用
前言 这个工具我第一次看到是在填坑群里面看到,是由研发-北京-蓝星同学分享的,看到比较有趣,就写一篇相关的记录下用法 火焰图里面也可以定位内存方面的问题,那个是通过一段时间的统计,以一个汇总的方式来查 ...
- linux shell简单快捷方式与通配符(元字符)echo -e文本显示颜色
1.shell常用快捷方式 ^R 搜索历史命令^D 退出^A 光标移动到命令行最前^E 光标移动到命令行最后^L 清屏^U 光标之前删除^K 光标之后删除^Y 撤销^S 锁屏^Q 解锁 2.多条命令执 ...
- iOS Transform坐标变化
在使用CGContext时,由于Quartz 2D与UIKit坐标不一致,所以需要对context进行再一次的变化,达到预期的效果. 1. 不同坐标原点介绍 在Quartz 2D中,坐标原点在画布的左 ...
- CSRF和XSS的区别
XSS是啥? xss就是跨域脚本攻击 什么是跨域脚本攻击? 就是在正常的输入框中(如:用户名修改等)插入script恶意代码,从而在你遍历数据的时候加载该js文件, 获取你的cookie或sessio ...
- MySQL第01课- CentOS + 单实例MySql编译安装总结
2016年2月,从oracle转向MySql ,碰上几个坑,特此记录 总结 1.注意环境变量.配置文件,操作过程不能出错 2.相比rpm方式安装,编译安装方式可以指定安装路径,再说安装是简单活,将来安 ...