linux编程之mprotect

Linux中mprotect()函数详解 测试源码 //mmp.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> int *g_ps32Result; void add(int a, int b) { *g_ps32Result = a + b; } void s... 阅读详情

mprotect: 设置内存访问权限

mmap 的第三个参数指定对内存区域的保护,由标记读、写、执行权限的 PROT_READ、PROT_WRITE 和 PROT_EXEC 按位与操作获得,或者是限制没有访问权限的 PROT_NONE。如果程序尝试在不允许这些权限的本地内存上操作,它将被 SIGSEGV 信号(Segmentation fault,段错误)终止。

在内存映射完成后,这些权限仍可以被 mprotect 系统调用所修改。mprotect 的参数分别为内存区间的地址,区间的大小,新的保护标志设置。所指定的内存区间必须包含整个页:区间地址必须和整个系统页大小对齐,而区间长度必须是页大小的整数倍。这些页的保护标记被这里指定的新保护模式替换。

获得页面对齐的内存
应注意的是, malloc 返回的内存区域通常并不与内存页面对齐,甚至在内存的大小是页大小整数倍的情况下也一样。如果您想保护从 malloc 获得的内存,您不得不分配一个更大的内存区域并在其中找到一个与页对齐的区间。
您可以选择使用 mmap 系统调用来绕过 malloc 并直接从 Linux 内核中分配页面对齐内存。

mmap通过映射 /dev/zero 来分配内存页。内存将被初始化为可读和可写模式。

