flat assembler
Message board for the users of flat assembler.

Index > Windows > Writing .EXEs Manually

Author
Thread Post new topic Reply to topic
babyboy10777



Joined: 28 Jun 2006
Posts: 6
Location: IL
babyboy10777
Hi. I'm creating a template for writing .EXEs, and I have 2 questions:

* What is SizeOfImage? How do you determine this? My documentation
says it is the size of everything aligned to 1000h, but FASM uses
2000h for a 1000h/4096/1K .EXE with 1 flat section
* In the following code, I receive an "out of range" (exceeds 4GB?)
error when referring to label @@. "display @f" doesn't even work

Note: This is experimental project. I haven't studied the PE format in
a long time (since 1999), and there may be errors due to inconsistent
documentation. Thanks.

Code:
; Manual .EXE template

macro align n { db ((n-1)-($+n-1) mod n) dup(0) }

exe:
dw 'MZ'                   ; useless...
db 3Ah dup(0)
dd 40h
db 'PE', 0, 0             ; signature
dd 1014Ch, 0, 0, 0        ; cpu (.I386+). # sections, etc
dd 10F00E0h, 10Bh         ; n/a
dd 0, 0, 0                ; size of .code/.idata/.data
dd 1000h, 0, 0, 400000h   ; entry, offset of .code/.data, base address
dd 1000h, 200h            ; alignment of sections in memory and file: 1K/512
dd 1, 0, 4, 0             ; versions
; ???????????????????????????????????????????????????????????????????????
n = exe_end-exe           ; total size rounded to 1000h?????????????????????
dd ((1000h-1)-(n+1000h-1) mod 10000h)
dd 200h, 0                ; section 1 offset
dw 2, 0                   ; subsystem
dd 1000h, 1000h, 1000h, 0 ; stack/heap reserve/commit
dd 0, 16                  ; flags, # directories
dq 0                      ; "data directory" structures
dd it+0E00h               ; import table rva, size...
dd one_end-it
dq 14 dup(0)

dq '.one'                 ; section header. file offset = 138h
dd one_end-one, 1000h     ; size, rva
dd exe_end-one            ; size rounded to 200h
dd 200h, 0, 0, 0          ; file offset, skip relocations, etc
dd 0E0000020h             ; attributes: readable, writable, executable, etc
db 200h-$ dup(0)          ; proceed to 200h/1000h

one:                      ; code:
a = @f + 401E00h          ; convert file offset to VA
; ??????????????????????????????????????????????????????????????????
push 0 a a 0              ; out of range?????????
call dword [MessageBox+401E00h]
push 0
call dword [ExitProcess+401E00h]
@@: db 'EXAMPLE', 0       ; data:

it:                       ; import table
dd 0,0,0, kernel_name+0E00h, kernel_table+0E00h
dd 0,0,0, user_name+0E00h, user_table+0E00h
dd 0,0,0,0,0
kernel_name db 'KERNEL32.DLL', 0
kernel_table:
ExitProcess dd _ExitProcess+0E00h
dd 0
_ExitProcess db 0, 0, 'ExitProcess', 0
user_name db 'USER32.DLL', 0
user_table:
MessageBox dd _MessageBox+0E00h
dd 0
_MessageBox db 0, 0, 'MessageBoxA', 0
one_end:
align 200h
exe_end:    
Post 03 Aug 2006, 03:14
View user's profile Send private message Reply with quote
Xanfa



Joined: 03 Aug 2006
Posts: 29
Xanfa
Quote:

* What is SizeOfImage? How do you determine this? My documentation
says it is the size of everything aligned to 1000h, but FASM uses
2000h for a 1000h/4096/1K .EXE with 1 flat section


