为什么执行shellcode时需要使用栈中的精确返回地址?
错误触发的核心原因
你构造的 payload 结构为 NOP sled + 有效shellcode + 覆盖返回地址,合法返回地址只能落在0xffffd521-0xffffd539区间的原因完全和栈上的 payload 分布对应:
1. 低于区间下限的地址(如0xffffd520)触发SIGILL的原因
0xffffd520及更低的地址并不属于你的 NOP sled 或有效shellcode范围:
- 这个位置要么存储的是你覆盖写入的返回地址本身的字节,要么是旧栈帧的EBP元数据,根本不是合法的CPU指令序列
- 当
ret指令把你填入的地址弹到EIP寄存器后,CPU会尝试解码该地址指向的字节,无法识别为合法指令时就会抛出非法指令错误。
2. 高于区间上限的地址触发SIGSEGV的原因
0xffffd539以上的地址已经超出了你 payload 中 NOP + 有效shellcode的总长度:
- 这些位置要么是栈上的随机垃圾数据,要么已经落在当前进程栈的不可访问/不可执行页边界
- CPU尝试访问没有读/执行权限的内存地址时,就会直接触发段错误。
补充说明
你当前的有效地址区间就是 NOP sled 的起始到有效shellcode的末尾,只要返回地址落在这个区间里,CPU就会先执行NOP空指令下滑到真实shellcode完成执行。另外注意gdb调试环境下的栈地址和直接宿主机运行的栈地址会有几字节到几十字节的偏移(gdb会额外注入调试相关的环境变量),脱离gdb运行时可能需要微调返回地址的偏移值。
内容的提问来源于stack exchange,提问作者AkechiShiro
相关产品推荐
相关产品推荐

