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.
uj5u.com熱心網友回復:
在堆疊上構造資料,然后將堆疊指標復制到另一個reg,完全正常。許多 shellcode 操作 RSP。
push rsp/pop rdi只是 2 位元組的版本mov rdi, rsp,它是在推送 0 和 8 位元組的 ASCII 資料之后出現的。(在 NASM 語法中可以更清楚地寫成mov rdi, '/bin//sh')。
使用除錯器單步執行 asm,并在syscall執行時查看 RDI 指向的記憶體,然后向后作業以了解您是如何到達那里的。
奇怪的是,他們mov rdi,rsp使用 push/pop將其壓縮到 2 個位元組,但在他們的異或歸零指令中使用了 REX 前綴。 xor esi,esi是等價的。NASM 會將該源優化為xor esi,esi,但您的鏈接顯示了反匯編。
此外,push 59/pop rax是在暫存器中構造小常量( __NR_execve)的標準 3 位元組方式,而不依賴于任何其他暫存器值。他們本可以做到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 的隱式歸零,所以更奇怪的是他們使用 64 位異或歸零進行 RSI。也許他們對 x86-64 了解不多,甚至沒有意識到cqo會明確使用 64 位運算元大小,將 RAX 符號擴展為 RDX:RAX,并打算在任何地方使用 64 位,因為他們認為需要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/357362.html
