首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何调用存储在char数组中的机器码?

如何调用存储在char数组中的机器码?
EN

Stack Overflow用户
提问于 2016-10-05 15:02:18
回答 6查看 14.6K关注 0票数 59

我正在尝试调用本机语言代码。下面是我到目前为止所得到的(它得到一个总线错误):

代码语言:javascript
复制
char prog[] = {'\xc3'}; // x86 ret instruction

int main()
{
    typedef double (*dfunc)();

    dfunc d = (dfunc)(&prog[0]);
    (*d)();
    return 0;
}

它确实正确地调用了函数,并到达ret指令。但是当它尝试执行ret指令时,它会出现SIGBUS错误。是不是因为我在一个页面上执行代码,而这个页面并没有被清除,或者类似的东西?

那么我到底做错了什么呢?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-10-05 15:16:26

第一个问题可能是存储prog数据的位置是不可执行的。

至少在Linux上,生成的二进制文件会将全局变量的内容放在"data" segmenthere中,这在most normal cases中是无法执行的。

第二个问题可能是您正在调用的代码在某种程度上是无效的。在C中有一个调用方法的特定过程,称为calling convention (例如,您可能正在使用"cdecl“方法)。对于被调用的函数来说,仅仅"ret“可能是不够的。它可能还需要做一些堆栈清理等工作,否则程序会意外地运行。一旦你解决了第一个问题,这可能会成为一个问题。

票数 53
EN

Stack Overflow用户

发布于 2016-10-05 16:01:55

为了使prog所在的页面成为可执行的页面,您需要调用memprotect。下面的代码进行了这个调用,并且可以执行prog中的文本。

代码语言:javascript
复制
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

char prog[] = {
   0x55,             // push   %rbp
   0x48, 0x89, 0xe5, // mov    %rsp,%rbp
   0xf2, 0x0f, 0x10, 0x05, 0x00, 0x00, 0x00,
       //movsd  0x0(%rip),%xmm0        # c <x+0xc>
   0x00,
   0x5d,             // pop    %rbp
   0xc3,             // retq
};

int main()
{
    long pagesize = sysconf(_SC_PAGE_SIZE);
    long page_no = (long)prog/pagesize;
    int res = mprotect((void*)(page_no*pagesize), (long)page_no+sizeof(prog), PROT_EXEC|PROT_READ|PROT_WRITE);
    if(res)
    {
        fprintf(stderr, "mprotect error:%d\n", res);
        return 1;
    }
    typedef double (*dfunc)(void);

    dfunc d = (dfunc)(&prog[0]);
    double x = (*d)();
    printf("x=%f\n", x);
    fflush(stdout);
    return 0;
}
票数 52
EN

Stack Overflow用户

发布于 2016-10-05 18:57:55

正如每个人已经说过的,你必须确保prog[]是可执行的,但是正确的方法是将符号放在可执行区域中,或者使用链接器脚本,或者在编译器允许的情况下指定C代码中的节,例如:

代码语言:javascript
复制
const char prog[] __attribute__((section(".text"))) = {...}
票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39867396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档