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

为何以下汇编指令序列会触发SIGILL信号?

拆解这段Shellcode的执行逻辑

你贴的这段GDB反汇编代码是一段很典型的x86_64 Linux Shellcode,核心是构造出执行/bin/sh的环境。而且你提到0x7fffffffdbe4地址之前的指令都是有效指令,程序在该地址已经调用了exit系统调用收尾,那我们就来一步步拆解这段核心指令的作用:

首先是GDB的反汇编输出:

gdb) x/20i $rip 
=> 0x7fffffffdbb0: movabs rax,0x2168732f6e69622f 
0x7fffffffdbba: push rax 
0x7fffffffdbbb: lea rdi,[rsp] 
0x7fffffffdbbf: xor rax,rax 
0x7fffffffdbc2: mov BYTE PTR [rdi+0x7],al 
0x7fffffffdbc5: mov QWORD PTR [rdi+0x8],rdi 
0x7fffffffdbc9: mov BYTE PTR [rdi+0x10],al 
0x7fffffffdbcc: mov rsi,QWORD PTR [rdi+0x8] 
0x7fffffffdbd0: push rax 
0x7fffffffdbd1: push rdi 

接下来逐个指令解析:

  • movabs rax,0x2168732f6e69622f:把十六进制值0x2168732f6e69622f塞进rax寄存器,转成ASCII看是/bin/sh!(因为x86_64是小端序,实际存储是反向的!hs/nib/,push到栈里就会变回正常的/bin/sh!顺序)
  • push rax:把rax里的8字节内容压栈,此时栈顶就是/bin/sh!这个字符串的起始位置
  • lea rdi,[rsp]:把栈顶地址加载到rdi寄存器——rdi是execve系统调用的第一个参数,也就是要执行的程序路径
  • xor rax,rax:这是个高效的清零操作,把rax整个置0,这样rax的低8位al也是0,刚好可以当字符串的结束符
  • mov BYTE PTR [rdi+0x7],al:把0写到rdi+0x7的位置,把/bin/sh!最后那个!替换成0,得到标准C风格的字符串/bin/sh
  • mov QWORD PTR [rdi+0x8],rdi:把rdi(也就是/bin/sh的地址)写到rdi+0x8的位置,这里在构造execve的第二个参数——argv数组,argv[0]就是程序路径,后续要补NULL终止符
  • mov BYTE PTR [rdi+0x10],al:把0写到rdi+0x10的位置,给argv数组加上NULL终止符,让数组合法
  • mov rsi,QWORD PTR [rdi+0x8]:把刚才构造好的argv数组地址加载到rsi寄存器,作为execve的第二个参数
  • push rax:把rax里的0压栈,为构造execve的第三个参数envp数组做准备(直接传NULL即可)
  • push rdi:把/bin/sh的地址压栈,后续应该会把rsp作为envp参数,再设置rax为59(execve的系统调用号),触发syscall执行shell,最后到0x7fffffffdbe4调用exit系统调用结束程序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:48:18