C语言调用汇编命令实现

C语言调用机器码令实现
  1. 编写被调用C代码

    #include <stdio.h>
    int add(int a,int b){
        return a+b;
    }
    
  2. 编译,注意添加*-c*参数,不然会因为没有main函数报错

    gcc -c add.c
    
  3. 获得编译后文件的机器码

    objdump -j .text -d add.o
    

    执行命令结果如下:

    
    add.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <add>:
       0:	55                   	push   %rbp
       1:	48 89 e5             	mov    %rsp,%rbp
       4:	89 7d fc             	mov    %edi,-0x4(%rbp)
       7:	89 75 f8             	mov    %esi,-0x8(%rbp)
       a:	8b 55 fc             	mov    -0x4(%rbp),%edx
       d:	8b 45 f8             	mov    -0x8(%rbp),%eax
      10:	01 d0                	add    %edx,%eax
      12:	5d                   	pop    %rbp
      13:	c3                   	retq   
    
    

    其中左侧从0x55到0xc3这些16进制的数即是add方法对应的机器码

  4. 编写C程序调用得到的机器码

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    
    // 定义数组存储机器码,也可以使用int类型
    // \x表示后面的字符是十六进制数
    const unsigned char code[]="\x55\x48\x89\xe5\x89\x7d\xfc\x89\x75\xf8\x8b\x55\xfc\x8b\x45\xf8\x01\xd0\x5d\xc3";
    
    int main(int argc,char* argv[]){
        /**
        这里和《揭秘Java虚拟虚拟机》一书中所写存在差异,按照书中的写法调用C语言会报段错误
        经过一番查找原因是机器码必须存在可执行内存页
        */
         void *buf;
        // mman.h头文件为Linux下内存管理函数库
        // mmap用来开辟新的内存空间,第二个参数分别表示可读|可写|可执行
        buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
                    MAP_PRIVATE|MAP_ANON,-1,0);
        // 内存拷贝,将code数组中内容拷贝到前面开辟的存存储空间中
        memcpy (buf, code, sizeof(code));
        // 标记内存区域为已读(具体用处不明,不敢乱说,貌似是个gcc内置函数)
        __builtin___clear_cache(buf, buf+sizeof(code)-1);
    
        // 定义函数指针
        int (*fun)(int,int);
        // 指向机器码内存空间
        fun=(void*)buf;
        // 调用方式
        int result=fun(8,1);
        printf("invoked result:%d\n",result);
    }
    
    

    上述调用过程基于Linux 5.10.6-arch1-1,不同的平台必定不兼容,不同的系统版本可能不兼容。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值