flat assembler
Message board for the users of flat assembler.

Index > Windows > How to insert code in DOS stub of a PE?

Author
Thread Post new topic Reply to topic
FlierMate11



Joined: 13 Oct 2022
Posts: 56
FlierMate11 25 Jan 2023, 07:20
I am referencing to Learning binary file formats (work in progress) by Tomasz.
(https://board.flatassembler.net/topic.php?t=20690)

I modified the basic.asm, to insert DOS program in the DOS stub:

Code:
SIZE_OF_STUB_HEADER := $ - Stub

        ; The code of a DOS program would go here.
;org 100h
use16

        mov ah, 09h
        mov dx, msg_string
        int 21h
        mov ax, 4c00h
        int 21h

msg_string      db      "Hello World$"
;org IMAGE_BASE
use32
SIZE_OF_STUB := $ - Stub      


But fasmg gives error:
Quote:

C:\FASMG>fasmg basic.asm
flat assembler version g.jxp0
basic.asm [32]:
mov dx, msg_string
mov? [137]
Processed: dw @src.imm
Error: value out of allowed range.


Or if I insert too long program, another error:
Quote:

C:\FASMG>fasmg basic.asm
flat assembler version g.jxp0
basic.asm [19]:
.NumberOfHeaderParagraphs dw SIZE_OF_STUB_HEADER / 16
Processed: .NumberOfHeaderParagraphs dw SIZE_OF_STUB_HEADER / 16
Error: value out of allowed range.


But if just the code to exit, then it is working:

Code:
SIZE_OF_STUB_HEADER := $ - Stub

        ; The code of a DOS program would go here.
;org 100h
use16

        mov ax, 4c00h
        int 21h

msg_string      db      "Hello World$"
;org IMAGE_BASE
use32
SIZE_OF_STUB := $ - Stub      


Does the DOS stub use "org 0h" or keep "org IMAGE_BASE" unchanged?

How long is the DOS stub allowed?

I have error also when using "call label" in DOS stub.

Please help!
Post 25 Jan 2023, 07:20
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: 19121
Location: In your JS exploiting you and your system
revolution 25 Jan 2023, 07:28
Stubs are only valid for MZ formats within PE files.

Stubs can be any length up to, IIRC, 64kb.
Post 25 Jan 2023, 07:28
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: 19121
Location: In your JS exploiting you and your system
revolution 25 Jan 2023, 07:31
A stub:
Code:
format MZ
segment zz
entry zz:0
stack 128
heap 0
push cs
pop ds
mov ah,9
mov dx,message
int 21h
mov ax,4cffh
int 21h
message:
db 'Windows 95 or higher required for this program!',0dh,0ah,'$'
db 256+128 dup 0xaa ; random data to make the stub bigger for testing    
The app.
Code:
format PE GUI 4.0 on 'BigStub-Stub.exe'

include 'win32ax.inc'

.code

  start:
        invoke  MessageBox,HWND_DESKTOP,"Hi! I'm the example program!","Win32 Assembly",MB_OK
        invoke  ExitProcess,0

.end start    
Post 25 Jan 2023, 07:31
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 56
FlierMate11 25 Jan 2023, 07:48
revolution wrote:
A stub:
Code:
format MZ
segment zz
entry zz:0
stack 128
heap 0
push cs
pop ds
mov ah,9
mov dx,message
int 21h
mov ax,4cffh
int 21h
message:
db 'Windows 95 or higher required for this program!',0dh,0ah,'$'
db 256+128 dup 0xaa ; random data to make the stub bigger for testing    
The app.
Code:
format PE GUI 4.0 on 'BigStub-Stub.exe'

include 'win32ax.inc'

.code

  start:
        invoke  MessageBox,HWND_DESKTOP,"Hi! I'm the example program!","Win32 Assembly",MB_OK
        invoke  ExitProcess,0

.end start    


Aww... I like this, tested OK on my PC.

I didn't know can insert DOS stub into PE output like that. Thanks.
Post 25 Jan 2023, 07:48
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: 19121
Location: In your JS exploiting you and your system
revolution 25 Jan 2023, 08:23
The stub can be any MZ format program. It doesn't have to be only a stub, it can be a full application.
Post 25 Jan 2023, 08:23
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8106
Location: Kraków, Poland
Tomasz Grysztar 25 Jan 2023, 12:17
revolution wrote:
Stubs can be any length up to, IIRC, 64kb.
MZ files can be larger. You can, in fact, assemble FASMW.EXE on top of FASMD.EXE, and it works.
Code:
; alteration in source\ide\fasmw\fasmw.asm:
format PE GUI 4.0 large NX on '..\fasmd\fasmd.exe'    
Post 25 Jan 2023, 12:17
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: 19121
Location: In your JS exploiting you and your system
revolution 25 Jan 2023, 15:44
Tomasz Grysztar wrote:
MZ files can be larger. You can, in fact, assemble FASMW.EXE on top of FASMD.EXE, and it works.
Thanks for the correction.

I wonder if it is possible to have a DOS TUI, Windows GUI and a CMD CLI in a single exe.

Windows is weird with how to detect and use the console vs a window. The requirement to mark the exe as either GUI or CLI forces an initial choice, and leaves the app with only inferior choices about how to deal with switching to another interface.

Many apps don't even try and just make two exe files.
Post 25 Jan 2023, 15:44
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 56
FlierMate11 06 Feb 2023, 09:52
I solved my original problem in Post #1:

Code:
use16
align 16

SIZE_OF_STUB_HEADER := $ - Stub

        ; The code of a DOS program would go here.

dos_stub:
        push  cs
        pop   ds
        mov   dx, msg - dos_stub
        mov   ah, 9
        int   21h
        mov   ax, 4c01h
        int   21h

msg     db "This program can only be run in Windows.",13,10,"$"


SIZE_OF_STUB := $ - Stub

use32
align 8                 


It compiles and runs nicely in DOSBox. Must use offset relative to the DOS stub.

I was inspired with the solution after checking other Windows EXE in hexdump mode.
Post 06 Feb 2023, 09:52
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8106
Location: Kraków, Poland
Tomasz Grysztar 06 Feb 2023, 10:40
FlierMate11 wrote:
Must use offset relative to the DOS stub.
You could also adjust ORG locally, and later restore it with:
Code:
org $%    
to bring it back to sync with file offsets. There's also an option of generating the code in a VIRTUAL block and then just copying the raw data into PE header with help of LOAD.

You can also adjust various values, including the entry point, by tweaking MZ headers. See how fasm-compatible PE formatter for fasmg does it:
Code:
                Stub:
                .signature                     dw "MZ"
                .bytes_in_last_page            dw .LENGTH and 1FFh
                .number_of_pages               dw (.LENGTH-1) shr 9 + 1
                .number_of_relocations         dw 0
                .number_of_header_paragraphs   dw .HEADER_LENGTH shr 4
                .minimum_heap                  dw .STACK_LENGTH shr 4
                .maximum_heap                  dw 0FFFFh
                .initial_ss                    dw 0
                .initial_sp                    dw .LENGTH - .HEADER_LENGTH + .STACK_LENGTH
                .checksum                      dw 0
                .initial_ip                    dw 0
                .initial_cs                    dw 0
                .relocations_offset            dw 40h
                .overlay_number                dw 0
                                               rb 3Ch - $
                .new_header_offset             dd Header

                .HEADER_LENGTH = $
                .STACK_LENGTH = 100h

                namespace Stub

                      include 'cpu/8086.inc'

                start:
                      push    cs
                      pop     ds
                      mov     dx,message - start
                      mov     ah,9
                      int     21h
                      mov     ax,4C01h
                      int     21h

                message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h

                end namespace

                align 16

                .LENGTH = $    
Note that it uses a locally-included instruction set, this way it works even when making PE for non-x86 architecture.

PS. This thread also reminded me of an inverse stub I made as a joke.
Post 06 Feb 2023, 10:40
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.