当前位置: 首页 > news >正文

linux程序保护机制gcc编译选项

预备知识:

计算机内存的结构通常包括以下几个主要部分:
1.代码段(Code Segment):也称为文本段,存储程序的可执行指令。代码段是被标记为可执行的,程序从代码段中获取指令并执行。

2.数据段(Data Segment):也称为全局数据段,存储全局变量和静态变量的数据。数据段在程序加载时被初始化,其大小在编译时确定。

3.堆(Heap):堆是用于动态分配内存的区域。在堆上分配的内存由程序员手动管理,可以通过函数(如malloc(0和free0)进行申请和释放。堆的大小可以根据需要动态增长或缩小。

4.栈(Stack):栈是用于管理函数调用和局部变量的内存区域。栈上的内存由编译器自动管理,存储函数调用过程中的局部变量、函数参数、返回地址等数据。栈的大小是固定的,并且在程序运行期间是动态变化的。

5.常量区(Constant Area):常量区存储常量值,如字符串常量和全局的const修饰的变量。这些常量在程序运行期间是不可修改的。

6.未初始化数据段(BSS Segment):也称为bss段,存储未初始化的全局变量和静态变量。在程序加载时,未初始化的变量会被初始化为0或空值。

example code:

#include <stdio.h>int main() {printf("Hello, World!\n");return 0;
}
gcc hello.c -o hello

得到hello可执行文件

1. -pie

作用: -pie是一个编译器选项,用于在生成可执行文件时将其编译为位置无关可执行文件(Position Independent Executable,PIE)。PIE是一种可执行文件格式,它可以在内存中加载的任何地址上执行,而不依赖于固定的基地址。适用于需要增加代码执行的安全性的场景。

-pie参数与动态链接有密切的关系。具体来说,-pie参数用于生成位置无关的可执行文件,而位置无关的可执行文件通常与动态链接配合使用。

在动态链接中,可执行文件在运行时,需要依赖于动态链接器(ld.so或ld-linux.so)加载共享库(例如.so文件),以填充程序中的符号引用。这种方式允许多个可执行文件共享同一个共享库,减少内存使用并提高可执行文件的灵活性。

使用方法:

gcc -pie hello.c -o hello

验证-pie参数是否生效:

objdump -x hello

(objdump主要用于静态分析和反汇编目标文件、可执行文件和共享库)
若查找到与重定位相关的节,例如.rela.dyn和.rela.plt。如果这些节存在,则说明-pie参数已经生效,并且程序是以位置无关的方式编译的。
在这里插入图片描述
还可以查找DYNAMIC标志,以验证是否启用了动态链接。
使用readelf命令查看可执行文件的头部信息。

readelf -l hello

在输出中查找INTERP字段。如果该字段存在,并且显示了动态链接器的路径(如/lib/ld-linux.so.2),则说明可执行文件启用了动态链接。
在这里插入图片描述

2. -z noexecstack

-z noexecstack 是一个用于在Linux系统上编译可执行文件时的安全特性选项。当启用此选项时,它将堆栈标记为不可执行,意味着无法从堆栈中执行代码。这有助于防止某些类型的安全漏洞,如缓冲区溢出攻击。

使用方法:

要在编译过程中启用 -z noexecstack 选项,您需要使用兼容的编译器,如GCC,并将选项作为命令行参数传递。以下是一个使用此选项编译C程序的示例:

gcc -z noexecstack hello.c -o hello

验证 -z noexecstack 参数是否生效:

使用 readelf 命令来检查生成的可执行文件的头部信息。readelf 是一个用于查看和分析 ELF (Executable and Linkable Format) 格式文件的工具。
运行以下命令来查看可执行文件的头部信息:

readelf -l hello

在输出中查找 GNU_STACK 部分。如果 GNU_STACK 部分中存在 RWE(可读可写可执行)标志,则表示 -z noexecstack 选项未生效。如果 GNU_STACK 部分中存在 RW(可读可写)标志,则表示 -z noexecstack 选项生效。
在这里插入图片描述

3. -fstack-protector

CC_STACKPROTECT补丁的防溢出原理是: 在进程启动的时候, 在每个buffer的后面放置一个预先设置好的stack canary, 当buffer发生缓冲区溢出的时候, 肯定会破坏stack canary的值, 当stack canary的值被破坏的时候, 内核就会直接当机。

先写个简单的有溢出的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void test(void)
{char buff[64];memset(buff, 0x41, 128);     //向64大小的buffer拷贝128字节, 肯定会发生缓冲区溢出。
}int main(void)
{test();return 0;
}

关闭no-stack-protector会报段错误:

wjr@WPF3N0KZ3:~$ gcc -o test test.c -fno-stack-protector
wjr@WPF3N0KZ3:~$ ./test 
Segmentation fault

加上stack-protector:

wjr@WPF3N0KZ3:~$ gcc -o test test.c -fstack-protector
wjr@WPF3N0KZ3:~$ ./test 
*** stack smashing detected ***: terminated
Aborted

