flat assembler
Message board for the users of flat assembler.

Index > Main > easy manual pe32 creation

Author
Thread Post new topic Reply to topic
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 01 Nov 2010, 19:33
Hi people.
I just wanted to share this file.
Really tired writing\counting lots of numbers - not here :)
There'd been lots of sources i've seen and many of those were hard coded.
Saying again - not here as internal structure fixes all that.
Actually PE format is known about a week to me and i'm eager helping(naive? - no wtf i'm sorry!).
Also lots of documents - those are often different as format creators are :)

Still there are good docs:
1. www.google.com, look for MS docs studying structures
2. lots of good and lots of stump: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v8.docx
3. download file

Well, here it is(pe - enu.asm).
Where would IMAGE_DOS_HEADER.MinimumextraParagraphs stay?
Is the stub valid?
Code:
;Manual PE32 creation example.
;Check next fields whenever changing this source:
;- IMAGE_OPTIONAL_HEADER.SizeOfImage
;- SECTION_X.Rva
format binary as 'exe'


SCRATCH:
macro padzero value*{db (value - $ and (value-1)) mod (value) dup 0}

macro m1 section{
  ;increase sections counter(see below)
  load a word from IMAGE_FILE_HEADER.NumberOfSections
  store word a+1 at IMAGE_FILE_HEADER.NumberOfSections
  ;defines 2 often usable constants(see below)
  load a dword from section#.Rva
  section#_RVA  = a - section#_RAW
  section#_BASE = IMAGE_BASE + section#_RVA
}


DISK_SECTOR = $0000'0200                                        ;0'000'512
PAGE        = $0000'1000                                        ;0'004'096
IMAGE_BASE  = $0040'0000                                        ;4'194'304


use16
org 0
IMAGE_DOS_HEADER:
  .Signature                  dw 'MZ'
  .BytesOnLastPage            dw 64                             ;page = 512 bytes
  .PagesInFile                dw 1
  .Relocations                dw 0
  .SizeOfHeaderInParagraphs   dw 64/16                          ;paragraph = 16 bytes
  .MinimumExtraParagraphs     dw 0
  .MaximumExtraParagraphs     dw 0
  .InitialRelativeSS          dw 0
  .InitialSP                  dw 64
  .Checksum:                  int $20                           ;exit to DOS
  .InitialIP                  dw .Checksum
  .InitialRelativeCS          dw 0
  .OffsetToRelocationTable    dw 0
  .OverlayNumber              dw 0
  .Reserved1                  dw 4 dup 0
  .OEMIdentifier              dw 0                              ;)
  .OEMInformation             dw 0                              ;)
  .Reserverd2                 dw 10 dup 0
  .OffsetToNewEXEHeader       dd 64                             ;IMAGE_NT_HEADERS


