为了理解二进制(虚拟内存布局、执行等等),我编写了一个 C 代码,声明了一个包含可执行代码字节的全局字符串,然后通过在 main() 函数中声明一个指针 PTR,它是栈上保留的本地内存区域,距离 main() 函数的返回地址2个 WORDS。因此,我所做的就是将返回地址的地址分配给该指针 (PTR = (int*)&PTR+2),然后覆盖该地址的内容为可执行代码的地址(静态字符串)。
现在的问题是,每当我编译并执行时,都会收到“segmentation fault”的错误消息。
可执行代码不进行任何内存输入/输出操作(只是一堆 NOPs)。
使用 GDB 确认过程完美无误:返回地址已更改为字符串的地址,但返回从未发生。
我知道可执行代码被映射到虚拟内存中标记为 RW 的页面上(.data 和 .bss 段),因此可能没有办法执行这样的代码,除非将代码注入到可执行的内存区域(标记为 RE 的页面)中。这是我对这个问题的理论,欢迎您提供更多详细信息。
现在的问题是,每当我编译并执行时,都会收到“segmentation fault”的错误消息。
可执行代码不进行任何内存输入/输出操作(只是一堆 NOPs)。
使用 GDB 确认过程完美无误:返回地址已更改为字符串的地址,但返回从未发生。
我知道可执行代码被映射到虚拟内存中标记为 RW 的页面上(.data 和 .bss 段),因此可能没有办法执行这样的代码,除非将代码注入到可执行的内存区域(标记为 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
}