sikerbela
sikerbela

Reputation: 388

asm64 write system call: non-adjacent memory?

I have this little program written in x64 assembly:

xor    rdx,rdx
push   rdx            ;null terminator
push   0x41414141     ;AAAA
push   0x45454545     ;EEEE
mov    rsi,rsp        ;pointer to the string
mov    rdi,1          ;output file: stdout
mov    rdx,8          ;buffer size 8
mov    rax,1          ;write syscall
syscall

As you can see, I push eight bytes to the stack and when I call write with buffer size 8, I am expecting to see EEEEAAAA but the output is EEEE. However, when I set the buffer size rdx to 12, I can see the full string EEEEAAAA. What is between those four-byte blocks? Aren't they ought to be adjacent?

Upvotes: 0

Views: 144

Answers (1)

Jester
Jester

Reputation: 58762

Each push writes 8 bytes, since that is the stack size in 64 bit mode. The immediate in the instruction is sign extended to 64 bits, see the instruction set reference: If the source operand is an immediate of size less than the operand size, a sign-extended value is pushed on the stack.

As such, your stack looks like (from rsp upwards):

0x0000000045454545 ; EEEE sign extended to 64 bits
0x0000000041414141 ; AAAA sign extended to 64 bits
0x0000000000000000 ; NULL terminator

As workaround you can do:

xor rdx, rdx
push rdx
mov rax, 0x4141414145454545
push rax
mov    rsi,rsp        ;pointer to the string
mov    rdi,1          ;output file: stdout
mov    rdx,8          ;buffer size 8
mov    rax,1          ;write syscall
syscall

Upvotes: 2

Related Questions