LLVM中期报告

1.主要开展的工作

研究对LLVM IR层面进行代码混淆,分析IR的指令 ,并且实现混淆
从LLVM代码混淆的角度出发,函数之间的正常调用构成了待混淆程序的原始控制流,不同的基础代码块构成了一个个的函数,每个基础代码块又是由一条一条程序语句构成的,每条程序语句可以看做是一条指令。这些细节可以帮助理解算法并实现代码混淆,基于LLVM的代码混淆就是通过对函数、代码块、程序语句和指令的处理,来混淆程序的控制流、数据流和逻辑等

2.研究成果

2.1实验环境的搭建
操作系统 Ubuntu 20.04.6
编译器版本 Obfuscator-LLVM 4.0.1
前端 Clang、clang++、others
编程语言 C、C++
目标平台 x86_64-unknown-linux-gnu
安装LLVM的方式有很多,可以从官方上下载预编译好的包,也可以用源码进行编译。这里我们用源码进行编译,版本是4.0.1的版本
我们使用如下命令进行了构建:
$cd llvm-project
$mkdir build && cd build
$cmake -G “Unix Makefiles” -DLLVM_ENABLE_PROJECTS=“clang” -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=“X86” -DBUILD_SHARED_LIBS=On …/llvm
$make

-G 指定为 Unix Makefiles
使用 DCMAKE_BUILD_TYPE 选项指定编译的版本为 Release,一共有四种模式可选,分别为Debug, Release, RelWithDebInfo和MinSizeRel。使用 Release 可以节省空间,省略调试信息。
DLLVM_TARGETS_TO_BUILD 指定目标平台的架构。
-DLLVM_ENABLE_PROJECTS表明还需要编译的项目,这里指定 clang,可以根据需要加入其他子项目。
-DBUILD_SHARED_LIBS 指定使用动态链接来链接LLVM的库,默认取值Off代表静态链接

2.2 LLVM IR
LLVM的核心就是LLVM IR,LLVM项目从一系列围绕LLVM IR工具
IR有三种等价的表达形式:
1.内存表示(Instruction类等)
2.被压缩的磁盘表示(位码文件)
3.人工可读文本的磁盘表示(LLVM汇编文件)
我们用编写的sum.c样本作为示例
int sum(int x,int y)
{
return x+y;
}
生成位码
clang sum.c -emit-llvm -c -o sum.bc
生成汇编
clang sum.c -emit-llvm -s -c -o sum.ll
汇编上述LLVM IR 汇编文本
llvm-as sum.ll -o sum.bc
从位码转换为IR汇编文本,反汇编程序:
llvm-dis sum.bc -o sum.ll

在LLVM IR中只有 .ll文件是人为可读的文件
在这里插入图片描述

2.3 LLVM IR基本块分割技术

基本块分割即将一个基本块分割为等价的若干个基本块,在分割后的基本块之间加上无条件跳转
在这里插入图片描述
基本块分割不是纯正的代码混淆技术,但是在以基本块为基本单位的代码混淆技术中,基本块的数量越多,进行代码混淆后的复杂度越大,通过人为增加基本块的数量,可以达到提高代码混淆效果的目的。其实现思路即判断和遍历每个函数中不包含PHI指令的基本块,研究根据指定的一个基本块会被分裂成几个基本块的个数,计算出对每一个基本块进行分割的次数再进行分割即可

待混淆的函数F,混淆后的函数为O(F)
输入:待混淆函数F
输出:混淆后的函数O(F)
步骤:
Begin
if(toObfuscate(&F))then
do split(Function &F)
for basic blocks in iterator do
containsPHI()
shuffle()
……
splitBasicBlock()
end
endif
end
主要函数 功能描述
bool toObfuscate(Function &F) 检测是都启动了split功能
bool containsPHI(BasicBlock *b) 检测如果它的size(即包含的指令数)只有1个或者包含PHI节点,则不分割该block
Void shuffle(std::vector<int

&vec) 用shuffle打乱指令的顺序
BasicBlock *splitBasicBlock(Instruction *I, const Twine &BBName = “”,bool Before = false) 基本块分割即将一个基本块分割为等价的若干个基本块,在分割后的基本块之间加上无条件跳转

