LLVM中期报告

news2024/11/24 14:35:04

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.coloradmin.cn/o/1672950.html

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

相关文章

Edge浏览器自动翻译功能按钮不见了

前言&#xff1a; 平时偶尔会用到Edge的页面翻译功能&#xff0c;使用挺方便。突然发现Edge浏览器的翻译功能不见 了。如下图所示&#xff1a; 解决思路&#xff1a; 1、从网上找各种解决方案也没有解决&#xff0c;其中有一个说到点右上角的三个点 2、点击设置…

构建滴滴业务中台:系统架构设计探索

在当今数字化时代&#xff0c;滴滴作为中国领先的出行平台&#xff0c;承载着数亿用户的出行需求&#xff0c;业务规模庞大且复杂多样。为了更好地支撑业务发展和提升服务质量&#xff0c;滴滴不断探索和构建业务中台&#xff0c;以实现业务的快速响应、灵活运营和持续创新。在…

深度学习之神经网络理论基础

深度学习之神经网络理论基础 人工神经元 人工神经元&#xff1a;人类神经元中抽象出来的数学模型 MP模型 mp模型&#xff1a;1943年心理学家W.S.McCulloch和数理逻辑学家W.Pitts研究出人工神经元&#xff0c;称为M-P模型。 M-P神经元&#xff08;一个用来模拟生物行为的数学模…

FileLink内外网文件交换系统解决方案

FileLink内外网文件交换系统&#xff0c;作为一种高效且安全的文件传输解决方案&#xff0c;在多个应用场景中发挥着不可替代的作用。无论是在企业内部不同子网间的文件交换&#xff0c;还是企业与外部合作伙伴之间的文件共享&#xff0c;FileLink都能提供稳定可靠的解决方案。…

Qt---文件系统

一、基本文件操作 1. QFile对文件进行读和写 QFile file( path 文件路径) 读&#xff1a; file.open(打开方式) QlODevice::readOnly 全部读取->file.readAll()&#xff0c;按行读->file.readLine()&#xff0c;atend()->判断是否读到文件尾 …

算法课程笔记——自下而上树形DP

算法课程笔记——自下而上树形DP #include<bits/stdc.h>usingnamespacestd; constintN100005; intn,a[N]; longlongdp[N][2]; vector<int> e[N]; voiddfs(intu){for(autov:e[u]){dfs(v);dp[u][1]dp[v][0];dp[u][0]max(dp[v][0],dp[v][1]);}dp[u][1]a[u]; } intmain…

一个API接口对接ChatGPT3.5/4.0,Claude3,文心一言,通义千问,智谱AI等多款AI模型,打造属于自己的AI应用

今天我要给大家介绍团队的最新项目——一个集成了ChatGPT-3.5/4.0、Claude3、文心一言、通义千问、智谱AI等多个AI模型的API模型聚合平台。仅需使用一个接口就可以对接所有AI模型 为什么要创建这个平台&#xff1f; 随着不同的AI模型陆续问世&#xff0c;每个模型都有其独特…

怎么获得公网IP?

什么是公网IP 在计算机网络中&#xff0c;公网IP&#xff08;Internet Protocol&#xff09;是指可以直接被互联网访问和通信的IP地址。相对应的&#xff0c;私网IP则是在局域网内使用的IP地址&#xff0c;无法直接被互联网访问。获得公网IP对于一些特定的网络需求非常重要&am…

C++的相关知识集

1、C概述 1 两大编程思想 c语言在c语言的基础上添加了面向对象编程和泛型编程的支持。c继承了c语言高效&#xff0c;简洁&#xff0c;快速和可移植的传统。 2 起源 与c语言一样&#xff0c;c也是在贝尔实验室诞生的&#xff0c;Bjarne Stroustrup(本贾尼斯特劳斯特卢普)在2…

解锁AI写作新纪元的文心一言指令

解锁AI写作新纪元的文心一言指令 在人工智能&#xff08;AI&#xff09;飞速发展的今天&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术取得了显著的进步。文心一言&#xff0c;作为NLP领域的一颗璀璨明星&#xff0c;以其强大的文本生成和指令理解能力&#xff0c;为…