IMAGE_NT_HEADERS:
  .Signature                  dd 'PE'


  IMAGE_FILE_HEADER:
    .Machine                  dw $014c                          ;i386 and over required
    .NumberOfSections         dw 0                              ;sections counter, MACRO FILLS THIS ITSELF
    .TimeDateStamp            dd %t                             ;seconds passed since 1970_01_01, 00:00
    .PointerToSymbolTable     dd 0
    .NumberOfSymbols          dd 0
    .SizeOfOptionalHeader     dw IMAGE_SECTION_HEADER-\         ;sizeof.IMAGE_OPTIONAL_HEADER
                                 IMAGE_OPTIONAL_HEADER
    .Characteristics          dw $0002                          ;this is an executable file


  IMAGE_OPTIONAL_HEADER:
    .Magic                    dw $010b                          ;32'bit
    .MajorLinkerVersion       db 0                              ;composer mark
    .MinorLinkerVersion       db 0                              ;...put smiles
    .SizeOfCode               dd 0
    .SizeOfInitializedData    dd 0
    .SizeOfUninitializedData  dd 0
    .AddressOfEntryPoint      dd PAGE+\                         ;PAGE(=.SectionAlignment); 1st section(being loaded to RAM) displacement relatively IMAGE_DOS_HEADER(=0)
                                 entry_point-SECTION_1_RAW      ;entry point
    .BaseOfCode               dd 0
    .BaseOfData               dd 0
    .ImageBase                dd IMAGE_BASE                     ;image load base; image starts at IMAGE_DOS_HEADER :)
    .SectionAlignment         dd PAGE                           ;sections will be aligned to this value on the load stage
    .FileAlignment            dd DISK_SECTOR                    ;section alignment in physical file
    .MajorOSVersion           dw 0
    .MinorOSVersion           dw 0
    .MajorImageVersion        dw 0                              ;smth
    .MinorImageVersion        dw 0                              ;yours
    .MajorSubsystemVersion    dw 4
    .MinorSubsystemVersion    dw 0
    .Win32VersionNumber       dd 0
    .SizeOfImage              dd PAGE*3                         ;size of image(including headers), reflected to RAM; rounded to .SectionAlignmnent
    .SizeOfHeaders            dd SECTION_1_RAW                  ;1st section displacement rounded to .FileAlignment
    .Checksum                 dd 0
    .Subsystem                dw 2                              ;win graphical user interface
    .Characteristics          dw 0
    .SizeOfStackReserve       dd 1024*1024                      ;stack space
    .SizeOfStackCommit        dd 0
    .SizeOfHeapReserve        dd 1024*1024                      ;heap space
    .SizeOfHeapCommit         dd 0
    .LoaderFlags              dd 0
    .NumberOfDataDirectories  dd 16                             ;numbers of pointers to (predefined) sections:

    .ExportTableRvaAndSize    dq 0                              ;1, export
    .ImportTableRvaAndSize    dd PAGE,\                         ;2, import, we'll use some
                                 0;entry_point-SECTION_1_RAW
    times 14 dq 0                                               ;3..16


  IMAGE_SECTION_HEADER:
    SECTION_1:
      .Name                   dq ''                             ;section name, eg 'tody' or 'body'
      .VirtualSize            dd 0
      .Rva                    dd PAGE                           ;mind .SectionAlignment ie any section's 1st byte's address
      .SizeOfRawData          dd SECTION_1_RAW.-SECTION_1_RAW   ;physical data size, align sections to .FileAlignment
      .PointerToRawData       dd SECTION_1_RAW                  ;physical data pointer, align sections to .FileAlignment
      .PointerToRelocations   dd 0
      .PointerToLineNumbers   dd 0
      .NumberOfRelocations    dw 0
      .NumberOfLineNumbers    dw 0
      .Characteristics        dd $0000'0020+\                   ;code
                                 $2000'0000+\                   ;executable
                                 $4000'0000+\                   ;readable
                                 $8000'0000                     ;writable
      m1 SECTION_1                                              ;great!
    SECTION_2:
      .Name                   dq 'section2'
      .VirtualSize            dd 0
      .Rva                    dd PAGE*2                         ;see, we are skipping 1st section's alignment and 1st section itself
      .SizeOfRawData          dd SECTION_2_RAW.-SECTION_2_RAW
      .PointerToRawData       dd SECTION_2_RAW
      .PointerToRelocations   dd 0
      .PointerToLineNumbers   dd 0
      .NumberOfRelocations    dw 0
      .NumberOfLineNumbers    dw 0
      .Characteristics        dd $e000'0020
      m1 SECTION_2                                              ;great again!

  padzero DISK_SECTOR                                           ;align to .FileAllignment




  SECTION_1_RAW:
                                                                ;import table
    dd 0,0,0,kernel_name+SECTION_1_RVA,kernel_table+SECTION_1_RVA
    dd 0,0,0,user_name+SECTION_1_RVA,user_table+SECTION_1_RVA
    dd 0,0,0,shell_name+SECTION_1_RVA,shell_table+SECTION_1_RVA
    dd 0,0,0,0,0

    kernel_name db 'kernel32.dll',0
    kernel_table:
      exit_process  dd exit_process_+SECTION_1_RVA
      beep          dd beep_+SECTION_1_RVA
      dd 0
      exit_process_ dw 0
                    db 'ExitProcess',0
      beep_         dw 0
                    db 'Beep',0

    user_name db 'user32.dll',0
    user_table:
      message_box  dd message_box_+SECTION_1_RVA
      dd 0
      message_box_ dw 0
                   db 'MessageBoxA',0

    shell_name db 'shell32.dll',0
    shell_table:
      shell_execute  dd shell_execute_+SECTION_1_RVA
      shell_alabama  dd shell_alabama_+SECTION_1_RVA
      dd 0
      shell_execute_ dw 0
                     db 'ShellExecuteA',0
      shell_alabama_ dw 0
                     db 'ShellAboutA',0


  entry_point:                                                  ;entry point
  use32
        push     0
        push     0
        call     @f
        db       'Next MessageBoxA comes...',0
     @@:push     0
        call     [message_box+SECTION_1_BASE]


        push     0
        push     caption+SECTION_2_BASE
        call     @f
        db       'Check next fields whenever changing this source:',10,\
                 '- IMAGE_OPTIONAL_HEADER.SizeOfImage'           ,10,\
                 '- SECTION_X.Rva',0
     @@:push     0
        call     [message_box+SECTION_1_BASE]


        push     0
        push     0
        call     @f
        db       'ShellExecuteA and notepad.exe(the two rude boys) are trying to strip me...',0
     @@:push     0
        call     [message_box+SECTION_1_BASE]


        push     5
        push     0
        push     0
        call     @f
        db       'pe - enu.asm',0
     @@:push     0
        push     0
        call     [shell_execute+SECTION_1_BASE]


        cmp      eax,32
        mov      eax,fail+SECTION_2_BASE
        mov      edx,pervert+SECTION_2_BASE
        cmova    eax,edx
        push     0
        push     0
        push     eax
        push     0
        call     [message_box+SECTION_1_BASE]


        push     0
        push     0
        call     @f
        db       'DO',0
     @@:push     0
        call     [message_box+SECTION_1_BASE]


        mov      edi,melody+SECTION_2_BASE
        call     edi


        push     0
        call     @f
        db       'www.flatAssembler.net, www.wasm.ru, edemko@rambler.ru',0
     @@:push     caption+SECTION_2_BASE
        push     0
        call     [shell_alabama+SECTION_1_BASE]


        push     0
        push     0
        call     @f
        db       'The wiper is coming... ExitProcess',0
     @@:push     0
        call     [message_box+SECTION_1_BASE]


        push     0
        call     [exit_process+SECTION_1_BASE]
  padzero DISK_SECTOR
  SECTION_1_RAW.:




  SECTION_2_RAW:
    caption db 'Manual PE32 creation example',0
    fail    db 'hohoho',0
    pervert db 'effing perverts :)',0

    melody:
        push    300 120
        call    [beep+SECTION_1_BASE]
        ret     0

  padzero DISK_SECTOR
  SECTION_2_RAW.:

































