flat assembler
Message board for the users of flat assembler.

Index > Windows > Create PE from scratch

Author
Thread Post new topic Reply to topic
LiuJunfeng



Joined: 28 Nov 2003
Posts: 48
Location: China
LiuJunfeng 26 Mar 2004, 13:42
You can creat a PE file in this way:
Code:
;pe.asm
;-- a program for learning PE format
;note: the code below is not flexible enough
;you can try to improve it if you like
;Liu Junfeng

DOS_Header:
   .e_magic  dw "MZ"      ;IMAGE_DOS_SIGNATURE
   .e_cblp       dw 0x0080
   .e_cp   dw 0x0001
   .e_crlc dw 0x0000
   .e_cparhdr      dw 0x0004
   .e_minalloc     dw 0x0010
   .e_maxalloc     dw 0xFFFF
   .e_ss   dw 0x0000
   .e_sp   dw 0x0140
   .e_csum dw 0x0000
   .e_ip   dw 0x0000
   .e_cs   dw 0x0000
   .e_lfarlc       dw 0x0040
   .e_ovno dw 0x0000
   .e_res  rw 4
   .e_oemid     dw 0x0000
   .e_oeminfo      dw 0x0000
   .e_res2 rw 10
   .e_lfanew   dd PE_header  ;PE header Offset

DOS_Stub:
 org 0
 use16
   push cs
   pop ds
   mov dx,msg
   mov ah,9h
   int 21h
   mov ax,4C01h
   int 21h
   msg:
   db "this program cannot be run in DOS mode.",13,10,"$"
 org $+DOS_Stub

rb 0x80 - $   ;$ equal to curent offset

Parameters:
NS = 3         ;NumberOfSections
BA = 0x400000  ;Base Address
SA = 0x1000    ;SectionAlignment
FA = 0x0200    ;FileAlignment

PE_header:
   .Signature               dd "PE"
   FileHeader:
     .Machine                dw 0x014C             ;i386
     .NumberOfSections           dw NS
     .TimeDateStamp    dd %t
     .PointerToSymbolTable dd 0
     .NumberOfSymbols       dd 0
     .SizeOfOptionalHeader dw SectionTable-OptionalHeader
     .Characteristics      dw 0x818F             ;
   OptionalHeader:                             ;OptionalHeader has 31 fields
     .Magic                  dw 0x010B             ;PE32
     .MajorLinkerVersion       db 1                    ;1.51
     .MinerLinkerVersion       db 51
     .SizeOfCode         dd 0
     .SizeOfInitializedData    dd 0
     .SizeOfUnInitializedData  dd 0
     .AddressOfEntryPoint      dd CodeSection
     .BaseOfCode         dd 0
     .BaseOfData        dd 0
     .ImageBase         dd BA
     .SectionAlignment         dd SA
     .FileAlignment            dd FA
     .MajorOSVersion           dw 1                  ;1.0
     .MinorOSVersion              dw 0
     .MajorImageVersion        dw 0                   ;0.0
     .MinorImageVersion        dw 0
     .MajorSubSystemVerion     dw 4              ;4.0
     .MinorSubSystemVerion     dw 0
     .Win32VersionValue        dd 0              ;Reserved
     .SizeOfImage            dd SA*(NS+1)             ;16384 bytes
     .SizeOfHeaders            dd SizeOfHeaders
     .CheckSum                      dd 0x6B94
     .SubSystem            dw 2                  ;Win32 GUI
     .DllCharacteristics       dw 0
     .SizeOfStackReserve       dd 0x1000
     .SizeOfStackCommit        dd 0x1000
     .SizeOfHeapReserve        dd 0x10000
     .SizeOfHeapRCommit        dd 0
     .LoaderFlags        dd 0                  ;Obsolete
     .NumberOfDataDirectories  dd 16

     Data_Directories:
       .Export_Table              dd 0,0              ; Rva,Size
       .Import_Table          dd ImportSection,0x80      ; Rva,Size
       .Resource_Table         dd 0,0              ; Rva,Size
       .Exception_Table       dd 0,0  ; Rva,Size
       .Certificate_Table     dd 0,0  ; Rva,Size
       .Relocation_Table      dd 0,0  ; Rva,Size
       .Debug_Data        dd 0,0  ; Rva,Size
       .Architecture              dd 0,0  ; Rva,Size
       .Global_PTR        dd 0,0  ; Rva,Size
       .TLS_Table         dd 0,0  ; Rva,Size
       .Load_Config_Table     dd 0,0  ; Rva,Size
       .BoundImportTable      dd 0,0  ; Rva,Size
       .ImportAddressTable    dd 0,0  ; Rva,Size
       .DelayImportDescriptor dd 0,0  ; Rva,Size
       .COMplusRuntimeHeader  dd 0,0  ; Rva,Size
       .Reserved              dd 0,0  ; Rva,Size