【Docker】docker 镜像如何push到私有docker仓库

文章目录 一、 网址解析对于Linux和macOS系统&#xff1a;对于Windows系统&#xff1a; 二、 镜像push 一、 网址解析 希望 registry.meizu.com 能够解析到内网IP地址&#xff08;例如10.128.17.157&#xff09;&#xff0c;您可以通过修改主机的 hosts 文件来实现。 hosts 文…

Workfine签章方案使用说明

概述 为支持绝大部分第三方签章平台&#xff0c;Workfine针对性添加了部分动作事件与message支持。用户只需要自己开发中间代理程序&#xff0c;用于Workfine与签章平台的通讯即可完成整套签章方案。 整体业务流程图如下&#xff1a; 设计端添加发送PDF动作事件&#xff0c;生…

代理IP可靠吗?哪里可以找到可靠的代理?

需要代理来访问受限制的网站或改善您的在线隐私&#xff1f;别再犹豫了&#xff01;在这篇博文中&#xff0c;我们将探讨您可以使用的选项&#xff0c;并提供有关在哪里获取代理的指导。 首先&#xff0c;让我们了解什么是代理及其工作原理。代理充当您的设备和互联网之间的中介…

HTML哆啦A梦

目录 写在前面 HTML简介 完整代码 代码分析 系列推荐 写在最后 写在前面 谁不想拥有一只可爱的叮当猫呢&#xff1f;本期小编给大家带来了一个萌萌的哆啦A梦。 HTML简介 HTML&#xff0c;即超文本标记语言&#xff0c;是构建网页的基础技术之一&#xff0c;它是一种标…

[数据结构1.0]选择排序

鼠鼠前面的博客介绍过选择排序是常见的排序算法&#xff0c;选择排序有但不限于直接选择排序和堆排序&#xff01;那么鼠鼠今天浅谈一下选择排序&#xff01; 鼠鼠本博客用排升序来介绍选择排序&#xff01; 目录 1.直接选择排序 1.1.直接选择排序 1.2.直接选择排序特性 2…

【qt】动态属性

这里写目录标题 一.属性1.属性的好处2.添加属性3.使用属性 二.只读属性 一.属性 1.属性的好处 说到属性&#xff08;property&#xff09;&#xff0c;你们会想到什么&#xff1f;我会联想到特点&#xff0c;就是一类对象所特有的&#xff0c;在C中&#xff0c;成员数据就是这…

标准流、浮动、flex布局

标准流 浮动 特点&#xff1a; 具备顶对齐&#xff0c;行内块显示特点&#xff0c;浮动的盒子是脱离了标准流。 如果父级的宽度不够&#xff0c;浮动的盒子会掉下来 <style>.one{width: 200px;height: 200px;background-color: aqua;float: left;}.two{width: 200px;he…

zabbix监控mariadb

zabbix 服务端安装请参阅&#xff1a;红帽 9 zabbix 安装流程_红帽安装zabbix-CSDN博客 源码包安装mariadb请参阅&#xff1a;源码包安装mariadb_mariadb 11 源码编译安装-CSDN博客 在MariaDB中&#xff0c;你需要创建一个专门的用户&#xff0c;用于Zabbix进行监控。这个用户…

PingCAP 戴涛:构建面向未来的金融核心系统

作者&#xff1a;戴涛 导读 近日&#xff0c;平凯星辰解决方案技术部总经理戴涛在 2024 数据技术嘉年华活动中&#xff0c;做了主题为“构建面向未来的金融核心系统”的分享&#xff0c;本文为戴涛演讲实录的全文。 文章分析了中国金融行业的发展趋势&#xff0c;并且基于这…

Typescript 哲学 - ts模块使用最佳实践

ts的作用域 默认是全局&#xff08;global&#xff09;&#xff0c;这也是为什么在 两个ts文件声明同一个变量报错变量名冲突&#xff0c;解决方法是使某个文件以模块的形式存在&#xff08;文件顶层使用 export 、import &#xff09; In TypeScript, just as in ECMAScript 2…