gpt4 book ai didi

c - 带有函数指针的 Memcpy 会导致段错误

转载 作者:太空狗 更新时间:2023-10-29 16:01:03 24 4
gpt4 key购买 nike

我知道我可以通过引用复制该函数,但我想了解以下产生段错误的代码中发生了什么。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int return0()
{
return 0;
}

int main()
{
int (*r0c)(void) = malloc(100);
memcpy(r0c, return0, 100);
printf("Address of r0c is: %x\n", r0c);
printf("copied is: %d\n", (*r0c)());
return 0;
}

这是我认为应该起作用的心智模型。

进程拥有分配给 r0c 的内存。我们正在从return0对应的数据段复制数据,复制成功。

我认为解引用函数指针与调用函数指针指向的数据段是一样的。如果是这样,那么指令指针应该移动到对应于 r0c 的数据段,其中将包含函数 return0 的指令。 return0对应的二进制代码不包含任何依赖于return0地址的跳转或函数调用,所以它应该只是返回0并恢复ip......函数指针100个字节当然足够了,0xc3很好在 r0c 的范围内(在字节 11 处)。

那么为什么会出现段错误呢?这是对 C 函数指针语义的误解,还是存在一些我不知道的阻止自修改代码的安全功能?

最佳答案

malloc 用于分配内存的内存页未标记为可执行。您不能将代码复制到堆中并期望它运行。

如果你想做这样的事情,你必须深入操作系统,并自己分配页面。然后你需要将它们标记为可执行文件。您很可能需要管理员权限才能在内存页上设置可执行标志。

这真的很危险。如果您在分发的程序中执行此操作并且存在某种错误,攻击者可以使用我们的程序写入那些分配的内存页面,那么攻击者可以获得管理员权限并控制计算机。


您的代码还存在其他问题,例如指向函数的指针可能无法很好地转换为所有平台上的通用指针。预测或以其他方式获取函数的大小非常困难(更不用说非标准的了)。您还在代码示例中打印出错误的指针。 (使用"%p" 格式打印void *,需要将指针转换为void *)。

此外,当您声明一个像 int fun() 这样的函数时,这与声明一个不带参数的函数不同。如果您想声明一个不带参数的函数,您应该显式使用 void,如 int fun(void)

关于c - 带有函数指针的 Memcpy 会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38445862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com