; val   = 0..2^64-1
; merge = 0<bytes<9 of value to show
; example: repeat 8
;            display 13,10
;            ShowHex $FEDCBA9876543210,%
;          end repeat
macro ShowHex val*, merge*{
  if merge > 0 & merge < 9
    local .a, .merge
    .merge = (merge) shl 1
    while .merge <> 0
      .a = (val) shr ((.merge - 1) * 4) and 1111b or 11'0000b
      if .a > 11'1001b
        .a = .a + 111b
      end if
      display .a
      .merge = .merge - 1
    end while
  end if
}
    


Description:
Download
Filename: pe by Bernd Luevelsmeyer.rar
Filesize: 18.78 KB
Downloaded: 481 Time(s)

Post 01 Nov 2010, 19:33
View user's profile Send private message Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler 01 Nov 2010, 20:46
My stub. Haven't tested it yet.

Code:
                db "MZ"                   ; DOS_Signature[2] = "MZ"
                dw peof-imgbase           ; DOS_PartPag = 128.
                dw $0001                  ; DOS_PageCnt = 1
                dw $0000                  ; DOS_ReloCnt = 0
                dw $0004                  ; DOS_HdrSize = 4
                dw $0010                  ; DOS_MinMem = 16.
                dw $FFFF                  ; DOS_MaxMem = 65535.
                dw $0000                  ; DOS_RelSS = 0
                dw $0140                  ; DOS_ExeSP = 140
                dw $0000                  ; DOS_ChkSum = 0
                dw $0000                  ; DOS_ExeIP = 0
                dw $0000                  ; DOS_RelCS = 0
                dw mzstart-imgbase        ; DOS_RelocOffset = 40
                rw 17
                dw peof-imgbase           ; DOS_PEOffset = 80
                db $00
                db $00
mzstart:
                use16
                mov     ax,$4c01
                int     $21    


Comments are what fasm spits out.

_________________
This is a block of text that can be added to posts you make.
Post 01 Nov 2010, 20:46
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
edemko



Joined: 18 Jul 2009
Posts: 549
edemko 11 Nov 2010, 13:20


Description:
Download
Filename: PEview by Wayne J. Radburn.rar
Filesize: 28.61 KB
Downloaded: 445 Time(s)

Post 11 Nov 2010, 13:20
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.