从汇编层看64位程序运行——栈保护

大纲

  • 栈保护
  • 延伸阅读
  • 参考资料

在《从汇编层看64位程序运行——ROP攻击以控制程序执行流程》中,我们看到可以通过“微操”栈空间控制程序执行流程。现实中,黑客一般会利用栈溢出改写Next RIP地址,这就会修改连续的栈空间。而编译器针对这种场景,设计了“栈保护”机制。

栈保护

比如下面的代码,buffer[8] = 'b’这句会导致栈溢出。

int main() {
    char buffer[8] = {0};
    buffer[0] = 'a';
    buffer[1] = buffer[0] + 1;
    buffer[8] = 'b';
    return 0;
}

如果我们采用“栈保护”机制编译,即增加-fstack-protector-strong(或者-fstack-protector、-fstack-protector-all等)编译选项。

# makefile
# 定义编译器
CC := gcc

# 定义编译选项
CFLAGS := -Wall -Werror -O0 -fstack-protector-strong

# 定义目标目录
OBJDIR := build
BINDIR := bin

# 定义源文件和目标文件
SRCS := $(wildcard src/*.c)
OBJS := $(patsubst src/%.c,$(OBJDIR)/%.o,$(SRCS))

# 获取当前工作目录名,即工程目录名
PROJECT_DIR_NAME := $(notdir $(shell pwd))

# 最终目标:编译所有文件并生成可执行文件
$(BINDIR)/$(PROJECT_DIR_NAME): $(BINDIR) $(OBJS)
	$(CC) $(CFLAGS) $(OBJS) -o $@

# 通用规则:如何从每个.c文件生成.o文件
$(OBJDIR)/%.o: src/%.c $(OBJDIR)
	$(CC) $(CFLAGS) -c $< -o $@

# 规则:创建build目录
$(OBJDIR):
	mkdir -p $(OBJDIR)

# 规则:创建bin目录
$(BINDIR):
	mkdir -p $(BINDIR)

# 伪目标:清理项目
.PHONY: clean
clean:
	rm -rf $(OBJDIR) $(BINDIR)

# 伪目标:打印变量(用于调试)
.PHONY: print
print:
	@echo "SRCS = $(SRCS)"
	@echo "OBJS = $(OBJS)"
	@echo "PROJECT_DIR_NAME = $(PROJECT_DIR_NAME)"

则程序在运行时,会报出栈移除提示。
在这里插入图片描述
那编译器如何做到“栈保护”的呢?

也许听着挺高大上,但是代码面前了无秘密,其原理也非常的简单。

我们看下这段代码的汇编
在这里插入图片描述
+12和+21这两行,汇编将段寄存器fs偏移+0x28的值保存到main函数栈帧的第一个局部变量位置(-0x8(%rbp))。这个局部变量是一个隐藏变量,后续没有代码对其进行改动。

+58和+62这两行,将检测第一个局部变量的值和寄存器fs偏移+0x28的值是否一致。如果一致就说明没问题,如果不一致就说明栈被污染了。
在这里插入图片描述

延伸阅读

那么段寄存器fs偏移+0x28是什么值?它为什么会在函数调用期间值不变?

这是因为fs断寄存器保存的是当前线程的TLS(Thread Local Storage),这样这个函数在线程上调度时,并不会被其他线程影响这段空间值。

但是GDB却无法打印出FS段地址,这个需要我们对代码进行改造,引入自定义的fs_base方法

#include <asm/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>

uint64_t fs_base() {
    uint64_t fs_base;
    long result = syscall(SYS_arch_prctl,ARCH_GET_FS,&fs_base);
    if (result == -1) {
        return 0;
    }
    return fs_base;
}

uint64_t gs_base() {
    uint64_t gs_base;
    long result = syscall(SYS_arch_prctl,ARCH_GET_GS,&gs_base);
    if (result == -1) {
        return 0;
    }
    return gs_base;
}

int main() {
    char buffer[8] = {0};
    buffer[0] = 'a';
    buffer[1] = buffer[0] + 1;
    buffer[8] = 'b';
    return 0;
}

然后我们调试这段代码,可以看到被赋值到rax寄存器中的,%fs:0x28指向的值是0x6ac935d29472ff00。
在这里插入图片描述
而fs段地址通过gdb看不到
在这里插入图片描述
我们在gdb中使用下面指令来查看fs段地址

 p/x (uint64_t) fs_base()

然后查看偏移0x28的空间中的值,可以发现这个值和上面被赋值到rax寄存器中的值一致。
在这里插入图片描述
那我们如何确定它是TLS中的地址呢?

我们可以通过下面指令查看TLS的起始地址

p (void*) pthread_self()

我们会发现这个地址和我们通过fs_base获得的地址是一样的。

在这里插入图片描述

参考资料

  • https://stackoverflow.com/questions/23095665/using-gdb-to-read-msrs

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

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

相关文章

pip install安装第三方库 error: Microsoft Visual C++ 14.0 or greater is required

原因&#xff1a; 在windows出现此情况的原因是pip安装的库其中部分代码不是python而是使用C等代码编写&#xff0c;我们安装这种类型的库时需要进行编译后安装。 安装Microsoft C Build Tools软件&#xff0c;但这种方式对于很多人来说过于笨重。&#xff08;不推荐&#xf…

视图库对接系列(GA-T 1400)十九、视图库对接系列(级联)注册

背景 在上一章视图库对接系列(GA-T 1400)十八、视图库对接系列(级联)代码生成中我们已经把代码生成了,那怎么实现级联? 我们可以抓包看设备是怎么注册到我们平台的, 那我们就怎么实现就可以了。 实现 先看设备注册到我们服务端的包 步骤 注册我们可以参考视图库对接系列(…

【JVM实战篇】内存调优:内存问题诊断+案例实战

文章目录 诊断内存快照在内存溢出时生成内存快照MAT分析内存快照MAT内存泄漏检测的原理支配树介绍如何在不内存溢出情况下生成堆内存快照&#xff1f;MAT查看支配树MAT如何根据支配树发现内存泄漏 运行程序的内存快照导出和分析快照**大文件的处理** 案例实战案例1&#xff1a;…

鼠标录制器哪个好用,5款热门鼠标连点器软件分享(收藏)

鼠标录制怎么操作&#xff1f;在我们日常的工作生活中&#xff0c;经常需要用到屏幕录制工具&#xff0c;如电脑录屏或者手机录屏&#xff0c;使用鼠标录制功能的话&#xff0c;可以省时省力。鼠标录制工具可以记录用户的鼠标移动、点击和键盘输入&#xff0c;并在需要时回放这…

CodeSouler:AI赋能,编程效率的革命性飞跃!

&#x1f525; 功能大揭秘&#xff0c;让你的代码飞起来&#xff01;&#x1f525; 01 添加代码注释 &#x1f4dd; 告别繁琐&#xff0c;一键添加精准注释&#xff01;提升代码清晰度&#xff0c;让后续维护不再是难题。 02 生成单元测试 &#x1f9ea; 智能分析&#xff0c;自…

swiper插件轮播图使用方法(保姆级)

一、swiper下载 swiper官网 可以按自己的需求来下载 一般都是下载最新版本 二、swiper使用方法 1. 解压找到这两个文件&#xff0c;放到vscode对应的文件夹里面&#xff0c;记得在代码中应用这两个文件(我使用的是vscode) 这些轮播图样式都可以自己选择 也可以在官网的在线演…

数模打怪(五)之相关系数

一、什么是相关系数 相关系数&#xff1a;用来衡量两个变量之间的相关性的大小。 根据数据满足的不同条件&#xff0c;选择不同的相关系数进行计算和分析。 两种最为常用的相关系数&#xff1a;person相关系数和spearman等相关系数。 二、Person相关系数 1、什么是Person相…

Linux——进程概念详解

一、进程的基本概念 在给进程下定义之前&#xff0c;我们先了解一下进程&#xff1a; 我们在编写完代码并运行起来时&#xff0c;在我们的磁盘中会形成一个可执行文件&#xff0c;当我们双击这个可执行文件时&#xff08;程序时&#xff09;&#xff0c;这个程序会加载到内存…

【系统架构设计】数据库系统(一)

数据库系统&#xff08;一&#xff09; 数据库模式与范式数据库的结构与模式数据模型关系代数数据的规范化反规范化 数据库设计事务管理备份与恢复分布式数据库系统数据仓库数据挖掘NoSQL大数据 数据库模式与范式 数据库的结构与模式 数据库技术中采用分级的方法将数据库的结…

Linux - 冯-诺依曼体系结构、初始操作系统

目录 冯•诺依曼体系 结构推导 内存提高效率的方法 数据的流动过程 体系结构相关知识 初始操作系统 定位 设计目的 操作系统之上之下分别有什么 管理精髓&#xff1a;先描述&#xff0c;再组织 冯•诺依曼体系 结构推导 计算机基本工作流程图大致如下&#xff1a; 输入设备&a…

vscode 打开远程bug vscode Failed to parse remote port from server output

vscode 打开远程bug vscode Failed to parse remote port from server output 原因如图&#xff1a; 解决&#xff1a;

【数学建模】技术革新——Lingo的使用超详解

目录 基础知识 1. 变量声明 示例 2. 常量声明 语法格式 示例 3. 目标函数 语法格式 示例 4. 约束条件 语法格式 示例 5. 完整的Lingo模型示例 示例 解释 6. 整数变量声明 语法格式 示例 7. 非线性规划 示例 8. 多目标优化 语法格式 示例 9. 数据输入与…

TypeScript 函数类型 (二)

函数类型 函数有两种方式定义 function 关键字来定义函数 function a(){}表达式定义&#xff08;箭头函数的形式&#xff09; const a()>{}函数需要定义类型的有三个地方 入参 和 返回值 以及 函数本身 的类型, 函数本身的类型常用于表达式定义的函数 function sum(a:stri…

洛谷 P1056 [NOIP2008 普及组 T2]:排座椅 ← 贪心算法

【题目来源】https://www.luogu.com.cn/problem/P1056https://www.acwing.com/problem/content/436/【题目描述】 上课的时候总有一些同学和前后左右的人交头接耳&#xff0c;这是令小学班主任十分头疼的一件事情。 不过&#xff0c;班主任小雪发现了一些有趣的现象&#xff0c…

Ubuntu Desktop Docker 配置代理

Ubuntu Desktop Docker 配置代理 主要解决 docker pull 拉取不了镜像问题. Docker Desktop 配置代理 这个比较简单, 直接在 Docker Desktop 里设置 Proxies, 示例如下: http://127.0.0.1:7890 Docker Engine 配置代理 1.Docker Engine 使用下面配置文件即可, root 用户可…

Git的基础操作

环境&#xff1a;Linux操作系统-Centos 创建本地仓库 首先创建一个目录,命名为:gitcode mkdir gitcode进入gitcode目录&#xff0c;创建本地仓库 git init此时&#xff0c;就会创建出了一个空的仓库在当前目录下了&#xff0c;此时目录下就有git的目录了 配置Git 首先重要的…

科技出海|百分点科技智慧政务解决方案亮相非洲展会

近日&#xff0c;华为非洲全联接大会在南非约翰内斯堡举办&#xff0c;吸引政府官员行业专家、思想领袖、生态伙伴等2,000多人参会&#xff0c;百分点科技作为华为云生态合作伙伴&#xff0c;重点展示了智慧政务解决方案&#xff0c;发表《Enable a Smarter Government with Da…

which 命令在Linux中是一个快速查找可执行文件位置的工具

文章目录 0、概念1、which --help2、which命令解释 0、概念 which命令用于查找命令的可执行文件的路径which 命令在 Linux 中用于查找可执行命令的完整路径。当你在 shell 中输入一个命令时&#xff0c;shell 会在环境变量 $PATH 定义的目录列表中查找这个命令。which 命令可以…

【Neural signal processing and analysis zero to hero】- 1

The basics of neural signal processing course from youtube: 传送地址 Possible preprocessing steps Signal artifacts (not) to worry about doing visual based artifact rejection so that means that before you start analyzing, you can identify those data epic…

SQL Server Query Store Settings (查询存储设置)

参考&#xff1a;Query Store Settings - Erin Stellato 在 SQL Server 2017 中&#xff0c;有九 (9) 个设置与查询存储相关。虽然这些设置记录在sys.database_query_store_options中&#xff0c;但我经常被问到每个设置的值“应该”是多少。我在下面列出了每个设置&am…