You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言读取内存中函数十六进制反汇编与预期不符,问题出在哪?

问题原因分析
  • 你读取到的前9个字节是C编译器自动生成的函数栈帧初始化代码(函数序言),不属于你手写的内联汇编部分:
    你输出的55 48 89 E5 89 7D FC 8B 55对应64位x86架构下的标准函数序言:
    push rbp
    mov rbp, rsp
    mov DWORD PTR [rbp-0x4], edi ; 存储输入参数a到栈上
    mov edx, DWORD PTR [rbp-0x4]
    
    这部分是C函数默认会生成的前置逻辑,你直接从Operation函数的起始地址拷贝机器码,自然会把这部分内容也包含进去。
  • 内联汇编的约束使用导致生成指令不固定:你给输入输出参数用了r约束,编译器会根据优化等级、寄存器占用情况自由选择绑定的寄存器,你手写的汇编指令实际生成的机器码会随编译参数变化,不一定和你预期的固定指令完全匹配。
  • 反汇编时架构匹配问题:如果你是在64位环境下编译的程序,反汇编时误选32位x86架构解析,也会得到完全不符合预期的结果。
  • 共享内存权限配置存在隐患:你代码中将shm_perm.uid赋值为getpid()是错误的,uid是用户ID,getpid()返回的是进程ID,只是因为你当前进程的运行用户恰好是共享内存的所有者,才没有触发权限错误。
修复方案
  • 如果要获取纯手写汇编的机器码,给Operation函数添加__attribute__((naked))修饰符,编译器不会自动生成函数序言、栈帧处理、返回指令等额外代码,函数内的所有逻辑完全由你自己用汇编实现,示例:
    __attribute__((naked)) int Operation(int a)
    {
        __asm__(
            ".intel_syntax;"
            "mov eax, edi;" // 64位下第一个参数直接从rdi取,不需要用约束
            "add eax, 1;"
            "add eax, 1;"
            "ret;" // 自己加返回指令
            ".att_syntax;"
        );
    }
    
  • 拷贝机器码前先通过objdump确认原函数的实际机器码:执行objdump -M intel -d 你的可执行文件,找到Operation函数的实际汇编和对应机器码,确认符合预期后再进行拷贝操作。
  • 反汇编共享内存的机器码时,选择和编译目标一致的架构,64位程序就用x86_64架构解析。

内容的提问来源于stack exchange,提问作者soon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:06:03