flat assembler
Message board for the users of flat assembler.
Index
> Windows > 64 bit not understood sub rsp,8 ! Goto page Previous 1, 2, 3, 4, 5, 6, 7, 8, 9 Next |
Author |
|
revolution 11 May 2022, 12:15
I encourage anyone to try this for themselves.
Start up your debugger. Open some code using multiple "sub rsp,1" instructions. Single step through them. Did anything crash? |
|||
11 May 2022, 12:15 |
|
Furs 11 May 2022, 12:16
I mean, the stack needs 8 byte alignment, that's the native size.
Read: https://devblogs.microsoft.com/oldnewthing/20190111-00/?p=100685 Short snippet: Quote: Since there is no red zone on x86, the memory at negative offsets relative to the stack pointer may be overwritten at any time. Therefore, the above sequence is permitted to jump to panic. |
|||
11 May 2022, 12:16 |
|
revolution 11 May 2022, 12:24
That article is about something else entirely.
Did you try my suggestion? |
|||
11 May 2022, 12:24 |
|
Furs 12 May 2022, 13:06
What do you understand from:
Quote: The memory at negative offsets relative to the stack pointer may be overwritten at any time. What's a "negative offset" to rsp being set to, idk, NULL as a general purpose register? It even explicitly gives a very rare scenario with a paging I/O page fault. Such things can't be tested easily, but they can happen. Don't write time bombs. Also when I said debugger I didn't mean breakpoints. I meant using the debugging API to trigger exceptions or something. I'm not too familiar with it, but I bet it's possible. |
|||
12 May 2022, 13:06 |
|
revolution 12 May 2022, 13:40
But "sub rsp,1" never generates and exception. So that article does not apply.
I guarantee you the stack won't ever be written, by any process (kernel included), before, during or after execution of "sub rsp, 1". So the code I posted will work fine. Please stop sowing unnecessary FUD. An app does not have any obligation to maintain a valid RSP value. In x86 you can use push to a stack aligned to 1 if you want to. There will be no exception unless your stack overflows it's bounds. Just don't try calling the Windows OS API, because we already know Windows uses the aligned data loads and crashes. But that is purely an OS decision, not a hardware requirement. Inside your code do whatever you want with RSP, the hardware won't care. External exceptions won't kill your process. Only your own internal exceptions will complain about an invalid stack. And "sub rsp,1" doesn't generate any exceptions. |
|||
12 May 2022, 13:40 |
|
AsmGuru62 12 May 2022, 15:33
This topic is somewhat devolved.
The sub rsp,8 is needed only at the start: label. Because Windows makes a CALL to that start: label and just immediately after the CALL the stack is not aligned to use OS API. Now, FASM has invoke macro which implements the shadow space (no need for SUB RSP,0x20). Also, you can use local directive inside the procedure (macros proc/endp) and it also automatically aligns stack to 16 bytes, so API can be called without any additional measures. Also #2: why PUSH/POP? x64 has registers (R12 ... R15) which are not used by API, so you can do the following to preserve RAX: Code: mov r12,rax .... call another API mov rax,r12 ; or just use R12 directly if you need it somewhere To use all these awesome macros -- you need to include "Win64W.Inc". |
|||
12 May 2022, 15:33 |
|
revolution 12 May 2022, 15:47
AsmGuru62 wrote: The sub rsp,8 is needed ... push rbp. Fewer bytes (not that is matters) push rbp. Debugger support (if you ever need it. Ya never know, right?) sub rsp,8. More bytes, for what? sub rsp,8. That magic value of 8, what does it mean? Why not 24? Or 72? I have no idea why everyone loves sub rsp, 8 so much. Is it because it isn't what normal C generators do? Is it because as assembly coders we must do stuff different, even for no purpose? I like the last reason the most. |
|||
12 May 2022, 15:47 |
|
macomics 12 May 2022, 15:58
Code: entry $ and spl, -16 ... Code: entry $ pop rax ... |
|||
12 May 2022, 15:58 |
|
Overclick 12 May 2022, 18:12
'Call' uses 8 bytes at stack only. You do whatever push or sub rsp just to align stack back to 16
You can 'call' twice to do the same Also don't forget to return the stack back after call by 'pop' or rsp directly: add rsp,8 as example |
|||
12 May 2022, 18:12 |
|
AsmGuru62 12 May 2022, 18:37
Indeed, PUSH RAX works also. It takes less bytes:
Code: 00000000004022B0 | 48:83EC 08 | SUB RSP, 0x8 | 00000000004022B4 | 50 | PUSH RAX | I copied this from FASM template for x64 provided in EXAMPLES folder. When you make your own function -- using proc/endp macros provide everything connected to stack alignment, so no need to balance the stack with POP. FASM uses LEAVE opcode to do it. All you need is to use CALL and pass values in ANY registers, because you are calling not OS API, but your own function. You can pass parameters in RAX or RSI, whatever is needed by the logic. It is the OS API which requires parameters in RCX,RDX,R8,R9 and needs a shadow stack room. When you design your own function -- none of that is needed. I just coded a large commercial app in x64 FASM and it works great! Just use proc/endp for your own functions and invoke for Windows API calls. |
|||
12 May 2022, 18:37 |
|
tthsqe 12 May 2022, 19:21
> But sub rsp,1 never generates an exception.
I don't think this is the point. The app can be interrupted at any point in time for keyboard, mouse, and spy cam interaction. |
|||
12 May 2022, 19:21 |
|
Overclick 12 May 2022, 21:30
Most elegant way:
Code: push rax call something ... ... something: ... invoke... ... ret 8 |
|||
12 May 2022, 21:30 |
|
revolution 13 May 2022, 00:17
tthsqe wrote: > But sub rsp,1 never generates an exception. The app is not obligated to maintain a valid rsp. So all that matters here is that "sub rsp,1" never causes an exception, so everything works perfectly fine. There really is no problem with "sub rsp,1", except that many people misunderstand what the kernel does, and think the red zone is for the kernel to place random data when it pleases. It doesn't. ___________________________________________ To macomics: What is your reasoning for your choice of rax? |
|||
13 May 2022, 00:17 |
|
macomics 13 May 2022, 00:52
revolution wrote: What is your reasoning for your choice of rax? Choose any of the 8. |
|||
13 May 2022, 00:52 |
|
revolution 13 May 2022, 01:11
So can I choose rbp?
|
|||
13 May 2022, 01:11 |
|
macomics 13 May 2022, 02:16
why not
add: I just want to draw attention to the fact that the module_entry_point call is not performed from an vacuum. If you don't want to bother with rollback and safe return from the main function, you can leave it to the system code. And if the system is lying in the struggle for the completion of a failed program, so what is the price of such a system. |
|||
13 May 2022, 02:16 |
|
Furs 13 May 2022, 13:28
revolution wrote: But "sub rsp,1" never generates and exception. So that article does not apply. Here are copy pasted quotes with emphasis: Quote: A debugger may use the memory beyond the red zone as a convenient place to store some data. For example, if you use the .call command, the debugger will perform the nested call on the same stack, and likely use some of that stack space to preserve registers so that they can be restored after the .called function returns. Any data stored beyond the red zone will therefore be destroyed. Quote: Suppose your thread gets pre-empted immediately after you store the data beyond the red zone. While your thread is waiting for a chance to resume execution, the memory manager pages out the code. Eventually, your thread resumes execution, and the memory manager tries to page it back in. Oh no, there’s an I/O error during the page-in! The operating system pushes an exception frame onto the stack for the STATUS_IN_PAGE_ERROR, clobbering the data you had been hiding beyond the red zone. revolution wrote: I guarantee you the stack won't ever be written |
|||
13 May 2022, 13:28 |
|
revolution 13 May 2022, 13:45
sub rsp,1 doesn't store data in the red zone.
Your article is not relevant. |
|||
13 May 2022, 13:45 |
|
Furs 14 May 2022, 13:49
Do you not understand English in the article, or have you still not read it?
Quote: A debugger may use the memory beyond the red zone [...] The point isn't the red zone. The point is that accessing the red zone requires rsp. And what happens if rsp has unaligned value or, worse, arbitrary value (like NULL)? What's [rsp-10] (red zone address) when rsp is NULL? It's not rocket science. |
|||
14 May 2022, 13:49 |
|
Goto page Previous 1, 2, 3, 4, 5, 6, 7, 8, 9 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.