main函数中Shellcode执行触发Segmentation Fault问题求助
段错误原因分析与修复方案
问题根源
从你提供的GDB反汇编和调试信息来看,核心问题有两个:
- 无效指令触发崩溃:
syscall(main+12)执行完成后,程序会跳到main+14的无效指令(标注为(bad)),CPU无法识别该指令,直接触发段错误。 - 执行流未正确收尾:你的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
相关产品推荐
相关产品推荐

