flat assembler
Message board for the users of flat assembler.

Index > Windows > Tiny PE in win64

Goto page Previous  1, 2, 3, 4
Author
Thread Post new topic Reply to topic
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 21023
Location: In your JS exploiting you and your system
revolution 19 Jul 2026, 17:59
The stack is not in the text section. "sub rsp,8" aligns the stack, not the code.
Post 19 Jul 2026, 17:59
View user's profile Send private message Visit poster's website Reply with quote
Calendos



Joined: 20 Jan 2021
Posts: 20
Location: France
Calendos 19 Jul 2026, 18:04
Thanks again. I'll think about your explanation.
Post 19 Jul 2026, 18:04
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4558
Location: vpcmpistri
bitRAKE 19 Jul 2026, 19:24
There are two concepts being overlayed: load-time alignment and runtime alignment. At load-time the OS aligns the section, but the entry-point address need not be aligned - the loader can CALL an odd address.

At runtime the ABI requires RSP alignment prior to CALL'ing an ABI function -- the loader assumes the entry-point is such a function. This means that on the application side a return address has been pushed on an aligned stack. In general, at entry to any ABI function the stack is unaligned by the return address.

It is important to become familiar with this ABI execution model: the CALL'er perspective (aligned) and the CALL'ee perspective (unaligned). Therefor, if a CALL'ee wished to execute an ABI function that CALL'ee would need to align the stack and create shadow-space -- otherwise there is potential for various crashes.

_________________
¯\(°_o)/¯ AI may [not] have aided with the above reply.
Post 19 Jul 2026, 19:24
View user's profile Send private message Visit poster's website Reply with quote
Calendos



Joined: 20 Jan 2021
Posts: 20
Location: France
Calendos 20 Jul 2026, 17:44
Thank you for your contributions, which have helped me to better understand this alignment issue. Thank you also, bitRAKE, for clarifying the concepts involved. Consulting Microsoft's online documentation, I found an interesting reference in the article "Overview of x64 ABI conventions," the relevant section of which I've reproduced at the end of this message. This confirms that the stack is aligned to 4 bytes instead of 8. Hence, the corresponding action on RSP.

However, I still don't understand the alignment method that involves subtracting 8 from the RSP register (or the `push rbp` suggested by revolution). Personally, I would have preferred an instruction like:

AND RSP,0FFFFFFFFFFFFFFF0
By doing so, we would truly align RSP to a QWord.

From what I recall, I've never seen this kind of alignment practice in 64-bit MASM. But I have very little 64-bit programming experience. Could you recommend some reading material that would help me progress, if needed?

Thank you in advance!
Quote:
Overview of x64 ABI conventions

Conflicts with the x86 compiler
Data types that are larger than 4 bytes aren't automatically aligned on the stack when you use the x86 compiler to compile an application. Because the architecture for the x86 compiler is a 4 byte aligned stack, anything larger than 4 bytes, for example, a 64-bit integer, can't be automatically aligned to an 8-byte address.
Working with unaligned data has two implications.
• It may take longer to access unaligned locations than it takes to access aligned locations.
• Unaligned locations can't be used in interlocked operations.
If you require more strict alignment, use __declspec(align(N)) on your variable declarations. This causes the compiler to dynamically align the stack to meet your specifications. However, dynamically adjusting the stack at run time may cause slower execution of your application.

The text above is available at https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170
Post 20 Jul 2026, 17:44
View user's profile Send private message Reply with quote
alCoPaUL



Joined: 20 Jun 2023
Posts: 13
Location: NYC
alCoPaUL 20 Jul 2026, 18:36
instead of messagebox, you can use printf and pass the output string through stdout & finally silently save it to a binary file, script or some kind of file format...

and still maintaining less than 1k byte size...
Post 20 Jul 2026, 18:36
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4558
Location: vpcmpistri
bitRAKE 20 Jul 2026, 20:13
Calendos wrote:
AND RSP,0FFFFFFFFFFFFFFF0
There are several ways to perform the alignment, but we also should ask ourselves, "Will this function return?"; "Does the code need to preserve the state provided by the caller?"

ExitProcess does not return. If that's the termination route of your application then the code doesn't even need to preserve non-volatile registers! The code can do POP REG -- not using the return and reuse caller's shadow-space.

I like to use ENTER .frame, 0 -- just to save on code bytes, it's slower execution wise.

AND RSP,-16 is only more valid when the stack value is unknown - like dynamic stack buffers. Let me know if you'd like an example - searching the board will no doubt return many from me.

