【发布时间】:2016-11-01 23:38:38
【问题描述】:
在理解二进制文件(虚拟内存布局、执行...等)的过程中,我编写了一个C 代码,该代码声明了一个包含可执行代码字节的全局字符串,然后我覆盖了从通过在main() 中声明一个指针(PTR),将main() 函数指向该可执行代码,这是一个在堆栈上保留的本地内存区域,距离main() 的返回地址2 个字远,所以我所做的就是将返回地址的地址分配给该指针(PTR=(int*)&PTR+2),然后用可执行代码的地址(静态字符串)覆盖该地址的内容。
现在的困境是也就是说,每当我编译和执行时,我都会收到 分段错误。
可执行代码没有内存input/output(它只是一堆NOPs)。
使用 GDB,我确保该过程完美运行:返回地址更改为字符串的地址,但返回永远不会发生。
我所知道的是可执行代码已映射到虚拟内存中的页面标记为RW(.data 和.bss 段),因此除非将代码注入到内存的executable 区域(标记为@987654335 的页面),否则可能无法执行这样的代码执行@)。这就是我对这个主题的理论,我邀请你提供更多细节。
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
}
【问题讨论】:
-
您可能想调用 mprotect sycall 并添加 PROT_EXEC 标志...在许多架构(x86 也是)上的数据页上没有 x 权限,通过阅读 /proc/$ 检查 linux 中的内存映射应用程序运行时的 PID/maps 文件(在 gdb 中停止),其中 $PID 是目标进程的 pid。您将看到加载了 rw- 权限的 data/bss 段。
-
@osgx 这和我猜的一模一样,旧的 linux 内核(比如 2007 年之前)是否允许这种执行?
-
你呢?您可以检查旧内核上的映射文件。有关于技术的 wiki 页面:en.wikipedia.org/wiki/Executable_space_protection 和“NX 位”/“XD 位”技术可能需要在 CPU 和内核中......将“可执行”位添加到硬件的页面级翻译(操作系统可能有 3 位 rwx权限;但硬件没有 x 位)。 PAE 也应该在 32 位 x86 模式下打开。 (详细信息在这里en.wikipedia.org/wiki/NX_bit)
-
afr0ck,你真正的问题是什么?您需要更详细的链接吗?
-
Linux kernels > 2.3 支持带有 XD 位的完整 PAE,所以我真的需要一个非常旧的 Linux 内核来进行这样的尝试。顺便说一句,感谢您的帮助。 @osgx
标签: c memory segmentation-fault elf shellcode