int fd = open (“/dev/zero”, O_RDONLY);
char* memory = mmap (NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close (fd);

然后,您的程序可以使用 mprotect 把它变成只读:

mprotect (memory, page_size, PROT_READ);

有一种监控内存访问的高级技巧,可以通过利用 mmap 和 mprotect 保护目标内存区间,然后当程序访问时候接收并处理 Linux 系统发送的 SIGSEGV 信号。代码 展示了这个技巧。

代码使用mprotect检测内存访问

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

static int alloc_size;
static char* memory;

void segv_handler (int signal_number)
{
  printf (“memory accessed!\n”);
  mprotect (memory, alloc_size, PROT_READ | PROT_WRITE);
}

int main ()
{
  int fd;
  struct sigaction sa;

  /* 初始化segv_handler为SIGSEGV的句柄。*/
  memset (&sa, 0, sizeof (sa));
  sa.sa_handler = &segv_handler;
  sigaction (SIGSEGV, &sa, NULL);

  /* 使用映射/dev/zero分配内存页。最初映射的内存为只写。*/
  alloc_size = getpagesize ();
  fd = open (“/dev/zero”, O_RDONLY);
  memory = mmap (NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0);
  close (fd);
  /* 写页来获得一个私有复制。 */
  memory[0] = 0;
  /* 使内存为不可写。 */
  mprotect (memory, alloc_size, PROT_NONE);

  /* 写分配内存区域。 */
  memory[0] = 1;
  /* 所有工作都结束;unmap内存映射。 */
  printf (“all done\n”);
  munmap (memory, alloc_size);

  return 0;
}

上述程序按照如下步骤执行:

  1. 程序为 SIGSEGV 建立一个信号处理句柄。
  2. 程序通过映射 /dev/zero 分配一个内存分页,然后通过写入数据的方式获得一个私有复本。
  3. 程序通过调用带 PROT_NONE 权限的 mprotect 保护了内存。
  4. 当程序在后续执行中写入内存时,Linux 向进程发送 SIGSEGV,这个信号被 segv_handler 句柄接收处理。这个句柄将解除内存保护,因而程序内存访问得以继续。
  5. 当信号句柄执行完成时,程序控制权返回 main 函数,程序将使用 munmap 来释放内存。

C语言_mprotect 函数深度解析与应用实践 Linux mprotect 函数深度解析与应用实践 阅读详情

相关推荐

pwn刷题num34---mprotect修改内存权限 + ret2shellcode

BUUCTF-PWN-not_the_same_3dsctf_2016 首先查保护–>看链接类型–>赋予程序可执行权限–>试运行 32位程序,小端序 开启部分RELRO-----got表可写 未开启canary保护-----存在栈溢出 开启NX保护-----堆栈不可执行 未开启PIE-----程序地址为真实地址 静态链接 ida一下 gets函数明显的栈溢出,v4只有0x2D大小,gets函数对输入的字符串没有大小限制 看一下栈区 v4距离返回地址(r所在位置)0x2d个字节 找

tbsqigongzi的博客 2442

Linux下查看内存使用状况的命令:free -h

total:指一共有多少内存; used:正在被使用的内存; free:完全空闲中的内存; shared:共享内存(无实际用处?) buffer/cache:缓存缓冲内存; available:真实可用的内存; cache(内存中的高速缓存)的作用:提高cpu读取数据的速度;(访内存比访问外存花费时间少,划分部分内存作为缓存区,提高性能---高效率的读) buffer(内存中的缓冲区):为了提高写硬盘的速度;(高效率的写) 参考书籍:运维手册 ...

JoggingPig的博客 2377

手把手教你用mprotect()实现Linux内存页权限动态切换(附完整示例代码)

本文深入解析了Linux系统编程中mprotect()系统调用的核心原理与实战应用。通过详尽的代码示例,手把手教你如何利用mprotect()动态切换内存页的读写执行权限,实现安全沙箱、JIT编译等高级功能,并涵盖错误处理、性能优化等工程化最佳实践。

weixin_29231263的博客 185

mprotect

mprotect是一个在Linux操作系统中使用的函数,它允许用户修改一段指定内存区域的访问权限。

qq_42805085的博客 1080

FPGA实战:手把手教你实现VESA DSC编码(附Verilog代码解析)

本文详细介绍了如何使用FPGA实现VESA DSC编码器,包括核心架构设计、Verilog代码实现与优化技巧。通过流水线设计、色彩空间转换和预测编码等关键技术,帮助开发者掌握工业级DSC编码器的开发流程,并提供实用的调试与性能优化方法。

weixin_29165725的博客 405

ESP8266入门(一)固件烧录及常见问题分析

为了实现对数据的远程收集和分析,偶然间发现了esp8266这个模块,对此进行了深入的学习,可是在学习之初遇到了大量的问题,这个系列文章就为大家讲讲我遇到的坑以及解决办法,还有esp8266如何连上oneNet云平台的方法。因为我用的是esp8266nodemcu,可以直接连接usb进行烧录,如果用模块的话接线就比较麻烦,可以去搜搜看.

Jerryxuzherui的博客 8955

linux 关于虚拟内存的几个系统调用

《linux/UNIX系统编程手册》中提到的一个关于虚拟内存的几个系统调用,在有些场景下需要对应用程序的虚拟内存进行进一步的调优时经常需要用到这几个系统调用。 mprotect mproect系统调用主要用于修改内存区域上的权限,函数原型如下: #include <sys/mman.h> int mprotect(void *addr, size_t len, int prot); addr: 所要修改的虚拟内存区域的起始地址,其中addr地址必须与系统页(sysconf(_SC_P

weixin_42730667的博客 2830

MIA文献阅读 —— 深度学习在医学图像分析中的最新进展及临床应用【2024】_再现性;深度学习

coderVAEVAEVAE) (Kingma威林,2014)在概率性的工作方式学习观测数据之间的映射空间x∈Rmx∈R^mx∈Rm 和潜在的空间z∈Rnmnz∈Rn(m>>n)。作为一个潜变量模型,VAEVAEVAE制定这个问题作为观察样品的最大化对数似logpxlog∫px∣zpzdzpx∣zp (x | z)p(x∣z)可以很容易地使用神经网络建模,和pzp (z)

2401_84181704的博客 1243

深入解析Linux中mprotect()函数的内存保护机制

本文深入解析Linux系统中mprotect()函数的内存保护机制。作为内存管理的核心系统调用,mprotect()能精确控制内存区域的读、写、执行权限,是保障程序安全与健壮性的关键。文章通过剖析其工作原理、内核实现流程(涉及VMA、页表与TLB刷新),并结合制造段错误、动态代码生成(JIT)等实战示例,详细展示了其应用场景与避坑指南。

yhn456789的博客 966

安卓集成华为HMS Scankit实现自定义扫码功能

实现扫码功能 使用的是集成华为扫描的SDK,UI界面借鉴的是谷歌官方的Zxing项目中的自定义view,两者结合实现。 先上效果图: 先在项目根级别(build.gradle)当中配置HMS Core SDK的Maven仓地址。 // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huaw

qq_47625961的博客 5512

42、Windows Server Update Services(WSUS)全面指南

本文全面介绍了Windows Server Update Services(WSUS)的安装、配置、管理与优化策略。内容涵盖WSUS基础认知、客户端更新问题解决、多服务器架构设计、计算机分组策略、更新审批与报告查看,并深入探讨了SSL加密配置、性能优化、与其他系统(如AD和SCCM)集成以及常见故障排查方法。通过本指南,IT管理员可高效部署和管理企业级软件更新,提升安全性和运维效率。

