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

深入理解Linux内存保护:mprotect函数源码解析

前言

在Linux系统编程中,内存管理是一个核心话题。今天我们来深入分析musl libc中mprotect函数的实现,看看它是如何工作的。

源码分析

#include <sys/mman.h> #include "libc.h" #include "syscall.h" int __mprotect(void *addr, size_t len, int prot) { size_t start, end; start = (size_t)addr & -PAGE_SIZE; end = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE; return syscall(SYS_mprotect, start, end-start, prot); } weak_alias(__mprotect, mprotect);

核心要点解析

1️⃣ 为什么需要页对齐?

Linux内核的内存保护是‌以页(Page)为单位‌的,通常是4KB(4096字节)。

start = (size_t)addr & -PAGE_SIZE;

这行代码的作用是‌向下取整到页边界‌。

  • -PAGE_SIZE在补码表示下是0xFFFFF000(假设PAGE_SIZE=4096)
  • & -PAGE_SIZE相当于保留高位,低位清零,实现页对齐

举例‌:

  • addr = 0x1005,PAGE_SIZE = 0x1000
  • start = 0x1005 & 0xFFFFF000 = ‌0x1000‌ ✅

2️⃣ 结束地址的向上取整

end = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE;

这里需要‌向上取整到页边界‌,技巧是先加上PAGE_SIZE-1再对齐。

举例‌:

  • addr = 0x1005,len = 100,PAGE_SIZE = 0x1000
  • addr + len = 0x1069
  • 加上 PAGE_SIZE-1 = 0x1069 + 0xFFF = 0x2068
  • 对齐后 end = 0x2068 & 0xFFFFF000 = ‌0x2000‌ ✅

这样就覆盖了 [0x1000, 0x2000) 整个页范围。

3️⃣ 系统调用封装

return syscall(SYS_mprotect, start, end-start, prot);

调用真正的系统调用,参数为:

  • start‌: 起始地址(已对齐)
  • end-start‌: 实际保护的内存大小
  • prot‌: 保护标志(PROT_READ/WRITE/EXEC等)

4️⃣ weak_alias 的妙用

weak_alias(__mprotect, mprotect);

这创建了一个‌弱符号别名‌,允许用户自定义mprotect函数来覆盖默认实现,常用于:

  • 调试 Hook
  • 安全沙箱
  • 内存检测工具

实际应用场景

表格

场景用法示例
🛡️ 数据保护禁止写入代码段`mprotect(code, len, PROT_READPROT_EXEC)`
🔒 安全加固栈不可执行启动时设置栈为 PROT_READPROT_WRITE
🐛 调试标记内存为只读检测溢出mprotect(buf, size, PROT_READ)

完整示例

#include <sys/mman.h> #include <stdio.h> #include <string.h> int main() { char buf; // 先可写 strcpy(buf, "Hello"); printf("%s\n", buf); // 改为只读(会保护整个页) if (mprotect(buf, 4096, PROT_READ) == 0) { // buf = 'X'; // ❌ 段错误! printf("内存已保护\n"); } return 0; }

总结

表格

知识点说明
页对齐内核以页为单位管理权限
位运算技巧& -PAGE_SIZE快速对齐
向上取整+PAGE_SIZE-1再对齐
weak_alias允许函数覆盖,灵活性强

这个看似简单的函数,体现了‌系统编程的精髓‌:理解硬件约束,用最少的代码高效解决问题!💡


参考资料‌:

  • musl libc源码
  • Linux man page:man 2 mprotect

觉得有用就点个赞吧👍 欢迎评论区讨论!

#Linux #系统编程 #mprotect #musl #内存管理

http://www.jsqmd.com/news/1077748/

相关文章:

  • 终极AI视频帧率提升指南:使用Flowframes让视频更流畅的完整教程
  • League Akari:英雄联盟玩家的智能工具箱完整使用指南
  • 【限时更新】IntelliJ IDEA 2024.2 Windows安装适配公告:.NET 8.0 Runtime冲突预警+WSL2集成安装包实测对比
  • 从噪音困扰到静音享受:如何用FanControl为Windows电脑定制专属风扇策略
  • MCP协议入门:AI代理服务编排的轻量级通信标准
  • COB和SMD LED显示屏有什么区别?采购时应该怎么选?
  • Nessus 10.11.0专业版实战指南:部署、配置与漏洞扫描深度解析
  • 终极Office激活指南:3分钟解锁Microsoft 365完整功能
  • B站视频转换终极指南:如何用m4s-converter一键保存珍贵内容
  • 告别手写烦恼:如何用text-to-handwriting让数字文本拥有手写灵魂?
  • 终极MPV播放器懒人包:10分钟打造专业级视频播放体验
  • 终极指南:让微信网页版在任何浏览器中完美运行的简单方法
  • 当工具越来越多,Prompt 需要分层管理
  • B站缓存视频拯救指南:m4s-converter让消失的视频重获新生
  • MicroPython对接大模型:uopenai + 火山方舟实现文字聊天和图片理解
  • 开源PLC编程终极指南:如何用OpenPLC Editor零成本掌握工业自动化
  • EasyOCR微调实战:零基础提升垂直场景OCR准确率
  • TIDAL无损音乐下载终极指南:三步安装法让你轻松获取24-bit高解析度音频
  • 从高斯曲率到Morse-Bott理论:能量函数如何刻画曲面形态
  • AI原生工作流方法论:从Prompt操作到系统工程
  • 英雄联盟智能助手:5个功能彻底改变你的游戏体验
  • 【小白向】低配电脑也能流畅跑,虾壳云一键部署 OpenClaw v2.7.9 适配教程(最新安装包)
  • 【学术干货】从「预测器」到「发现工具」:清华UniCM如何让AI真正理解全球气候系统
  • 2026年6月24日漏洞文字版表述一句话版本(漏洞危害以及修复建议),通常用于漏洞通报中简洁干练【持续更新中】,漏洞通报中对于各类漏洞及修复指南,漏洞通报话术,漏洞日常修复建议
  • 系统设计 017: Session 与 Cookie
  • SteamAutoCrack:终极Steam游戏DRM保护绕过解决方案深度解析
  • STL到STEP格式转换:工程级3D数据互操作的技术实现
  • RAG生产就绪实战:LangChain+FastAPI+FAISS高并发部署指南
  • 别天天只知道群发!教你 搭建个人微信增量语料库,低成本喂饱本地大模型
  • 多智能体系统设计实战:从模式选择到通信协议