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编译选项
预备知识: 计算机内存的结构通常包括以下几个主要部分: 1.代码段(Code Segment):也称为文本段,存储程序的可执行指令。代码段是被标记为可执行的,程序从代码段中获取指令并执行。 2.数据段(Data Segment):…...
指针与引用:C语言中的内存魔法
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 也把我学习过程中搜集的资料分享给大家,希望可以帮助大家少走弯路,链接: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在实际项目中用作缓存时经常碰到的,也是经常面试的三大问题:缓存穿透、缓存击穿、缓存雪崩,以及这些问题的常用解决方法。 在介绍这三大问题之前,我们需要先了解Redis作为一个缓存中间件,在项目中是如何…...
Kettle系列(一)下载安装与基础配置
Kettle系列(一)下载安装与基础配置 说明一、下载二、目录结构三、基础配置(1)环境变量(2)kettle配置 四、连接mysql8五、连接其他数据库六、总结 说明 更新时间:2023/08/13 17:47 本文记录了wi…...
MuMu模拟器运行一段时间后Device.Present耗时突然上升
1)MuMu模拟器运行一段时间后Device.Present耗时突然上升 2)如何在运行过程中获得温度信息 3)Input System鼠标更换主按键的Bug 4)如何禁止Unity向https://config.uca.cloud.unity3d.com发送设备信息 这是第347篇UWA技术知识分享…...
14-矩阵相乘及其运算法则
矩阵与向量的乘法 在这一篇文章中我们就将基于上一篇重新审视矩阵的这个视点来理解矩阵的乘法,那么在这一篇,我们主要来看一下矩阵和向量的乘法。这里这个线性方程组是上一小节给大家举的模拟的一个非常简单的小型经济系统的例子,我们可以把…...
redis学习笔记(八)
文章目录 redis的配置redis的核心配置选项Redis的使用 redis的配置 cat /etc/redis/redis.confredis 安装成功以后,window下的配置文件保存在软件 安装目录下,如果是mac或者linux,则默认安装/etc/redis/redis.conf redis的核心配置选项 绑定ip:访问白名单&#x…...
Wlan——无线服务集和AP的基本概念以及AP的配置
目录 WLAN服务集的基本概念 AP的基本概念 AP的分类 AP模式的切换 胖(FAT)AP介绍 胖AP的工作模式 接入模式和路由模式的区别 胖AP的组网方式 瘦(FIT)AP介绍 瘦AP的工作模式 瘦AP的组网方式 胖AP和瘦AP的区别 AP的配置…...
【必看】时序逻辑仿真成组合逻辑?你知道原因吗?
对于初学者,一般会遇到这种情况,明明写的时序逻辑,结果仿真结果却是组合逻辑,然后看遍设计代码,始终找不到原因,交流群、知乎这种问题随处可见。但不要怀疑软件问题,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音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。C/C是音视频必…...
ADB连接安卓手机提示unauthorized
近期使用airtest进行自动化测试时,因为需要连接手机和电脑端,所以在使用adb去连接本人的安卓手机vivo z5时,发现一直提示unauthorized。后来经过一系列方法尝试,最终得以解决。 问题描述: 用数据线将手机接入电脑端&…...
【软件工程】内聚
概念 是指一个模块内部个成分之间相互关联程度的度量。也就是说,凝聚是对模块内各处理动作组合强度的一种度量。很显然,一个模块的内聚越大越好。 偶然凝聚 一个模块内的各处理元素之间没有任何联系,只是偶然地被凑到一起。这种模块也称为…...
支持对接鸿蒙系统的无线模块及其常见应用介绍
近距离的无线通信得益于万物互联网的快速发展,基于集成部近距离无线连接,为固定和移动设备建立通信的蓝牙技术也已经广泛应用于汽车领域、工业生产及医疗领域。为协助物联网企业终端产品能快速接入鸿蒙生态系统,SKYLAB联手国产芯片厂家研发推…...
java项目打包运行报异常:Demo-1.0-SNAPSHOT.jar中没有主清单属性
检查后发现pom文件中有错误,需要添加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服务器(此处采用yum安装…...
微信小程序实现图片多点裁剪
话不多说,直接上代码 1、页面布局 <view class"buttons" style"height: 50px;"><view class"upload btn" style"background-color: #d18118;"bindtap"uploadImage"> 上传图片 </view><vie…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