cicd6pipeline的博客 99

Linux下定位内存踩踏问题的一种方法

我们在Linux下用C/C++开发具有一定复杂性的系统时,需要集成多个部门开发的SDK。内存越界的问题,往往让人头疼。本文提供了一种思路,用来定位内存踩踏。

Hi20240217的博客 1387

【CAN总线测试】——通讯相关诊断测试

本章主要介绍通讯相关诊断测试用例设计

LOVE135149的博客 1816

linux c内存检测,Linux C调试库检测内存损坏

有时以前在带有简单MMU的嵌入式系统上工作时,我曾经动态编程这个MMU以检测内存损坏.例如,在运行时的某个时刻,foo变量被一些意外数据覆盖(可能是通过悬空指针或其他任何东西).所以我添加了额外的调试代码:>在init时,foo使用的内存被指示为MMU的禁区;>每当foo被故意访问时,就可以在之前禁止访问该区域;>添加了MMU irq处理程序以转储主服务器和负责违规的地址.这实际...

weixin_42322467的博客 221

一篇文章足够你学习Bluez,提供史上最全的Bluez教程,让你告别Bluez从入门到放弃

Bluez是真的难,说“入门到放弃”真的毫不夸张,Bluez的学习曲线陡峭,要求对Linux 系统/驱动概念、D-Bus 通信和蓝牙协议都有要求,加上网络上其实没有一个完整的介绍Bluez系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度。

朝气蓬勃 2541

2026年03月CCF-GESP编程能力等级认证C++编程一级真题解析

本文收录于专栏《。订阅后可阅读专栏内所有文章。

人生就是一个不断学习的过程 341

preadv2系统调用及示例

本文介绍了Linux系统编程中的三个重要函数:preadv2、pwritev2和pkey_mprotect。preadv2结合了pread和readv的功能,支持从指定偏移量分散读取数据到多个缓冲区,并可通过flags参数控制I/O行为。pwritev2是其写入版本,支持将多个缓冲区的数据集中写入到指定偏移量。pkey_mprotect是mprotect的扩展,允许将内存区域与特定保护键关联,实现更细粒度的内存访问控制。这些函数都提供了更灵活的I/O和内存管理能力,适合高性能应用场景。

悟空看八戒烤熟了没的专栏c)4Upqt4SeVk 835

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

linux 自修改代码 smc,如何在x86程序集中编写自修改代码

哇,这比我想象的要痛苦得多 . 100%的痛苦是linux保护程序不被覆盖和/或执行数据 .两个解决方案如下所示并且涉及了很多谷歌搜索,所以有点简单地把一些指令字节和执行它们是我的,在页面大小上的mprotect和对齐是从谷歌搜索中剔除的,我必须为这个例子学习的东西 .自修改代码是直截了当的,如果您接受程序或至少只是两个简单的函数,编译然后反汇编,您将获得这些指令的操作码 . 或者使用nasm来...

weixin_29251131的博客 285

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Linux内存保护实战:mprotect()函数防止内存越界的5个关键技巧

本文深入探讨了Linux系统编程中利用mprotect()函数进行内存保护的5个实战技巧。通过设置防护页隔离缓冲区、动态切换内存权限、结合信号处理与堆栈回溯定位错误根源等方法,开发者可以主动预防和捕获内存越界、释放后使用等顽疾,构建更健壮、安全的C/C++应用程序。

echo99的专栏 715

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

用mprotect()给Linux进程内存上锁:从SIGSEGV信号处理到内存权限管理

本文深入探讨了如何使用Linux的mprotect()系统调用实现进程内存的动态权限管理,从SIGSEGV信号处理到构建安全沙箱的实战应用。通过详细的代码示例和场景分析,展示了如何利用内存权限控制保护敏感数据、实现反调试机制,并优化性能以应对高频访问场景。

k8l9m0n的博客 182

pwn学习日记Day5 基础知识积累

知识杂项 int mprotect(const void *start, size_t len, int prot); mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。 int fflush(FILE *stream) fflush():会强迫将缓冲区内的数据写回参数stream 指定的文件中. 如果参数stream 为NULL,ff...

anxiong1803的博客 239
上一篇: linux编程之定时器
下一篇: Makefile常用函数总结
刘军卫
博客等级 码龄19年 1143粉丝 245原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值