_________________
¯\(°_o)/¯ AI may [not] have aided with the above reply.
Post 20 Jul 2026, 20:13
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 21023
Location: In your JS exploiting you and your system
revolution 20 Jul 2026, 23:41
Calendos wrote:
However, I still don't understand the alignment method that involves subtracting 8 from the RSP register (or the `push rbp` suggested by revolution). Personally, I would have preferred an instruction like:

AND RSP,0FFFFFFFFFFFFFFF0
By doing so, we would truly align RSP to a QWord.
Consider the flow of instructions just before the program executes its first instruction.
Code:
; Inside the OS loader, that puts the program in memory
; here RSP is always aligned to 0 mod 16, as per the FASTCALL convention

    call [program_entry_point] ; address is in the PE header
; here RSP is now 8 mod 16, the return address was pushed onto the stack

; --------------------------------------------------------

; now inside the program, the first instruction
entry:
    push rbp                        ; (or sub rsp, 8 if preferred)
; here RSP is now 0 mod 16 again, proper alignment is guaranteed

; program does its thing here    
Post 20 Jul 2026, 23:41
View user's profile Send private message Visit poster's website Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1818
Location: Toronto, Canada
AsmGuru62 24 Jul 2026, 00:32
The issue is that when Windows starts your program --- your aligned entry point is CALL-ed by Windows Loader.
Obviously a CALL instruction will put the return code into stack, misaligning it.
'text' section is aligned, of course.
Post 24 Jul 2026, 00:32
View user's profile Send private message Send e-mail Reply with quote
Calendos



Joined: 20 Jan 2021
Posts: 20
Location: France
Calendos 03 Aug 2026, 14:02
RSP alignment at the entry point of 64-bit programs

Revolution, bitRake, and AsmGuru62—thanks again for your contributions. I wanted to implement them in a simple 64-bit program designed to display the hexadecimal value of the RSP register at the entry point (see the end of this post).
RSP value obtained with this program: 00000000-0009FF58
The program crashes if I remove the first line containing `sub rsp,8`, which confirms your observations. However, if I place that instruction immediately after `loop Loop4` rather than at the beginning, the program works again.
I infer—perhaps incorrectly—that it is the Windows functions that do not support this misalignment. What do you think?
Code:
; Viewing the contents of the RSP register at
; the entry point of a Windows 64-bit program.

format PE64 GUI 5.0
entry start

include 'win64a.inc'

section '.text' code readable executable

  start:

        sub     rsp,8                   ; alignment of the RSP register
        mov     rax,rsp
        add     rax,8                   ; actual value of RSP at program entry
        cld
        mov     rdi,_RegContent
        mov     rcx,16

;==== Converting 64-bit binary value to asciiz string ====
Loop4:
        rol     rax,4
        push    rax
        and     al,0Fh
        cmp     al,10
        jb      @F
        add     al,7

@@:     add     al,30h
        stosb
        cmp     rcx,9
        jne     @F
        mov     al,'-'
        stosb

@@:     pop     rax
        loop    Loop4

;===== Dispalying in a Message Box and Exit
        invoke  MessageBox,NULL,_RegContent,_title,MB_ICONERROR+MB_OK

        invoke  ExitProcess,NULL

section '.data' data readable writeable

  _RegContent  DB  32 dup(0)
  _title       DB 'ESP register content when starting',0

section '.idata' import data readable writeable
  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'                       
Post 03 Aug 2026, 14:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 21023
Location: In your JS exploiting you and your system
revolution 03 Aug 2026, 14:35
Calendos wrote:
I infer—perhaps incorrectly—that it is the Windows functions that do not support this misalignment. What do you think?
Yes, It is only an API spec, not a hardware spec.

Programs are free to use any alignment for RSP, or even use RSP for arithmetic, as long as the usage is purely internal and no API calls to external libraries or system calls are made.

Mentioned in a previous post is Windows uses movapd (or maybe movdqa, maybe both) to copy register values to the shadow space in the stack. It is these instructions, and only these instructions that require alignment of the destination address. For "speed" of course. So calling an API function with a misaligned stack creates the problem for movdqa/movapd.

BTW: Use push rbp instead of "sub rsp,8".
Post 03 Aug 2026, 14:35
View user's profile Send private message Visit poster's website Reply with quote
Calendos



Joined: 20 Jan 2021
Posts: 20
Location: France
Calendos 04 Aug 2026, 05:37
Finally, I get it!!!!!
Have a great day, everyone.
Post 04 Aug 2026, 05:37
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.