给出指令
$clang sum.c -S -emit-llvm -o sum.ll
$clang sum.c -S -emit-llvm -o sumpass.ll -mllvm -split
以sum.c为示例
在这里插入图片描述
在这里插入图片描述
2.4控制流平坦化混淆技术
在这里插入图片描述
算法生成一个选择指令swtichl,并将原有的基本块均作为switch指令的后继跳转,由选择指令的选择变量switchVtr参数决定在每一次的选择中哪一个基本块作为其后继跳转。
为了实现这一目标,在所有原基本块的开头增加选择标识数指令,在基本块的尾部添加新生成选择变量的指令。此外,算法还生成一个调度分发块,作为所有原基本块的后续跳转。调度分发块的后继节点为选择指令,调度分发块会将所有原基本块传递的选择变量传递给选择指令,选择指令继续下一个循环,直到将所有原基本块执行完毕。
此外,由于LLVM IR作为一种静态单赋值(SSA)形式的代码表示[9],即每个变量都只能被赋值一次,而控制流平坦化算法在执行后,所有原基本块的前驱块都变成了分发块,因此PHI指令发生了损坏。同时,平坦化后原基本块之间会不存在确定的前后关系(由分发块决定),因此某些变量的引用可能会损坏,称之为逃逸变量,这些逃逸变量在编译时会出现分不清定义和引用顺序的问题。所以在算法的最后需要修复所有的PHI指令和逃逸变量。
这种混淆算法可以有效增加程序的复杂性和安全性,大大提升逆向分析者的分析难度。混淆后程序的控制流为:
(1)从入口块进入,执行入口块,然后跳转到分发块;
(2)根据分发块中switch指令跳转到对应的基本块;
(3)执行完分发的基本块后跳转到统一的返回块;
(4)返回块跳转到分发块,分发块读取基本块中switch指令的case值,继续进行下一次分发和跳转。

待混淆函数为F,混淆后的函数为O(F)
步骤:
Begin
createLowerSwitchpass()
for basic block in function iterator do
save original basic block
end
AllocaInst() and ConstantInst::Get(…)
BasicBlock::Create()
SwitchInst::Create()
caesVar
loopEntry
loopEnd
for basic blocks in original basic block iterator do
put all basic block in switch,
change terminator instruction,
addCase(numCase,i)
reaalculate switch variable
end
end
主要函数 功能描述
createLowerSwitchPass() LLVM底层Switch指令创建口
AllocaInst() LLVM创建指令,并为指令分配地址空间创建了一个switch用的变量
ConstantInst::get() 创建常量,并为常量赋值
BasicBlock::Create() 创建基本块的接口
SwithchIns::Create(&f->begin(), swDefault, 0, loopEntry) 创建上层Switch指令接口
addCase(numCase,i) 创建Switch指令的各个分支的接口
给一个样例test.c进行展示
int test(int a, int b)
{
while(a!=0)
{
a=a+b;
}
if (b>5)
{
b-=1;
b=a+b;
}
return 0;
}
给出指令:
$clang test.c -S -emit-llvm -o test.ll
$clang test.c -S -emit-llvm -o testpass.ll -mllvm -split -mllvm -fla
在这里插入图片描述
在这里插入图片描述
2.5 LLVM IR指令替换技术
指令替换技术可以将指定的IR指令替换为功能相同但更复杂的指令,从而实现对IR的混淆。
指令替换的方式众多,其中最主要的方式是对运算指令的替换。在对运算指令的替换中,首先遍历需要混淆的函数或基本块中的指令,当检测到指定的指令后,在对应的位置创建混淆的指令,并取代原来的指令。同样的运算指令可以有多种不同的替换方式,混淆的强度主要取决于具体的实现过程,将不同的替换方式进行搭配可以提高代码混淆的效果。
在这里插入图片描述
待混淆的指令I,混淆后的指令为O(I)
输入:待混淆的指令I
输出:混淆后的指令O(I)
步骤:
Begin
if(I.getOpcode() == Instruction::
**)
Substitution(I)
ToRemove(I)
endif
end
主要函数 功能描述
unsigned getOpcode() const {
return getValueID() - InstructionVal;
} 检测指令的运算类型
void Substitution(Instruction& I) 对指令进行替换
void ToRemove(Instruction& I) 删除原有的指令
以test.c为例,进行两种不同的指令替换:
#include <stdio.h>
int main() {
int x = 0;
int y = x + 1;
printf(“%d\n”, y);
return 0;
}
$clang test.c -s -emit-llvm o -test.ll
$clang test.c -s -emit-llvm -subtest -o -test.ll
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自定义类型——结构体、枚举和联合

