我可以执行驻留在数据段(ELF 二进制)中的代码吗?

2024-04-06

在理解二进制文件(虚拟内存布局、执行...等)的方式中,我写了一个C声明一个全局字符串的代码,其中包含可执行代码的字节,然后我覆盖了返回地址main()通过声明一个指针(PTR) in main()这是保留在堆栈上的本地内存区域,距离返回地址较远 2 个字main(),所以我所做的就是将返回地址的地址分配给该指针(PTR=(int*)&PTR+2)然后用可执行代码的地址(静态字符串)覆盖该地址的内容。

现在的困境是,每当我编译并执行时,我都会收到一个分段故障。 可执行代码不占用内存input/output(它只是一堆NOPs).

使用 GDB,我确保该过程完美运行:返回地址更改为字符串的地址,但返回从未发生。

我所知道的是可执行代码被映射到虚拟内存中标记的页面RW (.data & .bss段)所以也许没有办法执行这样的代码,除非代码被注入到executable内存区域(标记的页面RE)。这就是我关于这个主题的理论,我邀请您提供更多细节。

char code[]="\x90\x90\x90\x90\x90\x90\x90\x90"; //a static string contains executable code

int main()
{
int *return_address; //Pointer to the return address - uninitialized
return_address = (int *)&return_address + 2; //Initializing the return address - according to stack layout
(*return_address) = (int)code; //Overwriting the return address with the code's address
}

我收到分段错误。

它是数据执行预防的硬件控制(https://en.wikipedia.org/wiki/Executable_space_protection#Linux https://en.wikipedia.org/wiki/Executable_space_protection#Linux) - 如果页表中没有设置“x”(执行)位,则不能直接跳转到数据页。所有位的内存映射都列在/proc/$pid/maps / /proc/$pid/smaps文件为“rwx”表示可写代码,“rw-”表示不执行的数据,“r--”表示只读数据,“r-x”表示普通代码。

如果你想执行数据,你应该调用mprotect系统调用与PROT_EXEC标记想要成为代码的数据部分。

在 x86 世界中,这完全实现为“NX位”/“XD位”功能 https://en.wikipedia.org/wiki/NX_bitPentium 4 (Prescott) 及更新版本(Core、Core2、Core i*、core m)/Athlon 64 / Opteron 及更新版本。如果操作系统工作在32位模式,则必须打开PAE才能在页表中包含该位。在 x86_64 模式(64 位)中,始终支持 NX/XD 位。

第一个支持变体在 2004 年左右被添加到 Linux 中:http://linuxgazette.net/107/pramode.html http://linuxgazette.net/107/pramode.html

在 2007 年,您可能拥有过时的硬件、旧的内核或没有 PAE 的 32 位模式内核。

有关 NX/XD 钻头的信息:https://en.wikipedia.org/wiki/NX_bit https://en.wikipedia.org/wiki/NX_bit

有时'rwx'模式可能被禁止,检查https://en.wikipedia.org/wiki/W^X https://en.wikipedia.org/wiki/W%5EX.

对于 NX 之前的系统,有基于 x86 段寄存器的解决方案来部分禁用部分内存空间的执行。

我可以在没有分段错误的情况下执行上面的程序吗?

你可以:

  • 通过调用使数据页可执行mprotect其上与PROT_READ|PROT_EXEC
  • 将elf文件的数据段标记为可执行文件(需要深入内部ld脚本 - 默认位于ld --verbose)
  • 使所有页面包括.data和堆可执行文件(不仅仅是堆栈)
    与 ld 或 gcc-z execstack
  • 将 shellcode 移动到 elf 文件的文本数据中
  • 尝试禁用内核中的 nx/xd 位(困难;可能需要重新编译)
  • 使用未启用 PAE 选项(构建时间选项)的 32 位操作系统(内核)。
  • 使用没有 NX/XD 的旧 CPU
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以执行驻留在数据段(ELF 二进制)中的代码吗? 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲

随机推荐