栈溢出已改写返回地址到NOP但shellcode未执行问题排查
问题排查结果
核心错误点
- 64位地址被截断
你当前运行在64位环境下,内存地址是8字节长度的unsigned long类型,但你代码里用4字节的unsigned int存储返回地址ret,直接丢弃了地址高32位。从你提供的gdb日志可以看到栈地址是0x7fffffffde44这类64位地址,用4字节变量存储后只会保留低32位的0xffffde44,程序实际跳转的地址是非法地址,自然到不了NOP区域。 - 返回地址计算逻辑错误
你用exploit进程内部局部变量mem_i的地址加偏移作为返回地址,但execl启动的command是完全独立的进程,两个进程的地址空间相互隔离,exploit的栈地址和command的栈地址没有任何关联,你算出来的ret值本质上是无效的。 - 返回地址填充粒度错误
64位环境下栈的返回地址占8字节,你代码里循环填充返回地址时每次只写4字节、偏移加4,导致返回地址覆盖不完整,同样会触发跳转异常。
修复方案
- 将代码中所有存储地址的变量类型从
unsigned int替换为unsigned long,填充返回地址的循环步长从4改为8。 - 不要通过exploit的变量地址计算偏移,直接在gdb中调试
command程序,拿到somefunc内buffer的栈地址,加上合适的偏移作为ret的值;也可以用gdb的pwntools插件等工具的pattern create/pattern offset功能精准计算覆盖返回地址需要的偏移量。 - 测试前先关闭系统ASLR(地址空间随机化),避免每次运行栈地址随机变化:执行命令
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space即可临时关闭。 - 编译漏洞程序时明确添加
-m64参数生成64位程序,确保和你用的64位shellcode架构匹配。
内容的提问来源于stack exchange,提问作者Rainbow
相关产品推荐
相关产品推荐

