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

main函数中Shellcode执行触发Segmentation Fault问题求助

段错误原因分析与修复方案

问题根源

从你提供的GDB反汇编和调试信息来看,核心问题有两个:

  1. 无效指令触发崩溃:syscall(main+12)执行完成后,程序会跳到main+14的无效指令(标注为(bad)),CPU无法识别该指令,直接触发段错误。
  2. 执行流未正确收尾:你的shellcode只包含了write系统调用,没有后续的退出逻辑,导致程序执行到shellcode以外的垃圾指令区域。

你提到仅用nop指令也会崩溃,本质是相同的:执行流没有正确终止,最终跑到了无效指令区域。

修复步骤

1. 完善shellcode的执行逻辑

给shellcode添加退出系统调用,避免执行无效指令。以你当前的write调用为例,修改后的shellcode流程如下:

; 跳转至call指令
jmp short call_target  
pop_rsi:
    push 0x1            ; 设置rax=1(write系统调用号)
    pop rax
    mov rdi, rax        ; rdi=1(标准输出)
    pop rsi             ; rsi=call压入的返回地址(指向后续字符串)
    push 0xc
    pop rdx             ; rdx=12(写入长度)
    syscall

    ; 新增退出逻辑
    push 0x3c           ; rax=60(exit系统调用号)
    pop rax
    xor rdi, rdi        ; rdi=0(退出码)
    syscall

call_target:
    call pop_rsi        ; 将后续字符串地址压入栈
db 'Hello, World!'      ; 要输出的字符串

2. 编译时关闭安全限制

默认GCC的安全机制会干扰shellcode执行,编译时添加以下参数:

gcc -g3 -z execstack -fno-stack-protector -no-pie -o shellcode shellcode.c

参数说明:

  • -z execstack:允许栈区域可执行(如果shellcode放在栈上)
  • -fno-stack-protector:关闭栈保护机制
  • -no-pie:关闭位置无关代码,固定程序内存地址,方便调试

3. 正确的shellcode嵌入方式

如果用C语言嵌入shellcode,推荐用字符数组配合函数指针的写法,示例如下:

#include <stdio.h>

// 修改后的shellcode(含退出逻辑)
unsigned char shellcode[] = \
"\xeb\x2a\x50\x58\x48\x89\xc7\x5e\x6a\x0c\x5a\x0f\x05\x6a\x3c\x58\x48\x31\xff\x0f\x05\xe8\xd1\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

int main() {
    // 将shellcode地址转为函数指针
    void (*run_shellcode)() = (void(*)())shellcode;
    // 执行shellcode
    run_shellcode();
    return 0;
}

调试验证

编译完成后,用GDB逐步调试确认流程:

gdb ./shellcode
b *main
r
ni  # 单步执行,观察寄存器和指令执行情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:32:10