SectionTable:
  Section1:
    .Name                   dq ".data"
    .VirtualSize        dd 0x33
    .VirtaulAddress          dd DataSection
    .SizeOfRawData            dd SizeOfData
    .PointerToRawData          dd PointerToData
    .PointerToRelocations   dd 0
    .PointerToLinenumbers   dd 0
    .NumberOfRelocations    dw 0
    .NumberOfLinenumbers    dw 0
    .Characteristics        dd 0xC0000040        ;INITIALIZED_DATA+MEM_READ+MEM_WRITE
  Section2:
    .Name               dq ".code"
    .VirtualSize        dd 0x1C
    .VirtaulAddress          dd CodeSection
    .SizeOfRawData            dd SizeOfCode
    .PointerToRawData          dd PointerToCode
    .PointerToRelocations   dd 0
    .PointerToLinenumbers   dd 0
    .NumberOfRelocations    dw 0
    .NumberOfLinenumbers    dw 0
    .Characteristics        dd 0x60000020        ;CODE+MEM_READ+MEM_EXECUTE
  Section3:
    .Name                 dq ".idata"
    .VirtualSize       dd 0x80
    .VirtaulAddress          dd ImportSection
    .SizeOfRawData          dd SizeOfImport
    .PointerToRawData        dd PointerToImport
    .PointerToRelocations   dd 0
    .PointerToLinenumbers   dd 0
    .NumberOfRelocations    dw 0
    .NumberOfLinenumbers    dw 0
    .Characteristics      dd 0xC0000040        ;INITIALIZED_DATA+MEM_READ+MEM_WRITE

SizeOfHeaders = 0x200
rb SizeOfHeaders - $
RawData:

PointerToData:
org  SA
DataSection:

.MsgCaption db "Iczelion's tutorial no. 2",0
.MsgBoxText db "Win32 Assembly is Great!",0

SizeOfData = FA
rb  SizeOfData - ($-DataSection)

PointerToCode = PointerToData + SizeOfData
org  SA*2
CodeSection:

use32
push 0x40                                ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
push dword DataSection.MsgCaption+BA           ; |Title = "Iczelion's tutorial no. 2"
push dword DataSection.MsgBoxText+BA       ; |Text = "Win32 Assembly is Great!"
push 0                                        ; |hOwner = NULL
call dword [DS:ImageImportByName2+BA]           ; \MessageBoxA
push 0                                       ; /ExitCode = 0
call dword [DS:ImageImportByName1+BA]    ; \ExitProcess

SizeOfCode = FA
rb SizeOfCode - ($-CodeSection)

PointerToImport = PointerToCode + SizeOfCode
org  SA*3
ImportSection:

  ImageImportDescriptor1:
    .OriginalFirstThunk  dd  0x00000000
    .TimeDateStamp        dd  0x00000000  ;(GMT: Thu Jan 01 00:00:00 1970)
    .ForwarderChain     dd  0x00000000
    .Name             dd  DllNames.DllName1  ;=0x0000303C RVA to "KERNEL32.DLL"
    .FirstThunk          dd  ImageImportByName1 ;=0x00003054
                                                       ;pointer(RVA)to an IMAGE_IMPORT_BY_NAME struct
 ImageImportDescriptor2:
    .OriginalFirstThunk  dd  0x00000000
    .TimeDateStamp   dd  0x00000000  ;(GMT: Thu Jan 01 00:00:00 1970)
    .ForwarderChain     dd  0x00000000
    .Name             dd  DllNames.DllName2  ;=0x00003049 RVA to "USER32.DLL"
    .FirstThunk    dd  ImageImportByName2 ;=0x0000306A
                                                       ;pointer(RVA)to an IMAGE_IMPORT_BY_NAME struct
 ImageImportDescriptor3:   ;end of ImageImportDescriptor array by all NULL values
    .OriginalFirstThunk  dd 0
    .TimeDateStamp    dd 0
    .ForwarderChain     dd 0
    .Name               dd 0
    .FirstThunk         dd 0

  DllNames:
    .DllName1            db "KERNEL32.DLL",0
    .DllName2          db "USER32.DLL",0
  ImageImportByName1:
    .ThunkValue     dd .Hint, 0
    .Hint    dw    0x0000
    .Name    db    "ExitProcess",0
  ImageImportByName2:
    .ThunkValue        dd .Hint, 0
    .Hint    dw    0x0000
    .Name    db    "MessageBoxA",0

