这段execve系统调用shellcode中栈指针rsp的作用是什么
global _start section .text _start: xor rsi,rsi push rsi mov rdi,0x68732f2f6e69622f push rdi push rsp pop rdi push 59 pop rax cdq syscall
代码执行逻辑梳理
这段shellcode执行到push rsp前,栈上已经完成了路径字符串的构造,步骤如下:
xor rsi,rsi把rsi寄存器清零后执行push rsi,相当于在栈上压入了一个\0字符,作为后续路径字符串的结束符。mov rdi,0x68732f2f6e69622f写入的立即数按小端序解码后就是字符串/bin//sh(双斜杠不影响Linux路径解析),执行push rdi后,这8个字符就被压到了栈上,刚好和之前压入的\0拼接成完整的合法C字符串/bin//sh\0。- 此时
rsp寄存器存储的栈顶指针,刚好指向这个/bin//sh字符串的起始地址。
push rsp + pop rdi的作用
这两行指令的作用完全等价于mov rdi, rsp,就是把栈顶指针(也就是/bin//sh字符串的首地址)赋值给rdi寄存器,刚好匹配execve系统调用第一个参数要传入可执行文件路径指针的要求。
之所以不直接写mov rdi, rsp,是shellcode的特殊编写要求决定的:
push rsp+pop rdi的机器码只有2字节,比mov rdi, rsp的3字节更短,适合漏洞利用场景下对shellcode长度的严格限制- 这种写法不会引入NULL字节,避免漏洞利用时被字符串截断逻辑打断执行。
为什么其他shellcode没有类似操作
很多同类shellcode会直接用mov rdi, rsp实现同样的赋值效果,只是写法不同,底层逻辑完全一致。你看到的没有rsp操作的shellcode,大概率是通过其他方式把路径地址赋值给了rdi,比如直接把路径存在其他寄存器后直接转移给rdi,本质上没有区别。
内容的提问来源于stack exchange,提问作者user2370139
相关产品推荐
相关产品推荐

