64位Linux下ROP覆盖返回地址跳转not_called函数问题咨询
段错误根因与正确构造方法
栈偏移计算错误
从vulnerable_function的汇编指令推导栈帧布局:
- 函数入口执行
push %rbp,将旧rbp值压入栈,此时当前rbp指向栈中存储的旧rbp位置,该位置占8字节 - 执行
add $0xffffffffffffff80, %rsp,等价于rsp = rsp - 0x80,为当前函数分配0x80大小的栈空间 - 指令
lea -0x70(%rbp), %rax指定了用户输入缓冲区的起始位置为rbp - 0x70 - 从缓冲区起始位置到函数返回地址的总距离为:
0x70(缓冲区到rbp的距离) + 8(栈上存储的旧rbp长度) = 0x78
原payload使用"A"*0x80做填充,比实际需要的偏移量多了8字节,直接把返回地址位置完全覆盖成'A'对应的ASCII值0x41,生成非法访问地址。
跳转地址构造错误
- gdb查询得到
not_called的实际入口地址为0x720,原payload中拼接的"\x07\x44"对应地址为0x4407,和目标地址完全不符 - 64位Linux下函数返回地址为8字节宽度,原payload仅拼接2字节的地址值,剩余6字节会被前置填充的'BBBBBBBB'的ASCII值0x42填充,最终拼出的完整地址为
0x4242424200004407,不在进程合法内存映射范围内 - 小端序规则要求多字节数值按低位在前、高位在后的顺序存储,64位下
0x720需要补全到8字节宽度,不能仅写低位片段
正确payload构造逻辑
- 用0x78字节的'A'填充缓冲区到旧rbp的全部空间,刚好抵达返回地址的存储位置
- 按小端序拼接
not_called的完整8字节地址:\x20\x07\x00\x00\x00\x00\x00\x00
示例构造代码:
# 生成payload payload = b"A" * 0x78 payload += b"\x20\x07\x00\x00\x00\x00\x00\x00"
执行该payload时,函数执行到retq指令会直接跳转到not_called的入口地址,不会触发段错误。
内容的提问来源于stack exchange,提问作者user2833581
相关产品推荐
相关产品推荐