SizeOfImport = FA
rb SizeOfImport - ($-ImportSection) - 1
db 0
;----------------------------------------------------------------
    

After compile, you will get the same output as the following code:
Code:
; MsgBox example: FASMW version

format PE GUI 4.0
entry start
include '%fasminc%/win32a.inc'
section '.data' data readable writeable
  _MsgCaption      db "Iczelion's tutorial no. 2",0
  _MsgBoxText      db "Win32 Assembly is Great!",0
section '.code' code readable executable
  start:
        invoke  MessageBox, HWND_DESKTOP,\
               _MsgBoxText, _MsgCaption, MB_ICONINFORMATION+MB_OK
  exit:
        invoke  ExitProcess, 0
section '.idata' import data readable writeable
  library kernel32,'KERNEL32.DLL', user32,'USER32.DLL'
  import kernel32, ExitProcess,'ExitProcess'
  import user32, MessageBox,'MessageBoxA' 
    

Only the DateTimeStamp and Checksum may be different.
But now you know what's PE format and what does the compiler do to create the file.
Post 26 Mar 2004, 13:42
View user's profile Send private message Reply with quote
ShortCoder



Joined: 07 May 2004
Posts: 105
ShortCoder 01 Jun 2004, 18:13
Thank you for providing a very useful and very educational piece of code there.Very Happy

_________________
Boycott Symantec/Norton/PowerQuest whenever possible
Post 01 Jun 2004, 18:13
View user's profile Send private message Reply with quote
khanh



Joined: 25 Jul 2003
Posts: 27
khanh 01 Jun 2004, 19:20
Shocked If y know anythings about other pieces of code like that for linux format...
Can you post them here, I'm very interested in this. It shows me how my coding are actually translated?

Keep good work! Idea
Post 01 Jun 2004, 19:20
View user's profile Send private message Reply with quote
gorshing



Joined: 27 Jul 2003
Posts: 72
Location: Okla, US
gorshing 02 Jun 2004, 19:25
Thanks LiuJunfeng

I was curious of what resources helped you come up with the above code.

Thanks again,

_________________
gorshing
Post 02 Jun 2004, 19:25
View user's profile Send private message Visit poster's website Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy 02 Jun 2004, 19:58
BTW: you can use %T to get the time stamp... Wink
Post 02 Jun 2004, 19:58
View user's profile Send private message Visit poster's website Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 09 Sep 2004, 06:34
Quote:

Code:
DOS_Stub: 
 org 0 
 use16 
   push cs 
   pop ds 
   mov dx,msg 
   mov ah,9h 
   int 21h 
    


could somebody explain to me, why we need to ORG 0 here?

according to iczelion''s PE Tutorial 1,
Quote:

The DOS stub is actually a valid EXE that is executed in case the operating system doesn't know about PE file format.


since it is a valid exe, why it doesn't need the PSP? and ORG in 0x100?
Post 09 Sep 2004, 06:34
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 09 Sep 2004, 07:59
My *theory* is that this big file (512*x Bytes) is mapped differently and the program (DOS_Stub) actually lays on the bottom of memory so you can run it directly.

