assembly - 这个 shellcode 中使用的堆栈指针是什么?
问题描述
https://www.exploit-db.com/exploits/46907
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
一条指令是push %rsp
,然后将其弹出rdi
。我很困惑。根据文档,rdi
系统execve
调用中应该包含可执行文件的路径名。和这里有什么关系rsp
?其他 shellcode 不会操纵rsp
.
解决方案
在堆栈上构造数据,然后将堆栈指针复制到另一个 reg,是完全正常的。许多 shellcode 操纵 RSP。
push rsp
/pop rdi
只是 2 字节的版本mov rdi, rsp
,它是在推送 0 和 8 字节的 ASCII 数据之后出现的。(在 NASM 语法中可以更清楚地写为mov rdi, '/bin//sh'
)。
使用调试器单步执行 asm,并在执行时查看 RDI 指向的内存syscall
,然后向后工作以了解您是如何到达那里的。
奇怪的是,他们mov rdi,rsp
使用 push/pop 将其缩小到 2 个字节,但在 xor-zeroing 指令上使用了 REX 前缀。 xor esi,esi
是等价的。NASM 会将该源优化为xor esi,esi
.,但您的链接显示了反汇编。
此外,push 59
/pop rax
是在寄存器中构造小常量( ) 的标准 3 字节方式,__NR_execve
而不依赖于任何其他寄存器值。他们本可以做到lea eax, [rsi+59]
这也是 3 个字节,也可以避免任何0
字节。(5 字节mov eax, 59
将包括一个带有三个零字节的 imm32,这就是为什么大多数 shellcode 必须避免它。)
cdq
只需设置 RDX=0 ( envp=NULL
),因为此时 EAX 为正数。另一种节省字节与xor edx,edx
. 在这种情况下,他们显然知道在编写 32 位 reg (EDX) 时要利用完整 64 位 reg 的隐式归零,所以更奇怪的是,他们对 RSI 使用了 64 位异或归零。也许他们对 x86-64 了解不多,甚至没有意识到它cqo
会显式使用 64 位操作数大小,将 RAX 符号扩展为 RDX:RAX,并打算在任何地方都使用 64 位,因为他们认为需要。
推荐阅读
- python - 为什么绘图函数 plt.show() 在循环内部或外部表现不同?
- python - Python 请求库 - 从 POST 请求中抓取单独的 JSON 和 HTML 响应
- javascript - 如何在 For/In 循环中解析 Int,然后添加一个类来更改 CSS 中的字体颜色?
- c - 奇怪的内存问题,for 循环初始化不正确并修改堆内存
- sas - SAS PROC TRANSPOSE(“从宽到长”)
- powershell - PowerShell 命令仅适用于参数之间没有空格的情况
- angular - Nexted 在 rxjs 中订阅
- python - 如何从列表中更改图形标题的输出?
- java - NoSuchElementException:找不到行。?
- python - 播放器比相机蟒更快