这次程序打印了一条堆栈被溢出的信息,然后就自动退出了。
反汇编:

objdump -d test > hex
0000000000001120 <__do_global_dtors_aux>:1120:	f3 0f 1e fa          	endbr64 1124:	80 3d e5 2e 00 00 00 	cmpb   $0x0,0x2ee5(%rip)        # 4010 <__TMC_END__>112b:	75 2b                	jne    1158 <__do_global_dtors_aux+0x38>112d:	55                   	push   %rbp112e:	48 83 3d c2 2e 00 00 	cmpq   $0x0,0x2ec2(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>1135:	00 1136:	48 89 e5             	mov    %rsp,%rbp1139:	74 0c                	je     1147 <__do_global_dtors_aux+0x27>113b:	48 8b 3d c6 2e 00 00 	mov    0x2ec6(%rip),%rdi        # 4008 <__dso_handle>1142:	e8 09 ff ff ff       	call   1050 <__cxa_finalize@plt>1147:	e8 64 ff ff ff       	call   10b0 <deregister_tm_clones>114c:	c6 05 bd 2e 00 00 01 	movb   $0x1,0x2ebd(%rip)        # 4010 <__TMC_END__>1153:	5d                   	pop    %rbp1154:	c3                   	ret    1155:	0f 1f 00             	nopl   (%rax)1158:	c3                   	ret    1159:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

使用-fstack-protector参数后, gcc在函数的开头放置了几条汇编代码:

112d: 55 push %rbp
112e: 48 83 3d c2 2e 00 00 cmpq $0x0,0x2ec2(%rip) # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
1135: 00
1136: 48 89 e5 mov %rsp,%rbp

   1195:	e8 d6 fe ff ff       	call   1070 <memset@plt>119a:	90                   	nop119b:	48 8b 45 f8          	mov    -0x8(%rbp),%rax119f:	64 48 2b 04 25 28 00 	sub    %fs:0x28,%rax11a6:	00 00 11a8:	74 05                	je     11af <test+0x46>11aa:	e8 b1 fe ff ff       	call   1060 <__stack_chk_fail@plt>11af:	c9                   	leave  11b0:	c3                   	ret    

在memset后,gcc要检查这个操作是否发生了堆栈溢出, 将保存在rbp的这个值与原来的值对比一下,
如果不相同, 说明堆栈发生了溢出,那么就会执行__stack_chk_fail这个函数, 这个函数是glibc实现的,
打印出上面看到的信息, 然后进程退出。

相关文章:

linux程序保护机制gcc编译选项

预备知识&#xff1a; 计算机内存的结构通常包括以下几个主要部分&#xff1a; 1.代码段(Code Segment)&#xff1a;也称为文本段&#xff0c;存储程序的可执行指令。代码段是被标记为可执行的&#xff0c;程序从代码段中获取指令并执行。 2.数据段(Data Segment)&#xff1a…...

指针与引用:C语言中的内存魔法

开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 也把我学习过程中搜集的资料分享给大家&#xff0c;希望可以帮助大家少走弯路&#xff0c;链接&#xff1a;h…...

docker desktop搭建 nginx

【docker 桌面版】windows 使用 docker 搭建 nginx 拉取 nginx 镜像 docker pull nginx运行容器 docker run -d -p 80:8081 --name nginx nginx本地磁盘创建 nginx 目录 D:\DockerRep\nginx复制 docker 中的 nginx 配置文件 查看运行的容器 docker ps -a docker cp 9f0f82d66dd…...

Redis缓存雪崩、击穿、穿透?

我们谈谈Redis在实际项目中用作缓存时经常碰到的&#xff0c;也是经常面试的三大问题&#xff1a;缓存穿透、缓存击穿、缓存雪崩&#xff0c;以及这些问题的常用解决方法。 在介绍这三大问题之前&#xff0c;我们需要先了解Redis作为一个缓存中间件&#xff0c;在项目中是如何…...

Kettle系列(一)下载安装与基础配置

Kettle系列&#xff08;一&#xff09;下载安装与基础配置 说明一、下载二、目录结构三、基础配置&#xff08;1&#xff09;环境变量&#xff08;2&#xff09;kettle配置 四、连接mysql8五、连接其他数据库六、总结 说明 更新时间&#xff1a;2023/08/13 17:47 本文记录了wi…...

MuMu模拟器运行一段时间后Device.Present耗时突然上升

1&#xff09;MuMu模拟器运行一段时间后Device.Present耗时突然上升 2&#xff09;​如何在运行过程中获得温度信息 3&#xff09;Input System鼠标更换主按键的Bug 4&#xff09;如何禁止Unity向https://config.uca.cloud.unity3d.com发送设备信息 这是第347篇UWA技术知识分享…...

14-矩阵相乘及其运算法则