^o) I have come to an idea that we could programme that DOS_Stub Smile
We jump to a location in code where we are writing 16bit code while we are
actually programing in 32bit. So the output differs in Win32/DOS.
Post 09 Sep 2004, 07:59
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard 09 Sep 2004, 08:02
It has a PSP too (IIRC it's location is pointed by ES at startup). Only COM exectuables are having PSP in the beginning of the segment (org 0), so the actual executable starts at org 0x100.
Post 09 Sep 2004, 08:02
View user's profile Send private message Visit poster's website Reply with quote
mike.dld



Joined: 03 Oct 2003
Posts: 235
Location: Belarus, Minsk
mike.dld 09 Sep 2004, 10:05
Is there any limitations on then size of stub?
Post 09 Sep 2004, 10:05
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
silkodyssey



Joined: 02 Oct 2003
Posts: 198
Location: St.Vincent & the Grenadines
silkodyssey 09 Sep 2004, 10:44
This code is a lot easier to read and understand than a lot of other PEs from scratch that I have seen. Smile

_________________
silkodyssey
Post 09 Sep 2004, 10:44
View user's profile Send private message MSN Messenger Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 09 Sep 2004, 17:20
does PSP exists for 32 bit executable loading ?
Post 09 Sep 2004, 17:20
View user's profile Send private message Visit poster's website Reply with quote
polygon7



Joined: 14 Aug 2003
Posts: 62
Location: Poznan, Poland
polygon7 09 Sep 2004, 20:28
mike.dld wrote:
Is there any limitations on then size of stub?

Minimum size of "working" (*.exe file run corectly on Windows, but you
shouldn't run this at DOS) stub is 10 bytes:
Code:
dw 'MZ'
rb 8    


10 bytes stub looks like that:
Code:
Parameters:
NS = 1              ;NumberOfSections
BA = 0x400000  ;Base Address
SA = 0x1000    ;SectionAlignment
FA = 0x0200    ;FileAlignment

DOS_Header:
   .e_magic     dw "MZ"      ;IMAGE_DOS_SIGNATURE
         dw 0x0090
   .dll    dd "d3d8"
   .hInstance    dd BA
PE_header:
   .Signature                   dd "PE"
   FileHeader:
     .Machine                dw 0x014C             ;i386
     .NumberOfSections           dw NS
;;;;;;;;;;;;;;
     .TimeDateStamp          dd %t
     .PointerToSymbolTable dd 0         ; 4 \ 8b
     .NumberOfSymbols     dd 0         ; 4 /
;;;;;;;;;;;;;;

     .SizeOfOptionalHeader dw SectionTable-OptionalHeader
     .Characteristics          dw 0x818F             ;
   OptionalHeader:                             ;OptionalHeader has 31 fields
     .Magic                  dw 0x010B         ;PE32

;;;;;;;;;;;;;;
     .LinkerVersion            dw 0             ; 2  \
     .SizeOfCode            dd 0             ; 4   \ 14b
     .SizeOfInitializedData    dd 0             ; 4   /
     .SizeOfUnInitializedData  dd 0          ; 4  /
;;;;;;;;;;;;;;

     .AddressOfEntryPoint      dd CodeSection
     .BaseOfCode              dd 0
     .BaseOfData        dd PE_header
     .ImageBase         dd BA
     .SectionAlignment         dd SA
     .FileAlignment            dd FA
    

I dont know about maximum size of stub.

_________________
best regards
p7
Post 09 Sep 2004, 20:28
View user's profile Send private message Visit poster's website Reply with quote
vbVeryBeginner



Joined: 15 Aug 2004
Posts: 884
Location: \\world\asia\malaysia
vbVeryBeginner 16 Sep 2004, 09:06
Code:
IMAGE_DOS_HEADER:                         ;start : 00 (0) to 3F (63)
       .e_magic      dw     0x5A4D        ;00 01
       .e_cblp       dw     0x0080        ;02 03
       .e_cp         dw     0x0001        ;04 05
       .e_crlc       dw     0x0000        ;06 07
       .e_cparhdr    dw     0x0004        ;08 09
       .e_minalloc   dw     0x0010        ;10 11
       .e_maxalloc   dw     0xFFFF        ;12 13
       .e_ss         dw     0x0000        ;14 15
       .e_sp         dw     0x0140        ;16 17
       .e_csum       dw     0x0000        ;18 19
       .e_ip         dw     0x0000        ;20 21
       .e_cs         dw     0x0000        ;22 23
       .e_lfarlc     dw     0x0040        ;24 25
       .e_ovno       dw     0x0000        ;26 27
       .e_res        rw     4             ;28 29 | 30 31 | 32 33 | 34 35
       .e_oemid      dw     0x0000        ;36 37
       .e_oeminfo    dw     0x0000        ;38 39
       .e_res2       rw     10            ;40 41 | 42 43 | 44 45 | 46 47 | 48 49 | 50 51
       .e_lfanew     dd     0x00000080    ;52 53 | 54 55 | 56 57 | 58 59
                                          ;60 61 62 63
;=====================================================================================================
DOS_STUB:                          ;start : 40 (64) to 7F (127)
       use16                       ;DOS-STUB is a 16-bit program
                                   ;push  cs <- we save 1 byte here
                                   ;pop   ds <- we save another 1 byte here
                                   ;our DS is less 100h from CS, DS received PSP address
       mov    dx,0x100 + 0x0B      ;our db message starts at 0x0B because we save 3 bytes already
       mov    ah,0x9
       int    0x21
       mov    ah,0x4C              ;save 1 byte here because we need to use AH only for function
       int    0x21
       
       db     'This program cannot be run in DOS mode.',13,10,'$'

       rb     0x80 - $             ;0x80 - 0x75 = rb 0xB
;=====================================================================================================
IMAGE_NT_HEADERS:                                ;start : 80 (128) to 1EF (495)
       .Signature           db     'PE',0,0      ;128 131
       

       IMAGE_FILE_HEADER:                        ;start : 84 (132) to 97 (151)
              .Machine                           dw     0x014C        ;132 133 for intel 386
              .NumberOfSection                   dw     0x0003        ;134 135
              .TimeDateStamp                     dd     %t            ;136 139
              .PointerToSymbolTable              dd     0             ;140 143
              .NumberOfSymbols                   dd     0             ;144 147
              .SizeOfOptionalHeader              dw     0x00E0        ;148 149
              .Characteristic                    dw     0x818F        ;150 151
       

       IMAGE_OPTIONAL_HEADER:                    ;start : 98 (152) to F7 (247) * till IMAGE_DATA_DIRECTORY
                                                                      ;offset
              .Magic                             dw     0x010B        ;152 153
              .MajorLinkerVersion                db     0x01          ;154
              .MinorLinkerVersion                db     0x37          ;155
              .SizeOfCode                        dd     0             ;156 159
              .SizeOfInitializedData             dd     0             ;160 163
              .SizeOfUninitializedData           dd     0             ;164 167
              .AddressOfEntryPoint               dd     0x2000        ;168 171 = base + 2000 = 402000 (.code section)
              .BaseOfCode                        dd     0             ;172 175
              .BaseOfData                        dd     0             ;176 179
              .ImageBase                         dd     0x00400000    ;180 183 (default)
              .SectionAlignment                  dd     0x00001000    ;184 187 4096 bytes
              .FileAlignment                     dd     0x00000200    ;188 191 512 bytes (default)
              .MajorOperatingSystemVersion       dw     1             ;192 193
              .MinorOperatingSystemVersion       dw     0             ;194 195
              .MajorImageVersion                 dw     0             ;196 197
              .MinorImageVersion                 dw     0             ;198 199
              .MajorSubsystemVersion             dw     4             ;200 201
              .MinorSubsystemVersion             dw     0             ;202 203
              .Win32VersionValue                 dd     0             ;204 207
              .SizeOfImage                       dd     0x00004000    ;208 211
              .SizeOfHeaders                     dd     0x00000200    ;212 215
              .CheckSum                          dd     0x0000EF20    ;216 219
              .Subsystem                         dw     2             ;220 221 IMAGE_SUBSYSTEM_WINDOWS_GUI
              .DllCharacteristics                dw     0             ;222 223
              .SizeOfStackReserve                dd     0x00001000    ;224 227 4096 bytes
              .SizeOfStackCommit                 dd     0x00001000    ;228 231 4096 bytes
              .SizeOfHeapReserve                 dd     0x00100000    ;232 235 1048576 bytes
              .SizeOfHeapCommit                  dd     0             ;236 239
              .LoaderFlags                       dd     0             ;240 243
              .NumberOfRvaAndSizes               dd     0x10          ;244 247 16 decimal
              
              IMAGE_DATA_DIRECTORY:              ;start : F8 (248) to 177 (375) * till IMAGE_SECTION_TABLE
                     rq     1                    ;248 255
                     .ImportTableVA              dd     0x00003000           ;256 263
                     .ImportTableSize            dd     0x00000090
                     rq     14                   ;we don't need them also    ;263 + 112 = 375

              IMAGE_SECTION_TABLE:                                           ;start : 178 (376) to 1EF (495)
                     SECTION_1:
                            .Name                       dq     '.data'       ;start : 178 (376)
                            .VirtualSize                dd     0x0000001D
                            .VirtualAddress             dd     0x00001000    ;-> in memory, it is 401000
                            .SizeOfRawData              dd     0x00000200 
                            .PointerToRawData           dd     0x00000200    ;-> in our file, it is 0x200 (512) (offset from zero)
                            .PointerToRelocations       dd     0
                            .PointerToLineNumbers       dd     0
                            .NumberOfRelocations        dw     0
                            .NumberOfLineNumbers        dw     0
                            .Characteristic             dd     0xC0000040    ;end   : 19F (415)
                     SECTION_2:
                            .Name                       dq     '.code'       ;start : 1A0 (416)
                            .VirtualSize                dd     0x0000001C
                            .VirtualAddress             dd     0x00002000    ;-> in memory, it is 402000
                            .SizeOfRawData              dd     0x00000200
                            .PointerToRawData           dd     0x00000400    ;-> in our file, it is 0x400 (1024) (offset from zero)
                            .PointerToRelocations       dd     0
                            .PointerToLineNumbers       dd     0
                            .NumberOfRelocations        dw     0
                            .NumberOfLineNumbers        dw     0
                            .Characteristic             dd     0x60000020    ;end   : 1C7 (455)
                     SECTION_3:
                            .Name                       dq     '.idata'      ;start : 1C8 (456)
                            .VirtualSize                dd     0x00000090
                            .VirtualAddress             dd     0x00003000    ;-> in memory, it is 403000
                            .SizeOfRawData              dd     0x00000200
                            .PointerToRawData           dd     0x00000600    ;-> in our file, it is 0x600 (1536) (offset from zero)
                            .PointerToRelocations       dd     0
                            .PointerToLineNumbers       dd     0
                            .NumberOfRelocations        dw     0
                            .NumberOfLineNumbers        dw     0
                            .Characteristic             dd     0x40000040    ;end   : 1EF (495)
;                                                                                      |
;our SECTION_1 <PointerToRawData> points at 0x200 or (512) bytes from zero             |
;since we are currently in file offset 1EF  -------------------------------------------+
;we need to "rb 0xF" or "rq 2" so that our address from 1F0 to 1FF are filled.
                     rq     2                                                ;start : 1F0 (496) to 1FF (511)
                     
                     ;file offset   = 0x200
                     ;memory offset = 0x401000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_1.VirtualAddress)
                     ;=========================================================================================
                     SECTION_1_RAW_DATA:                                     ;start : 200 (512) to 3FF (1023)
                     org 0x401000
                            msgText       db     'Message Text',0            ;\  ;512 524 
                                                                             ; } we use 1D (29) bytes here
                            msgCaption    db     'Message Caption',0         ;/  ;525 540
                            
                            ; 541 to 1023 should be filled
                            ; (1023 - 541) + 1 = 483 bytes
                            
                            ; we NEED to + 1 because 1023 is not INCLUDED when
                            ; we use it to minus 541.
                            rb     483                         ;because our .code raw data start at 400 (1024)
                                                               ;and because our IMAGE_OPTIONAL_HEADER > FileAlignment is 0x200 (512) bytes

                     ;file offset   = 0x400
                     ;memory offset = 0x402000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_2.VirtualAddress)
                     ;=========================================================================================
                     org 0x2000
                     SECTION_2_RAW_DATA:                                            ;start : 400 (1024) to 5FF (1535)
                            use32                                                   ;we are using 32-bit instruction
                            push   0x40                 ;6A 40                      ;MB_OK + MB_ICONASTERIK + MB_APPLMODAL
                            push   msgCaption           ;68 0D 10 40 00             ;push msgCaption
                            push   msgText              ;68 00 00 40 00             ;push msgText
                            push   0                    ;6A 00                      ;push HWND_DESKTOP
                            call   dword [0x0040307A]   ;FF 15 7A 30 40 00          ;call MessageBoxA
                            push   0                    ;6A 00                      ;push zero for ExitProcess parameter
                            call   dword [0x0040305C]   ;FF 15 5C 30 40 00          ;call ExitProcess
                            
                            ;we have used 1C (2Cool bytes here
                            ;1052 to 1535 should be filled
                            ;(1535 - 1052) + 1 = 484 bytes
                            rb     484

                     ;file offset   = 0x600
                     ;memory offset = 0x403000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_3.VirtualAddress)
                     ;=========================================================================================
                     org 0x3000
                     SECTION_3_RAW_DATA:                                     ;start : 600 (1536) to 7FF (2047)
                            IMAGE_IMPORT_DESCRIPTOR_1:
                                   .OriginalFirstThunk  dd     0x00003054    ;3000 3003
                                   .TimeDateStamp       dd     0             ;3004 3007
                                   .ForwarderChain      dd     0             ;3008 300B
                                   .Name                dd     0x0000303C    ;300C 300F
                                   .FirstThunk          dd     0x0000305C    ;3010 3013
                            IMAGE_IMPORT_DESCRIPTOR_2:
                                   .OriginalFirstThunk  dd     0x00003072    ;3014 3017
                                   .TimeDateStamp       dd     0             ;3018 301B
                                   .ForwarderChain      dd     0             ;301C 301F
                                   .Name                dd     0x00003049    ;3020 3023
                                   .FirstThunk          dd     0x0000307A    ;3024 3027
                            
                                          ;terminated with IMAGE_IMPORT_DESCRIPTIOR that filled with 0 zeros
                            rd     5      ;the structure size of IMAGE_IMPORT_DESCRIPTOR
                                                                             ;3028 to 303B
                            
                     ;Our DLL Name
                     .KERNEL32     db     'KERNEL32.DLL',0                   ;303C to 3048
                     .USER32       db     'USER32.DLL',0                     ;3049 to 3053

                     IMAGE_THUNK_DATA32_1:
                            .ForwarderString     dd     0x00003064           ;3054 3057
                            .Function            dd     0                    ;3058 305B
                            .Ordinal             dd     0x00003064           ;305C 305F
                            .AddressOfData       dd     0                    ;3060 3063

                            IMAGE_IMPORT_BY_NAME_1:
                                   .Hint         dw     0                    ;3064 3065
                                   .Name         db     'ExitProcess',0      ;3066 3071

                     IMAGE_THUNK_DATA32_2:
                            .ForwarderString     dd     0x00003082           ;3072 3075
                            .Function            dd     0                    ;3076 3079
                            .Ordinal             dd     0x00003082           ;307A 307D
                            .AddressOfData       dd     0                    ;307E 3081

                            IMAGE_IMPORT_BY_NAME_2:
                                   .Hint         dw     0                    ;3082 3083
                                   .Name         db     'MessageBoxA',0      ;3084 308F

                     ;308F = 143 bytes used
                     ;must filled 2047 - (1536 + 143) = 368 + 1 = 369 bytes
                     rb 367
                     db 0
    


