I am learning x64 shellcode
on exploit.courses linux containers and I have a problem running a hello world x64 shellcode I wrote.
I am trying to move the "Hi there" buffer directly to a register so I don't use the .data
section.
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
I assemble the code and run it:
$nasm -f elf64 -o print2.o print2.asm
$ld -o print2 print2.o
$./print2
And nothing happens though print2 seems to exit normally... Could someone explain why?
Sorry if this question has already been asked. I tried looking for a similar one but couldn't find anything.
As first steps look at the write
documentation
ssize_t write(int fd, const void *buf, size_t count);
The second arguments must be a const void *
But for linux the calling convention is:
RDI, RSI, RDX, RCX, R8, R9, XMM0–7
Then your implementation is not correct.
You should do something like this
global _start
_start:
jmp short msg
routine:
...
pop rsi ;address of the string from the stack
...
msg:
call routine
db 'Hi here'