flat assembler
Message board for the users of flat assembler.
Index
> Windows > Error calling WSAStartup with unaligned stack in Win64 |
Author |
|
MUFOS 14 Jan 2017, 13:16
Hey, there Im getting an error when calling WSAStartup.
First I call MemAlloc, which is just a function to call HeapAlloc. Using the memory pointer, which is WSADATA, I pass it to WSAStartup. However, I get the same access violation error every time. Code: mov r8, 400 call MemAlloc mov [WSAData], rax mov cx, 0x101 mov rdx, rax call [WSAStartup] ret The following is the result: https://gyazo.com/9616013908dcb4da961152607341b057 Always the same address, 00007FFC4... I am using x64dbg. However, I tried a different debugger, same result. |
|||
14 Jan 2017, 13:16 |
|
MUFOS 14 Jan 2017, 13:26
revolution wrote: Your stack is not properly aligned. Thanks, could u explain what it means to align the stack? This is the first time im programming in win64. I am not really familiar with the calling convention. But do I need to allocate space for the parameters even when its passed using the registers? |
|||
14 Jan 2017, 13:26 |
|
revolution 14 Jan 2017, 13:31
MUFOS wrote: Thanks, could u explain what it means to align the stack? MUFOS wrote: But do I need to allocate space for the parameters even when its passed using the registers? |
|||
14 Jan 2017, 13:31 |
|
MUFOS 14 Jan 2017, 13:37
revolution wrote:
0 mod 16 = 0 I am not sure I understand :/ Newbie here. |
|||
14 Jan 2017, 13:37 |
|
revolution 14 Jan 2017, 13:40
Make sure the lowest four bits of RSP = 0 and then do the call. This should happen automatically if you have proper stack frame code.
|
|||
14 Jan 2017, 13:40 |
|
MUFOS 14 Jan 2017, 13:50
revolution wrote: Make sure the lowest four bits of RSP = 0 and then do the call. This should happen automatically if you have proper stack frame code. Would u mind giving me an example ? |
|||
14 Jan 2017, 13:50 |
|
revolution 14 Jan 2017, 13:55
This is in the fasm download:
Code: ; Example of 64-bit PE program format PE64 GUI entry start section '.text' code readable executable start: sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned mov r9d,0 lea r8,[_caption] lea rdx,[_message] mov rcx,0 call [MessageBoxA] mov ecx,eax call [ExitProcess] section '.data' data readable writeable _caption db 'Win64 assembly program',0 _message db 'Hello World!',0 section '.idata' import data readable writeable dd 0,0,0,RVA kernel_name,RVA kernel_table dd 0,0,0,RVA user_name,RVA user_table dd 0,0,0,0,0 kernel_table: ExitProcess dq RVA _ExitProcess dq 0 user_table: MessageBoxA dq RVA _MessageBoxA dq 0 kernel_name db 'KERNEL32.DLL',0 user_name db 'USER32.DLL',0 _ExitProcess dw 0 db 'ExitProcess',0 _MessageBoxA dw 0 db 'MessageBoxA',0 |
|||
14 Jan 2017, 13:55 |
|
MUFOS 14 Jan 2017, 13:58
revolution wrote: This is in the fasm download: So by subtracting by a product of 8 it gets 0 mod 16 aligned? I saw someone on the internet saying that one should subtract amount of bytes needed, then Code: and rsp, -10 Someone else suggests doing it, but instead: Code: and rsp, 0fffffff0h |
|||
14 Jan 2017, 13:58 |
|
revolution 14 Jan 2017, 14:17
If you use a normal stack frame with RBP and ensure that all stack adjustments are multiples is 16 bytes then you won't need to fiddle with it.
|
|||
14 Jan 2017, 14:17 |
|
MUFOS 14 Jan 2017, 14:20
revolution wrote: If you use a normal stack frame with RBP and ensure that all stack adjustments are multiples is 16 bytes then you won't need to fiddle with it. In the example above, 8*5 is not a multiple of 16. |
|||
14 Jan 2017, 14:20 |
|
revolution 14 Jan 2017, 15:06
The caller starts at 0 mod 16 and calls the "start:" label putting the stack at 8 mod 16. So if you then push RBP for a normal function then the stack is again 0 mod 16. And from there everything can use a full multiple of 16.
The example code doesn't push RBP so instead you adjust another 8 bytes to align it correctly. |
|||
14 Jan 2017, 15:06 |
|
MUFOS 14 Jan 2017, 15:35
revolution wrote: The caller starts at 0 mod 16 and calls the "start:" label putting the stack at 8 mod 16. So if you then push RBP for a normal function then the stack is again 0 mod 16. And from there everything can use a full multiple of 16. All right, thank you so much for the help +rep |
|||
14 Jan 2017, 15:35 |
|
MUFOS 14 Jan 2017, 18:08
revolution wrote: The caller starts at 0 mod 16 and calls the "start:" label putting the stack at 8 mod 16. So if you then push RBP for a normal function then the stack is again 0 mod 16. And from there everything can use a full multiple of 16. I actually have one more question; while I have my stack aligned in one stack frame, if I push an argument onto the stack for then to call a function, it seems I have to subtract 8 bytes from RSP to keep it aligned. That is all normal, or is there a better way to implement stack frame so that its aligned independent of number of arguments passed? |
|||
14 Jan 2017, 18:08 |
|
revolution 15 Jan 2017, 01:40
To comply with the fastcall spec you have to follow the argument order correctly. It is probably easiest to adjust the stack first and then place the arguments later using "mov" instructions. But whatever you do you still have to make it 0 mod 16. If you don't your code will crash, as you have seen.
|
|||
15 Jan 2017, 01:40 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.