当前位置:  开发笔记 > 运维 > 正文

Linux:执行手动加载到内存的代码

如何解决《Linux:执行手动加载到内存的代码》经验,为你挑选了1个好方法。

我正在使用Linux上的函数指针并尝试执行此C程序:

#include 
#include 

int myfun() 
{
    return 42;
}

int main()
{
    char data[500];
    memcpy(data, myfun, sizeof(data));
    int (*fun_pointer)() = (void*)data;
    printf("%d\n", fun_pointer());

    return 0;
}

不幸的是它会fun_pointer()随叫随到.我怀疑它与一些内存标志有关,但我没有找到有关它的信息.

你能解释为什么这段代码会出现错误吗?没有看到固定的data数组大小,没有调用函数的复制是正常的.

UPD:最后我发现应该使用带有flag的mprotect系统调用将内存段标记为可执行文件PROT_EXEC.此外,内存段应由mmap函数返回,如POSIX规范中所述.有一个相同的代码使用mmap内存分配PROT_EXEC标志(和工作):

#include 
#include 
#include 

int myfun() 
{
    return 42;
}

int main()
{
    size_t size = (char*)main - (char*)myfun;
    char *data = mmap(NULL, size, PROT_EXEC | PROT_READ | PROT_WRITE,
        MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    memcpy(data, myfun, size);

    int (*fun_pointer)() = (void*)data;
    printf("%d\n", fun_pointer());

    munmap(data, size);
    return 0;
}

此示例应符合-fPICgcc选项,以确保函数中的代码与位置无关.



1> dlask..:

那里有几个问题:

您的data数组保留在数据段中,而不是代码段中.

该地址搬迁没有被处理.

只是猜测,代码大小是未知的.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有