flat assembler
Message board for the users of flat assembler.

Index > Main > manual pe header

Author
Thread Post new topic Reply to topic
zxcv
Guest




zxcv 21 Dec 2007, 13:08
I saw on internet many diffrent examples of codes wich manualy biuild pe header.
How can i do that?
the only thing i use now is 'format pe console/gui' <-that changes only 1 byte.


//i ask not cuz im lazy and dont wana search, but i dont want to do smth wrong, as always...
Post 21 Dec 2007, 13:08
Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20415
Location: In your JS exploiting you and your system
revolution 21 Dec 2007, 13:18
I made this some time back:
Code:
       format  binary
      BaseAddress=0x400000
        SectionAlignment=0x1000
     FileAlignment=0x200
 org     BaseAddress
 RVA     equ -BaseAddress+

curr_file_offset=0
curr_section_num equ 0
Section0_start=$
curr_checksum=0
section@virtualLength=0

macro file_align v* {
   local a
     virtual
     align   v
   a=$-$$
      end virtual
 times   a db 0
}

DOS_Header:
     .e_magic        dw      'MZ'
      .e_cblp         dw      0x0080
      .e_cp           dw      0x0001
      .e_crlc         dw      0x0000
      .e_cparhdr      dw      0x0004
      .e_minalloc     dw      0x0008
      .e_maxalloc     dw      0x0008
      .e_ss           dw      0x0004
      .e_sp           dw      0x0080
      .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      RVA PE_header

DOS_stub:
  use16
       push    cs
  pop     ds
  mov     ah,9
        mov     dx,.message-DOS_stub
        int     21h
 mov     ax,4cffh
    int     21h
    .message:
    db      'Minimum - Win95',0dh,0ah,'$'
   use32

   file_align 4

PE_header:
  .Signature              dd      'PE'

FileHeader:
       .Machine                dw      0x014c
      .NumberOfSections       dw      NumberOfSections
    .TimeDateStamp          dd      %t 
 .PointerToSymbolTable   dd      0 
  .NumberOfSymbols        dd      0 
  .SizeOfOptionalHeader   dw      SectionTable-OptionalHeader
 .Characteristics        dw      0x010f

OptionalHeader:
   .Magic                          dw      0x010b
      .MajorLinkerVersion             db      0
   .MinerLinkerVersion             db      0
   .SizeOfCode                     dd      0
   .SizeOfInitializedData          dd      0
   .SizeOfUnInitializedData        dd      0
   .AddressOfEntryPoint            dd      RVA Entry@Start
     .BaseOfCode                     dd      0
   .BaseOfData                     dd      0
   .ImageBase                      dd      BaseAddress
 .SectionAlignment               dd      SectionAlignment
    .FileAlignment                  dd      FileAlignment
       .MajorOSVersion                 dw      1
   .MinorOSVersion                 dw      0
   .MajorImageVersion              dw      0
   .MinorImageVersion              dw      0
   .MajorSubSystemVersion          dw      4
   .MinorSubSystemVersion          dw      0
   .Win32VersionValue              dd      0
   .SizeOfImage                    dd      SizeOfImage
 .SizeOfHeaders                  dd      Section0_length
     .CheckSum                       dd      0
   .SubSystem                      dw      2       ;GUI
        .DLLCharacteristics             dw      0
   .SizeOfStackReserve             dd      0x1000
      .SizeOfStackCommit              dd      0x1000
      .SizeOfHeapReserve              dd      0x10000
     .SizeOfHeapCommit               dd      0
   .LoaderFlags                    dd      0
   .NumberOfDataDirectories        dd      (SectionTable-Data_Directories)shr 3

Data_Directories:
   .Export_Table           dd      0,0
 .Import_Table           dd      RVA ImportSection,ImportSection.length
      .Resource_Table         dd      0,0
 .Exception_Table        dd      0,0
 .Certificate_Table      dd      0,0
 .Relocation_Table       dd      0,0
 .Debug_Data             dd      0,0
 .Architecture           dd      0,0
 .Global_PTR             dd      0,0
 .TLS_Table              dd      0,0
 .Load_Config_Table      dd      0,0
 .BoundImportTable       dd      0,0
 .ImportAddressTable     dd      0,0
 .DelayImportDescriptor  dd      0,0
 .COMplusRuntimeHeader   dd      0,0
 .Reserved               dd      0,0