Hi babyboy10777 !
Greatwork ! (Athough i haven't read your code ! )
I don't know all about PE format as you do, but about first problem, i think :

SizeOfImage is the total memory that loader allocate for the PE file went load it in memory ( i'm sure you know this !).
SizeOfImage=Total virtual size of all sections + size of headers

As I see, size of headers is smaller than section alignment (often 1000h), so first section starts at RVA 1000h. In your case, your first and the only one section .flat is smaller than 1000h too ,so total virtual size allocate for your program is 2000h bytes

I think this will more cleary to understand:

ImageSize= RVA of last section + virtual size of last section(aligned to section alignment ).
Post 03 Aug 2006, 03:54
View user's profile Send private message Yahoo Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7739
Location: Kraków, Poland
Tomasz Grysztar
You forgot USE32 to make your code 32-bit. And since it is 16-bit by default, the PUSH tries to push 16-bit word, while your value doesn't fit in such range.

As for the SizeOfImage, Xanfa already explained it well.
Post 03 Aug 2006, 06:56
View user's profile Send private message Visit poster's website Reply with quote
babyboy10777



Joined: 28 Jun 2006
Posts: 6
Location: IL
babyboy10777
Xanfa: Thanks for your help. I appreciate it.

Tomasz: 16BITs? No wonder! I didn't disassemble it yet, but I knew those machine code bytes in the hex editor didn't look right -- call rm had a 2 byte displacement. By the way, FASM is the BEST assembler there is! I recommend it to every one.
Post 03 Aug 2006, 11:26
View user's profile Send private message Reply with quote
babyboy10777



Joined: 28 Jun 2006
Posts: 6
Location: IL
babyboy10777
Here's the finished, working template. It runs perfect. Just replace .bin extension with .exe.

Code:
; Manual .EXE template

macro align n { db ((n-1)-($+n-1) mod n) dup(0) }

use32
exe:
dw 'MZ'                   ; useless...
db 3Ah dup(0)
dd 40h
db 'PE', 0, 0             ; signature
dd 1014Ch, 0, 0, 0        ; cpu (.I386+). # sections, etc
dd 10F00E0h, 10Bh         ; n/a
dd 0, 0, 0                ; .code/.idata/.data sizes
dd 1000h, 0, 0, 400000h   ; entry, .code/.data offsets, base address
dd 1000h, 200h            ; section alignment in memory and file: 1K/512
dd 1, 0, 4, 0             ; versions
dd (((1000h +\            ; image size = (rva + section size) aligned to 1000h
one_end-one) shr 12) + 1) shl 12
dd 200h, 0                ; section 1 offset
dw 2, 0                   ; subsystem
dd 1000h, 1000h, 1000h, 0 ; stack/heap reserve/commit
dd 0, 16                  ; flags, # directories
dq 0                      ; "data directory" structures...
dd it+0E00h               ; import table rva, size...
dd one_end-it
dq 14 dup(0)

dq '.one'                 ; section header. file offset = 138h
dd one_end-one, 1000h     ; size, rva
dd exe_end-one            ; size rounded to 200h
dd 200h, 0, 0, 0          ; file offset, skip relocations, etc
dd 0E0000020h             ; attributes: readable, writable, executable, etc
db 200h-$ dup(0)          ; proceed to 200h/1000h

one:                      ; code:
push 0 @f+400E00h @f+400E00h 0
call dword [MessageBox+400E00h]
push 0
call dword [ExitProcess+400E00h]
@@: db 'EXAMPLE', 0       ; data:

it:                       ; import table
dd 0,0,0, kernel_name+0E00h, kernel_table+0E00h
dd 0,0,0, user_name+0E00h, user_table+0E00h
dd 0,0,0,0,0
kernel_name db 'KERNEL32.DLL', 0
kernel_table:
ExitProcess dd _ExitProcess+0E00h
dd 0
_ExitProcess db 0, 0, 'ExitProcess', 0
user_name db 'USER32.DLL', 0
user_table:
MessageBox dd _MessageBox+0E00h
dd 0
_MessageBox db 0, 0, 'MessageBoxA', 0
one_end:
align 200h
exe_end:    
Post 04 Aug 2006, 05:54
View user's profile Send private message Reply with quote
karl



Joined: 07 Feb 2006
Posts: 63
Location: South Africa
karl
wicked project, babyboy. i suddenly understand so much i didn't before. and for me the best thing is that you showed me how to use the win32 api without complex macros! yay!

some questions:

push 0 @f+400E00h @f+400E00h 0
what is @f? and what is 400E00h?

dd 0,0,0, kernel_name+0E00h, kernel_table+0E00h
what is 0E00h?

hmmm... i'm guesssing i could find that out by looking at .exe definition docs. if i understand. but then why call dword [MessageBox+400E00h] ?? what is the 400E00h?

so cool, man, so cool... thanks for posting it for everyone.
fasm truely is the best assembler! in fact, it's the best programming environment ever!!
Post 07 Aug 2006, 10:03
View user's profile Send private message Reply with quote
okasvi



Joined: 18 Aug 2005
Posts: 382
Location: Finland
okasvi
Quote:
push 0 @f+400E00h @f+400E00h 0
what is @f? and what is 400E00h?


read manual about anonymous labels, @f refers to @@: db 'EX... after call.
and 400E00h is imagebase+?????
Post 07 Aug 2006, 11:30
View user's profile Send private message MSN Messenger Reply with quote
karl



Joined: 07 Feb 2006
Posts: 63
Location: South Africa
karl
thanks okasvi, i'll look that stuff up....
Post 07 Aug 2006, 11:51
View user's profile Send private message Reply with quote
karl



Joined: 07 Feb 2006
Posts: 63
Location: South Africa
karl
for anyone interested: http://www.x86.org/ftp/manuals/tools/pe.pdf
good info.
Post 07 Aug 2006, 12:05
View user's profile Send private message Reply with quote
Fady



Joined: 13 Nov 2006
Posts: 4
Location: Cairo, Egypt
Fady
This is just perfect.

Thanks babyboy!
Post 26 Dec 2006, 05:01
View user's profile Send private message Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan
actually alignment macro works bad, i pointed that problem to Tomasz
Code:
db 0 dup (90h)
    

wrong value - 0.
But code
Code:
rb 0
    

is good.

_________________
Any offers?
Post 26 Dec 2006, 12:54
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
"babyboy10777" wrote:
Quote:
Here's the finished, working template. It runs perfect. Just replace .bin extension with .exe.

This is great. Works for me. Could not resist to run it in DOS also Laughing - works,
with some limitations. One just shouldn't run it unpatched - it freezes then,
unsurprisingly.

Fixed freezer problem, discussion continues here:

http://board.flatassembler.net/topic.php?t=6735

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 27 Dec 2006, 03:50
View user's profile Send private message 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.