Skip to content

64 bit linux unaligned stack crash and printf params repetition.#4

Open
artur-augustyniak wants to merge 1 commit intogynvael:masterfrom
artur-augustyniak:upstream_master
Open

64 bit linux unaligned stack crash and printf params repetition.#4
artur-augustyniak wants to merge 1 commit intogynvael:masterfrom
artur-augustyniak:upstream_master

Conversation

@artur-augustyniak
Copy link

Hi,
AFAIK problem with xmm registers and doubling printf arguments affects only x86_64 linux (and OSX in extension). Tested with a lot of your code from youtube assembly course, seems to work well on 32/64 bit Windows, Linux nad OSX:
For linux stub i had to extend stub space in asmloader itself 0x400 instead 0x200.
Affects 86_64 linux stub:

  ; remove args passed via registers from stack to avoid printing
  ; them twice in case of more than 6 printf arguments
  ; no easy way to detect exact number of arguments so we have to save the stack
  ; to rebuild it in case of less then 6 params
  mov [rel saved_stack_top], rdi
  mov [rel saved_stack_nd], rsi
  mov [rel saved_stack_rd], rdx
  mov [rel saved_stack_fourth], rcx
  mov [rel saved_stack_fifth], r8
  mov [rel saved_stack_sixth], r9
  add rsp, 48`

Next problem was rax usage for printf float args count:

  ; When calling printf stub uses rax, so this register is nonzero.
  ; This causes printf to "see" floating point arguments and starts using SSE.
  ; At the same time if the stack does not have the proper 16 byte alignment asmloader will crash.
  ; After first [rbx + 3 * 8] call rax may be nonzero again
  ; so code like:
  ;
  ; [bits 64]
  ;
  ; call no_arg_procedure
  ;
  ; push 0
  ; call [rbx + 0 * 8]
  ;
  ; no_arg_procedure:                  ; no_arg_procedure()
  ;
  ;    call _print
  ;         db "abc", 0xa, 0
  ;     _print:
  ;     call [rbx + 3 * 8]
  ;     add rsp, 8
  ;
  ;     call _print2
  ;         db "cde", 0xa, 0
  ;         _print2:
  ;         call [rbx + 3 * 8]
  ;     add rsp, 8
  ;     ret
  ;  ;end
  ;
  ; will leave stack unaligned and nonzero rax, this will crash, so:
  xor rax, rax
  call r15`

We also need to restore stack add rsp, 48 can hurt some ret address in case less than 6 arguments passed to printf,:

  ; restore 6 stack elements
  push QWORD [rel saved_stack_sixth]
  push QWORD [rel saved_stack_fifth]
  push QWORD [rel saved_stack_fourth]
  push QWORD [rel saved_stack_rd]
  push QWORD [rel saved_stack_nd]
  push QWORD [rel saved_stack_top]`

Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant