C语言中,通过函数指针直接执行一段二进制代码

1、看《揭秘java虚拟机》,其中提到C中用函数指针直接执行二进制代码,如下:

#include <stdio.h>
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
    0x89,0x75,0xf0,0xb8,0x5a,0x00,0x00,0x00,0xc9,0xc3,0x00};
int main(){
    int (*fun)();
    fun = (void*)code;
    int i = fun();
    printf("get this done. returned: %d \n", i);

    return 0;
}

编译后报错segmentation fault, google到答案大概是说这段二进制会保存在程序的数据段,没有可执行权限,然后编译的时候加上选项gcc -z execstack,可以解决.

2、不过还有另外一个思路,(Another way to do it without making everything executable is to copy this binary machine code into an executable buffer.)就是把这段二进制代码放到可执行buffer里,如下,不加参数编译后可以正常执行。

#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stdio.h>

char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
    0x89,0x75,0xf0,0xb8,0x5a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/*
00000000004004b4 <main> 55                          push   %rbp
00000000004004b5 <main+0x1>  48 89 e5               mov    %rsp,%rbp
00000000004004b8 <main+0x4>  89 7d fc               mov    %edi,-0x4(%rbp)
00000000004004bb <main+0x7>  48 89 75 f0            mov    %rsi,-0x10(%rbp)
-----------  00000000004004bf <main+0xb>  b8 5a 00 00 00         mov    $0x2a,%eax   'return 90;' 
00000000004004c4 <main+0x10> c9                     leaveq 
00000000004004c5 <main+0x11> c3                     retq 
*/
int main()
{

    void *buf;

    /* copy code to executable buffer */    
    buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
                MAP_PRIVATE|MAP_ANON,-1,0);
    memcpy (buf, code, sizeof(code));
    __builtin___clear_cache(buf, buf+sizeof(code)-1);  // on x86 this just stops memcpy from optimizing away as a dead store

    /* run code */
    int (*fun)();
    fun = (void*)buf;
    int i = fun();
    printf("get this done. returned: %d \n", i);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值