hopefully, this could be another reference for beginner (like me) to learn Smile
Post 16 Sep 2004, 09:06
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 15 Dec 2006, 11:36
here is another PE from scratch:
http://board.flatassembler.net/topic.php?t=1694
Post 15 Dec 2006, 11:36
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 15 Dec 2006, 19:34
Here is another one (which is the most recent that I remember, anyways):

Writing .EXEs Manually (babyboy10777)
Post 15 Dec 2006, 19:34
View user's profile Send private message Visit poster's website Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan 16 Dec 2006, 17:52
And pointing to a small thing - ORG - in DOS stub - it should be ORG 100h, cuz stub is just old COM proggy (do not confuse with COM technology). Just write ORG 100h and forget about adding 100 to RVA of labels e.g.
Code:
mov    dx,0x100 + 0x0B    

_________________
Any offers?
Post 16 Dec 2006, 17:52
View user's profile Send private message Reply with quote
charli



Joined: 07 Mar 2007
Posts: 1
charli 07 Mar 2007, 18:02
I found this tut for making a valid PE file with a hexditor and Ollydbg

http://www.tuts4you.com/blogs/download.php?view.1225
Post 07 Mar 2007, 18:02
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1900
DOS386 07 Mar 2007, 18:22
Quote:
Here is another one (which is the most recent


No longer ...

http://board.flatassembler.net/topic.php?t=6735 (In MAIN)

someone puts them ALL into FAQ ?

Quote:

And pointing to a small thing - ORG - in DOS stub - it should be ORG 100h, cuz stub is just old COM proggy


WRONG. It is a MZ DOS executable, and needs ORG 0.

_________________
Bug Nr.: 12345

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

Status: Closed: NOT a Bug
Post 07 Mar 2007, 18:22
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.