SectionTable:

rept 32 num {
  if num<=NumberOfSections
    Section#num:
     .Name                   dq      Section#num#_name
   .VirtualSize            dd      Section#num#_length
 .VirtualAddress         dd      RVA Section#num#_start
      .SizeOfRawData          dd      Section#num#_file_length
    .PointerToRawData       dd      Section#num#_file_start
     .PointerToRelocations   dd      0
   .PointerToLinenumbers   dd      0
   .NumberOfRelocations    dw      0
   .NumberOfLinenumbers    dw      0
   .Characteristics        dd      Section#num#_characteristics
  end if
}

      file_align FileAlignment

macro update_checksum {
        local j
     repeat ($-$$)/2
             load j word from (%-1)*2+$$
         curr_checksum=curr_checksum+j
               curr_checksum=(curr_checksum and 0xffff)+(curr_checksum shr 16)
     end repeat
  if curr_section_num=0
               store dword final_checksum at OptionalHeader.CheckSum
       end if
}
macro .section_finish {
    match num,curr_section_num\{
  Section\#num\#_length=($+section@virtualLength)-Section\#num\#_start
    file_align FileAlignment
    update_checksum
     Section\#num\#_file_length=$-Section\#num\#_start
       curr_file_offset=curr_file_offset+$-Section\#num\#_start
  if Section\#num\#_length=0
                org (($+section@virtualLength)+SectionAlignment)and(not(SectionAlignment-1))
        else
                org (($+section@virtualLength)+SectionAlignment-1)and(not(SectionAlignment-1))
      end if
      section@virtualLength=0
    \}
}
macro .section name*,characteristics* {
    .section_finish
    match s,curr_section_num\{rept 2 n:s\\{curr_section_num equ n\\}\}
    match num,curr_section_num\{
  Section\#num\#_start=$
    Section\#num\#_file_start=curr_file_offset
        Section\#num\#_characteristics=characteristics
    Section\#num\#_name=name
    \}
}
macro .end start* {
    .section_finish
     SizeOfImage=RVA $
   NumberOfSections=curr_section_num
   Entry@Start=start
   final_checksum=curr_checksum+curr_file_offset
}

.section '.text',0xe0000020       ;read write execute

Start:        pushd   0
   pushd   Caption
     pushd   Text
        pushd   0
   call    [MessageBox]
        pushd   0
   call    [ExitProcess]

.section '.data',0xc0000040         ;read write

Caption   db      'Caption',0
Text   db      'Text',0

.section '.udata',0xc0000040           ;read write
virtual

       rd      1280

section@virtualLength=$-$$
end virtual
.section '.idata',0xc0000040    ;read write

ImportSection:
                    dd      0,0,0,RVA kernel_name,RVA kernel_table
                      dd      0,0,0,RVA user_name,RVA user_table
                  dd      0,0,0,0,0

       _ExitProcess    db      0,0,'ExitProcess',0
       _MessageBox     db      0,0,'MessageBoxA',0

   kernel_name     db      'KERNEL32.DLL',0
  user_name       db      'USER32.DLL',0

        file_align 4

    kernel_table:
   ExitProcess     dd      RVA _ExitProcess
                    dd      0
   user_table:
     MessageBox      dd      RVA _MessageBox
                     dd      0

ImportSection.length=$-ImportSection

.end Start    
Post 21 Dec 2007, 13:18
View user's profile Send private message Visit poster's website Reply with quote
asmrox



Joined: 19 Jan 2008
Posts: 160
asmrox 06 Mar 2008, 18:39
is it possible to create pure pe file? without dos header?
can i use e_ip as entrypoint?
Post 06 Mar 2008, 18:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20415
Location: In your JS exploiting you and your system
revolution 06 Mar 2008, 18:42
asmrox wrote:
is it possible to create pure pe file? without dos header?
can i use e_ip as entrypoint?
No. The PE format specifies a DOS header, you can't strip it off, because that would mean it ain't a PE file anymore.
Post 06 Mar 2008, 18:42
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4060
Location: vpcmpistri
bitRAKE 06 Mar 2008, 20:44
The DOS header appears at the base address, so more useful constant data could be stored there. Also it can be reduced to a few bytes. I've attached an image of the best PE file I've ever seen (works on XP). I'd attached the source code, but I don't have it and haven't quite worked through all the dependancies.

