2017-10-12 167 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'。 –