Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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