加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 10:03:30 所属栏目:百科 来源:网络整理
导读:我知道我可以通过引用复制该函数,但我想了解以下代码中发生的段错误. #include stdio.h#include stdlib.h#include string.hint return0(){ return 0;}int main(){ int (*r0c)(void) = malloc(100); memcpy(r0c,return0,100); printf("Address of r0c is: %x
我知道我可以通过引用复制该函数,但我想了解以下代码中发生的段错误.

#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: %xn",r0c);
    printf("copied is: %dn",(*r0c)());
    return 0;
}

这是我认为应该起作用的心理模型.

该进程拥有分配给r0c的内存.我们正在复制与return0对应的数据段中的数据,并且复制成功.

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

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

解决方法

malloc用于分配内存的内存页面未标记为可执行文件.您无法将代码复制到堆中并期望它运行.

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

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

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

当你声明一个类似int fun()的函数时,它与声明一个不带参数的函数不同.如果要声明一个不带参数的函数,则应该在int fun(void)中明确使用void.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读