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

编写的x86汇编Shell生成函数无执行效果,求技术指引

帮你搞定x86汇编生成Shell的问题

嘿,我来帮你梳理下这个x86汇编生成shell的问题~你的代码里有几个关键问题导致它没起作用,咱们一个个拆解:

核心错误点

  • 系统调用号搞错了:你最后写的mov $1,%eax是exit系统调用的编号(十进制1),但你需要调用的是execve(用来启动新进程的系统调用),它在32位Linux下的编号是0xb(十进制11),而且必须在触发int 0x80前把这个值放到eax里。
  • /bin/sh的构造方式不对:你用add %ebx,%edi的方式没法正确拼接出/bin/sh的字符串地址。x86是小端字节序,正确的做法是把字符串按字节逆序压栈,然后用栈顶地址作为文件名指针。
  • 缺少execve的必要参数:execve需要三个参数,对应到系统调用的寄存器分配是:
    • ebx:指向/bin/sh字符串的指针
    • ecx:指向参数数组的指针(数组第一个元素是/bin/sh的指针,末尾要跟NULL)
    • edx:指向环境变量数组的指针(一般传NULL即可)
  • 程序入口不完整:你声明了.global main但没实现main函数,而且代码写到mov $0,%e...就中断了,没法完成完整的调用流程。

修正后的完整代码

.global main
.text
main:
    call create_shell  # 让程序入口main调用我们的shell生成函数

create_shell:
    push %ebp
    movl %esp, %ebp

    # 构造/bin/sh字符串并压栈(小端序,逆序存储为两个4字节值)
    pushl $0x0068732f  # 对应字节: 0x2f('/'), 0x73('s'), 0x68('h'), 0x00(空终止符)
    pushl $0x6e69622f  # 对应字节: 0x2f('/'), 0x62('b'), 0x69('i'), 0x6e('n')
    movl %esp, %ebx    # 将栈顶地址赋值给ebx,也就是/bin/sh的指针

    # 构造argv数组:[&/bin/sh, NULL]
    pushl $0x0         # 压入NULL作为数组结束标记
    pushl %ebx         # 压入/bin/sh的指针
    movl %esp, %ecx    # 将栈顶地址赋值给ecx,也就是argv数组的指针

    # 设置envp为NULL
    xorl %edx, %edx    # 用异或快速将edx置0

    # 设置execve的系统调用号
    movl $0xb, %eax    # eax = 11,对应execve的系统调用编号
    int $0x80          # 触发Linux系统调用

    # 容错逻辑:如果execve失败,执行exit(0)
    movl $1, %eax      # exit的系统调用编号
    xorl %ebx, %ebx    # exit码设为0
    int $0x80

代码解释

  1. 程序入口:实现main函数并调用create_shell,确保程序启动后能执行我们的逻辑。
  2. 构造/bin/sh:把字符串拆成两个4字节的逆序值压栈,栈顶就是字符串的起始地址,刚好符合execve对文件名参数的要求。
  3. 参数数组构造:按execve的要求,先压入NULL,再压入/bin/sh的指针,栈顶就是参数数组的首地址。
  4. 系统调用触发:把正确的调用号放到eax,触发int 0x80,系统就会启动/bin/sh进程。
  5. 容错处理:如果execve调用失败(比如权限问题),会执行exit(0)让程序正常退出。

编译运行提示

用32位gcc编译:

gcc -m32 -o shell_program shell.s

运行生成的程序就能看到shell了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:31