矩阵与向量的乘法 在这一篇文章中我们就将基于上一篇重新审视矩阵的这个视点来理解矩阵的乘法&#xff0c;那么在这一篇&#xff0c;我们主要来看一下矩阵和向量的乘法。这里这个线性方程组是上一小节给大家举的模拟的一个非常简单的小型经济系统的例子&#xff0c;我们可以把…...

redis学习笔记(八)

文章目录 redis的配置redis的核心配置选项Redis的使用 redis的配置 cat /etc/redis/redis.confredis 安装成功以后,window下的配置文件保存在软件 安装目录下,如果是mac或者linux,则默认安装/etc/redis/redis.conf redis的核心配置选项 绑定ip&#xff1a;访问白名单&#x…...

Wlan——无线服务集和AP的基本概念以及AP的配置

目录 WLAN服务集的基本概念 AP的基本概念 AP的分类 AP模式的切换 胖&#xff08;FAT&#xff09;AP介绍 胖AP的工作模式 接入模式和路由模式的区别 胖AP的组网方式 瘦&#xff08;FIT&#xff09;AP介绍 瘦AP的工作模式 瘦AP的组网方式 胖AP和瘦AP的区别 AP的配置…...

【必看】时序逻辑仿真成组合逻辑?你知道原因吗?

对于初学者&#xff0c;一般会遇到这种情况&#xff0c;明明写的时序逻辑&#xff0c;结果仿真结果却是组合逻辑&#xff0c;然后看遍设计代码&#xff0c;始终找不到原因&#xff0c;交流群、知乎这种问题随处可见。但不要怀疑软件问题&#xff0c;modelsim这些专用软件基本不…...

PyTorch翻译官网教程-LANGUAGE MODELING WITH NN.TRANSFORMER AND TORCHTEXT

官网链接 Language Modeling with nn.Transformer and torchtext — PyTorch Tutorials 2.0.1cu117 documentation 使用 NN.TRANSFORMER 和 TORCHTEXT进行语言建模 这是一个关于训练模型使用nn.Transformer来预测序列中的下一个单词的教程。 PyTorch 1.2版本包含了一个基于论…...

SpringBoot复习:(43)如何以war包的形式运行SpringBoot程序

一、.pom.xml配置packging为war <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven…...

Dubbo高手之路2,6种扩展机制详解

目录 一、Dubbo扩展机制的概述二、Dubbo的自适应扩展机制1. 什么是自适应扩展机制2. 自适应扩展机制的使用示例 三、Dubbo的SPI扩展机制1. 什么是SPI扩展机制2. SPI扩展机制的使用示例3. Dubbo的SPI扩展机制中自定义扩展点的实现示例 四、Dubbo的自定义扩展点机制1. 什么是自定…...

C语言快速回顾(二)

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》&#xff0c;结合我自己的工作学习经历&#xff0c;我准备写一个音视频系列blog。C/C是音视频必…...

ADB连接安卓手机提示unauthorized

近期使用airtest进行自动化测试时&#xff0c;因为需要连接手机和电脑端&#xff0c;所以在使用adb去连接本人的安卓手机vivo z5时&#xff0c;发现一直提示unauthorized。后来经过一系列方法尝试&#xff0c;最终得以解决。 问题描述&#xff1a; 用数据线将手机接入电脑端&…...

【软件工程】内聚

概念 是指一个模块内部个成分之间相互关联程度的度量。也就是说&#xff0c;凝聚是对模块内各处理动作组合强度的一种度量。很显然&#xff0c;一个模块的内聚越大越好。 偶然凝聚 一个模块内的各处理元素之间没有任何联系&#xff0c;只是偶然地被凑到一起。这种模块也称为…...

支持对接鸿蒙系统的无线模块及其常见应用介绍

近距离的无线通信得益于万物互联网的快速发展&#xff0c;基于集成部近距离无线连接&#xff0c;为固定和移动设备建立通信的蓝牙技术也已经广泛应用于汽车领域、工业生产及医疗领域。为协助物联网企业终端产品能快速接入鸿蒙生态系统&#xff0c;SKYLAB联手国产芯片厂家研发推…...

java项目打包运行报异常:Demo-1.0-SNAPSHOT.jar中没有主清单属性

检查后发现pom文件中有错误&#xff0c;需要添加build内容才能恢复正常。 添加下面文件后再次启动恢复正常。 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactI…...

nginx+keepalived实现负载均衡和高可用

环境准备 IPVIP环境客户端192.168.134.174Master192.168.134.170192.168.134.100需要配置nginx负载均衡Backup192.168.134.172192.168.134.100需要配置nginx负载均衡web1服务器192.168.134.171 web2服务器 192.168.134.173 1、首先安装nginx服务器&#xff08;此处采用yum安装…...

微信小程序实现图片多点裁剪

话不多说&#xff0c;直接上代码 1、页面布局 <view class"buttons" style"height: 50px;"><view class"upload btn" style"background-color: #d18118;"bindtap"uploadImage"> 上传图片 </view><vie…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...