2017-10-12 164 views
1

我正在學習x64 shellcode關於exploit.courses linux容器和我運行hello world x64 shellcode的問題我寫了。 我正在嘗試將「Hi there」緩衝區直接移動到一個寄存器,因此我不使用.data部分。xll helloworld shellcode不打印任何東西

section .data 

;msg db "Hi there" 

section .text 

global _start 
_start: 
;zeroed out these registers 
xor rax, rax 
xor rbx, rbx 
xor rsi, rsi 
xor rdi, rdi 
xor rdx, rdx 

;write (int fd, char *msg, unsigned int len); 
mov rax,1 ; syscall 1 is write in 64bit arch 
mov rdi,1 ; rdi is fd 
mov rbx, 0x6572656874206948 
mov rdx, 9; rdx is size (9 for null byte) 
syscall ; instead of int 0x80 for 32 bit architecture 

;exit (int ret) 
mov rax, 60 ; syscall 60 is exit in 64bit arch 
mov rdi, 0 ; rdi is error code 
syscall 

我組裝和運行代碼:

$nasm -f elf64 -o print2.o print2.asm 
$ld -o print2 print2.o    
$./print2 

並沒有任何反應,雖然print2似乎正常退出...有人能解釋一下爲什麼?

對不起,如果這個問題已經被問到。我試圖尋找一個類似的,但找不到任何東西。

+2

使用'strace'。爲什麼當你通過rsi = NULL作爲緩衝區時,你期望它打印什麼? 'rbx'不是系統調用參數寄存器之一。請參閱https://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64。而且你總是需要傳遞一個指向內存中數據的指針write()。另見https://stackoverflow.com/tags/x86/info –

+0

@PeterCordes對不起,我現在只看到你的評論 – invictus1306

+0

@ invictus1306:我確定這是一個重複的東西,但我沒有花時間去看着。即使已經對答案進行了評論,您也不需要爲發佈答案而道歉。 SO想要真正的答案。唯一錯誤的是回答一個問題,該問題應該作爲許多傳遞數據中的一個而不是指針問題的重複來解決(除非這個問題甚至沒有在正確的寄存器中,所以IDK)。 –

回答

1

作爲第一步看writedocumentation

ssize_t write(int fd, const void *buf, size_t count); 

第二個參數必須是一個const void *

但對於Linux調用約定是:

RDI, RSI, RDX, RCX, R8, R9, XMM0–7 

那麼你的實現是不正確。

你應該做這樣的事情

global _start 


_start: 

    jmp short msg 

    routine: 

    ... 
    pop rsi   ;address of the string from the stack 
    ... 


    msg: 
    call routine  
    db 'Hi here' 
+0

這是64位代碼。使用RIP相關的'LEA rsi,[rel msg]'而不是'jmp' /'call'。或者爲了避免rel32位移的機器代碼中出現'00',跳過字符串以使'LEA'偏移量爲負(在高字節中爲FF而不是00)。這同樣使得'call'不包含'00'字節。或者在你的NOP-sled跳轉目標之前放置你的'msg'。 –