http://www.xakep.ru/post/21399/default.asp

Edit: here is a first draft at RE'ing the image. I am impressed by the author's work.


Description: 153 byte PE message box
Download
Filename: mzpe153.asm
Filesize: 833 Bytes
Downloaded: 473 Time(s)


_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 Mar 2008, 20:44
View user's profile Send private message Visit poster's website Reply with quote
dap



Joined: 01 Dec 2007
Posts: 61
Location: Belgium
dap 06 Mar 2008, 21:21
It is possible to write a 97 bytes executable, but it doesn't conform to the specification : http://www.phreedom.org/solar/code/tinype/


Last edited by dap on 06 Mar 2008, 22:52; edited 1 time in total
Post 06 Mar 2008, 21:21
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4060
Location: vpcmpistri
bitRAKE 06 Mar 2008, 22:30
Yeah, and it doesn't do anything. Confused
Code:
ImageBase = $1000000

; MZ header: only two fields that matter are e_magic and e_lfanew
  db "MZ" ; e_magic
  dw ?

  db "PE"
  dw ?

pehdr:
  dw 0x014C     ; Machine (Intel 386)
  dw 1          ; NumberOfSections

; dd 0xC3582A6A ; TimeDateStamp UNUSED
; Entry point
  use32
start:
  push 42
  pop eax
  ret

codesize = $ - start

  dd ?               ; PointerToSymbolTable UNUSED
  dd ?               ; NumberOfSymbols UNUSED
  dw sections-opthdr ; SizeOfOptionalHeader
  dw 0x103           ; Characteristics

;
; PE optional header: debug directory size at offset 0x94 from here must be 0

e_lfanew  equ 4
filealign equ e_lfanew
sectalign equ e_lfanew

opthdr:
  dw 0x10B      ; Magic (PE32)
  db ?          ; MajorLinkerVersion UNUSED
  db ?          ; MinorLinkerVersion UNUSED

SizeOfImage = (((hdrsize+(sectalign-1))/sectalign)*sectalign) + (((codesize+(sectalign-1))/sectalign)*sectalign)
SizeOfHeaders = (((hdrsize+(filealign-1))/filealign)*filealign)

sections:
  dd ?          ; SizeOfCode UNUSED                  ; Name UNUSED
  dd ?          ; SizeOfInitializedData UNUSED       ; Name UNUSED
  dd codesize   ; SizeOfUninitializedData UNUSED     ; VirtualSize
  dd start      ; AddressOfEntryPoint                ; VirtualAddress
  dd codesize   ; BaseOfCode UNUSED                  ; SizeOfRawData
  dd start      ; BaseOfData UNUSED                  ; PointerToRawData
  dd ImageBase  ; ImageBase                          ; PointerToRelocations UNUSED
  dd e_lfanew   ;*SectionAlignment                   ; PointerToLinenumbers UNUSED
  dd filealign  ; FileAlignment                      ; NumberOfRelocations, NumberOfLinenumbers UNUSED
  dw ?          ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED
  dw ?          ; MinorOperatingSystemVersion UNUSED
  dw ?          ; MajorImageVersion UNUSED
  dw ?          ; MinorImageVersion UNUSED
  dw 4          ; MajorSubsystemVersion
  dw ?          ; MinorSubsystemVersion UNUSED
  dd ?          ; Win32VersionValue UNUSED
  dd SizeOfImage
  dd SizeOfHeaders
  dd ?          ; CheckSum UNUSED
  db 2          ; Subsystem (Win32 GUI)

hdrsize = $ - $$
filesize = $ - $$    
I've marked all the unused space with ?'s.

Although my messagebox code is only 11 bytes - I have not figured a way to wedge the needed support structures into the file, yet:
Code:
  push eax
  cdq
  inc eax
  bswap eax
  push eax
  push eax
  push edx
  call [eax+user32]
  retn    

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 Mar 2008, 22:30
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.