自定义类型——结构体、枚举和联合 结构体结构体的声明匿名结构体结构体的自引用结构体的初始化结构体的内存对齐修改默认对齐数结构体传参 位段枚举联合 结构体 结构是一些值的集合&#xff0c;这些值被称为成员变量&#xff0c;结构的每个成员可以是不同类型的变量。 数组是…

【随笔】Git 高级篇 -- 远程跟踪分支 git checkout -b | branch -u(三十五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

向银行家应用程序添加日期

● 首先我们将下面图片上的时间更换成现在的时间 const now new Date(); const day now.getDate(); const month now.getMonth() 1; const year now.getFullYear(); const hour now.getHours(); const min now.getMinutes();labelDate.textContent ${day}/${month}/$…

parallelsdesktop19密钥激活 PD19虚拟机完整图文安装教程

Parallels Desktop 19 &#xff08;简称 PD 19)是最新发布的 macOS 平台的 windows 虚拟机&#xff0c;本文是使用 Parallels Desktop 19 虚拟机安装 Windows 的详细图文破解安装教程。 一下载安装 Parallels Desktop 软件下载完成后打开&#xff0c;双击打开 安装.dmg Para…

3. 深度学习笔记--优化函数

深度学习——优化器算法Optimizer详解&#xff08;BGD、SGD、MBGD、Momentum、Adagrad、Adadelta、RMSprop、Adam、Nadam、AdaMax、AdamW &#xff09; 0. GD &#xff08;梯度下降&#xff09; Gradient Descent&#xff08;梯度下降&#xff09;是一种迭代优化算法&#xf…

汇昌联信电商:拼多多新手怎么做店铺的免费流量会慢慢起来?

在拼多多上开店&#xff0c;新手们往往面临着如何吸引免费流量的挑战。毕竟&#xff0c;流量是店铺生存和发展的血脉&#xff0c;没有流量&#xff0c;就没有销量&#xff0c;店铺也就失去了生命力。那么&#xff0c;作为拼多多新手&#xff0c;如何做才能让店铺的免费流量慢慢…

初识C语言——第十九天

for循环 1.简单概述 2.执行流程 3.建议事项&#xff1a;

RuoYi-Vue-Plus (SpringCache、CacheManager、@Cacheable、缓存雪崩、击穿、穿透)

一、概述 1、SpringCache是Spring提供的一个缓存框架&#xff0c;在Spring3.1版本开始支持将缓存添加到现有的spring应用程序中&#xff0c;在4.1开始&#xff0c;缓存已支持JSR-107注释和更多自定义的选项。 2、SpringCache利用了AOP&#xff0c;实现了基于注解的缓存功能&…

基于Java的qq截图工具参考论文(论文 + 源码)

【免费】基于Java的qq截图工具.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89304179 基于Java的qq截图工具 摘要 当今时代是飞速发展的信息时代&#xff0c;人们在对信息的处理中对图像的处理量与日俱增&#xff0c;这一点在文档人员上显得非常突出。 本软…

Linux下Telemac-Mascaret源码编译安装及使用

目录 软件介绍 基本依赖 其它可选依赖 一、源码下载 二、解压缩 三、编译安装 3.1 修改环境变量设置文件 3.2 修改配置文件 3.3 编译安装 四、算例运行 软件介绍 TELEMAC-MASCARET是法国电力集团(EDF)的法国国立水利与环境实验室开发的一款研究水动力学和水文学领域的…

宿舍管理系统代码详解(登录界面)

之前已经对这个管理系统进行了大体上的结构的展现&#xff0c;后面的篇章将对其中的前端代码进行详细的介绍与展示。 目录 一、数据库建表 二、登录界面前端代码 1.样式展示 2.代码详解 &#xff08;1&#xff09;template部分 &#xff08;2&#xff09;script部…

DC/DC 隔离定电,压输入电源(0.1-3W)介绍

定电压输入非稳压输出 SMD(0.25-2W)系列&#xff0c;典型性能:直流输入、直流输出隔离型模块电源SMD 表贴型产品&#xff0c;完全实现采用全自动贴片机来组装和满足回流焊工艺&#xff0c;大大提高产能和人工费用。此产品小&#xff0c;效率高&#xff0c;低输出纹波及提供 300…

SSH 免密登录,设置好仍然需要密码登录解决方法

说明&#xff1a; ssh秘钥登录设置好了&#xff0c;但是登录的时候依然需要提供密码 查看系统安全日志&#xff0c;定位问题 sudo cat /var/log/auth.log或者 sudo cat /var/log/secure找到下面的信息 Authentication refused: bad ownership or modes...&#xff08;网上的…

重大升级 | OpenSCA SaaS全面接入供应链安全情报!

结合社区用户反馈及研发小伙伴的积极探索&#xff0c; OpenSCA 项目组再次发力&#xff0c;SaaS版本重大升级啦&#xff01; 用户的需求是OpenSCA前进的动力&#xff0c;欢迎更多感兴趣的朋友们积极试用和反馈~ 更 新 内 容 1.全面接入云脉XSBOM供应链安全情报 2.强大的资产…

嫦娥六号揭秘真相:阿波罗登月是真是假?一文终结所有疑问!

近期&#xff0c;嫦娥六号的成功发射如同璀璨的星辰&#xff0c;再次将人们的视线聚焦于浩瀚的宇宙&#xff0c;与此同时&#xff0c;网络上关于美国阿波罗登月是否造假的争议也如潮水般涌现。一些声音宣称&#xff0c;嫦娥六号的发射为揭示美国阿波罗登月任务的真实性提供了关…

宝塔面板各种疑难杂症处理命令教程

下载地址&#xff1a;宝塔面板各种疑难杂症处理命令教程 这份宝塔面板各种疑难杂症处理命令教程&#xff0c;可以解决市面上遇到的各种难题&#xff0c;建议有技术能行的下载使用&#xff0c;小白也可以下载来学习可以帮助你解决宝塔面板遇到的各种难题

对中介者模式的理解

目录 一、场景1、题目 【[来源](https://kamacoder.com/problempage.php?pid1094)】1.1 题目描述1.2 输入描述1.3 输出描述1.4 输入示例1.5 输出示例 二、不采用中介者设计模式1 代码2 问题 三、中介者设计模式1 代码2 更好的例子 四、个人思考 一、场景 设计模式不是银弹&am…

宝塔纯净版 7.6.0版本无需手机登录 [稳定版本/推荐]

下载地址&#xff1a;宝塔纯净版 7.6.0版本无需手机登录.zip 宝塔纯净版介绍 无需手机登录&#xff1a;不再有手机登录提示&#xff0c;或按照提示输入任意手机号密码即可模拟绑定&#xff1b; 安全&#xff1a;剥离了所有与宝塔官方的通信、上报、下发&#xff1b;并且不与…

有哪些网络兼职适合大学生参与?揭秘几个简单又实用的兼职机会

有哪些网络兼职适合大学生参与&#xff1f;揭秘几个简单又实用的兼职机会 对于大学生而言&#xff0c;除了专注于学业&#xff0c;利用空余时间参与一些网络兼职&#xff0c;不仅能锻炼个人技能&#xff0c;还能为未来的职业生涯积累宝贵的经验。想象一下&#xff0c;步入社会…

Linux-磁盘管理类实训

一、Linux分区和磁盘操作命令 &#xff08;1&#xff09;将系统内所有的分区&#xff08;文件系统&#xff09;列出来&#xff09; &#xff08;2&#xff09;将系统中所有特殊文件格式及名称都列出来 &#xff08;3&#xff09;将/bin下面的可以用的磁盘容量以易读的容量格式…