0

I'm trying to put a reference to my stack pointer into the %rsi register so that the syscall will get the struct from i's second parameter.

here is the code :

01: mov $0x2a, %al
02 : mov $3, %rdi
03 : push $0x02
04 : push $0x0068
05 : push $0x5c11
06 : push $0xa8c0
07 : push $0x1401
08 : mov (%rsp), %r13
09 : mov %r13, %rsi # this is where I get lost
10 : mov $0x10, %dl
11 : syscall

strace ./helloWorld give me this :

connect(3, 0x5c11, 16)
exit(0)

My question is : how can I pass a struct that I have put on the stack to the rsi register (by passing the pointer of the stack)

What I have tryied so far :

  • Reading about GNU syntax
  • passing the reference directly without intermediate register
    08 : #mov (%rsp), %r13
    09 : mov %rsi, (%rsp)
    
  • using pointer deplacement
    03 : mov $0x02 (%rsp)
    04 : movw $0x0068 2(%rsp)
    05 : movw $0x5c11 4(%rsp)
    06 : movw $0xa8c0 6(%rsp)
    07 : movw $0x1401 8(%rsp)
    08 : # mov (%rsp), %r13
    09 : mov (%rsp), %rsi
    
    strace ./hellowWorld:
    ...
    connect(3, 0xa8c05c1100680002, 16)
    ...
    

Every time I have in the second argument is the value of the registers or the stacks, not a pointer.

Using NASM syntax, Everything is ok.

I am using theses resources :

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    You do not want the indirection. Just do `mov %rsp, %rsi`. – Jester May 30 '22 at 20:44
  • (FYI, it's [register](https://en.wikipedia.org/wiki/Processor_register), not a [registry](https://en.wikipedia.org/wiki/Registry).) – Erik Eidt May 30 '22 at 20:44
  • @Jester, ok, that worked Oo. I don't understand though. Ains't you supposed to pass a pointer ? Does the %rsp register alway leads to the stack pointer ? – GuiltySpark May 30 '22 at 20:54
  • The rsp *is* the stack pointer; it points to the top byte on the stack. The rsp register holds the value that is the address of the top of stack, aka the stack *pointer*. If you dereference the stack pointer you'll get items/bytes/words that are on the stack. – Erik Eidt May 30 '22 at 20:56
  • @ErikEidt, Ah Is see. This was my mistake. I though this register was like any other, and if I want to pass a pointer and not a value, I have to do something more. But stack register gives the start of the stack pointer. Nothing to do more. Thanks a lot, this was really usefull ! – GuiltySpark May 30 '22 at 21:15
  • 2
    Ok, good. FYI, all the registers are like that though, holding simple values that sometimes happen to be addresses. – Erik Eidt May 30 '22 at 21:54
  • FYI, your two version aren't equivalent. Your version with `push` is using `pushq $sign_extended_imm32`, so you're pushing $0x0000000000005c11` into 8 bytes by itself. If you want to push 8 bytes of data where the top 4 is non-zero, `mov $0x12345678abcdef, %rcx` / `push %rcx` or something. (Pick any tmp register). Or `push` and `mov $imm32, 4(%rsp)` but that takes more bytes around the immediates. – Peter Cordes May 31 '22 at 02:39
  • [Printing an integer as a string with AT&T syntax, with Linux system calls instead of printf](https://stackoverflow.com/q/45835456) is a near duplicate, includes a working example as part of making a `write` system call, although the data gets onto the stack via `mov` stores, not `push`. – Peter Cordes May 31 '22 at 04:32

0 Answers0