Obsah

Soubor EXE

Spustitelnej soubor MS-DOSu (MS-DOS Executable File)
Aplikace pro Windows PE (Portable Executable)

Spustitelnej soubor MS-DOSu (16-bit real mode)

Při spuštění souboru typu EXE se vytvoří PSP (sem se uložej parametry z příkazový řádky), načte se kód programu,
provede se relokace, nastaví se SS:SP podle hodnot v hlavičce a spustí se CS:IP.
ds = es = PSPSEG
Program musí sám nastavit ds.

Ofset Velikost Význam
0 2 MAGIC - "MZ" (5A4Dh)
2 2 CBLP - počet bytú v poslední stránce
4 2 CP - dýlka souboru v 512 bajtovejch stránkách včetně hlavičky
6 2 CRLC - počet položek v relokační tabulce
8 2 CPARHDR - velikost záhlaví v paragrafech (16 B) včetně relokační tabulky
10 2 MINALLOC - Minimální velikost požadovaný paměti za koncem programu v paragrafech
12 2 MAXALLOC - Maximální velikost požadovaný paměti za koncem programu v paragrafech
14 2 SS (stack segment) od začátku programu v paragrafech
16 2 SP (stack pointer)
18 2 CSUM - Kontrolní součet
20 2 IP (instruction pointer)
22 2 CS (code segment) od začátku programu v paragrafech
24 2 LFARLC - offset relokační tabulky od začátku souboru v bajtech (1Ch = 28)
26 2 OVNO - Číslo overlaye (0 = základní modul)
28 8 RES? - nepoužito
36 2 OEMID?
38 2 OEMINFO?
40 20 RES2? - nepoužito
60 4 LFANEW? - offset nový hlavičky
LFARLC CRLC*4 Relokační tabulka: {uns2 ofs, uns2 seg}*CRLC
Segment se počítá od začátku programu v paragrafech
CPARHDR*16 (CP*512)-(CPARHDR*16) Kód programu, max 1 MiB, v praxi ještě míň

Jak je to v souboru a jak v paměti

Soubor *.EXE Paměť
Ofset Velikost Význam Adresa Velikost Význam
  0:0 400h (256*4 = 1024) Tabulka přerušení
40h:0 100h (256) Proměný BIOSu
0 28? Hlavička 50h:0 ? MS-DOS
LFARLC CRLC*4 Relokační tabulka PSPSEG:0 256 PSP
CPARHDR*16 (CP*512) - (CPARHDR*16) Kód programu a
inicializovaný data
STARTSEG:0 (CP*512) - (CPARHDR*16) Kód programu a inicializovaný data,
začátek programu = (STARTSEG+CS):IP,
kde CS,IP jsou hodnoty z hlavičky souboru
? ? Neinicializovaný data
(STARTSEG+SS):0 SP Zásobník (stack)
? ? Halda (heap)
0A000h:0 320 KiB Sdílená paměť
0F000h:0 64 KiB ROM BIOS

Relokace se provádí takhle:
RTEntry = {uns2 ofs, seg}
foreach(RTEntry rte in RT)
 word[STARTSEG+rte.seg:rte.ofs] += STARTSEG;


Aplikace pro Windows PE (Portable Executable)

U aplikací pro Windows je LFARLC >= 40h (obvykle 40h).
Na začátku je vložená aplikace pro MS-DOS zvaná "stub", která vypíše hlášku "This program requires Microsoft Windows." nebo "This program cannot be run in DOS mode." a ukončí se.

Ofset Velikost Význam
0 40h (64) ? Hlavička pro MS-DOS (old-style header), viz výš
3Ch (60) 4 LFANEW - ofset hlavičky pro Windows (new-style header file offset, obvykle 80h)
LFANEW+0 2 Magic = "PE" (4550h) (Portable Executable)
LFANEW+2 1 0
LFANEW+3 1 0
LFANEW+4 2 Machine (obvykle 14Ch - Intel)
LFANEW+6 2 NumberOfSections - počet položek v SectionTable
LFANEW+8 4 TimeDateStamp - datum a čas, kdy byl soubor vytvořenej
LFANEW+0Ch 4 PointerToSymbolTable
LFANEW+10h 4 NumberOfSymbols
LFANEW+14h 2 SizeOfOptionalHeader (OH)
LFANEW+16h 2 Characteristics
LFANEW+18h 2 OH Magic
LFANEW+1Ah 1 MajorLinkerVersion
LFANEW+1Bh 1 MinorLinkerVersion
LFANEW+1Ch 4 SizeOfCode
LFANEW+20h 4 SizeOfInitializedData
LFANEW+24h 4 SizeOfUninitializedData
LFANEW+28h 4 AddressOfEntryPoint
LFANEW+2Ch 4 BaseOfCode
LFANEW+30h 4 BaseOfData
LFANEW+34h 4 ImageBase
LFANEW+38h 4 SectionAlignment = 4096 or 8192
LFANEW+3Ch 4 FileAlignment = 512
LFANEW+40h 2 MajorOperatingSystemVersion
LFANEW+42h 2 MinorOperatingSystemVersion
LFANEW+44h 2 MajorImageVersion
LFANEW+46h 2 MinorImageVersion
LFANEW+48h 2 MajorSubsystemVersion
LFANEW+4Ah 2 MinorSubsystemVersion
LFANEW+4Ch 4 Reserved1
LFANEW+50h 4 SizeOfImage
LFANEW+54h 4 SizeOfHeaders
LFANEW+58h 4 CheckSum
LFANEW+5Ch 2 Subsystem
LFANEW+5Eh 2 DllCharacteristics
LFANEW+60h 4 SizeOfStackReserve
LFANEW+64h 4 SizeOfStackCommit
LFANEW+68h 4 SizeOfHeapReserve
LFANEW+6Ch 4 SizeOfHeapCommit
LFANEW+70h 4 LoaderFlags
LFANEW+74h 4 NumberOfRvaAndSizes = 16
LFANEW+78h 8*16 DataDirectory (RvaAndSizes) RVA = Ofset od ImageBase
OfsetvelikostVýznam
04RVA
44Size

IMAGE_DIRECTORY_ENTRY_EXPORT 0
IMAGE_DIRECTORY_ENTRY_IMPORT 1
IMAGE_DIRECTORY_ENTRY_RESOURCE 2
IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
IMAGE_DIRECTORY_ENTRY_SECURITY 4
IMAGE_DIRECTORY_ENTRY_BASERELOC 5
IMAGE_DIRECTORY_ENTRY_DEBUG 6
IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
IMAGE_DIRECTORY_ENTRY_TLS 9
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
IMAGE_DIRECTORY_ENTRY_IAT 12

Položka v SectionTable

Počet položek = NumberOfSections
Pozice v souboru = LFANEW + 18h + SizeOfOptionalHeader

Ofset Velikost Význam
0 8 Name
8 4 PhysicalAddress / VirtualSize
12 4 VirtualAddress
16 4 SizeOfRawData
20 4 PointerToRawData
24 4 PointerToRelocations
28 4 PointerToLinenumbers
32 2 NumberOfRelocations
34 2 NumberOfLinenumbers
36 4 Characteristics:
0x20 - kódová sekce (.text)
0x40 - inicializovaný data (.rdata, .data)
0x80 - neinicializovaný data (.bss)
0x04000000 - nelze cachovat
0x08000000 - nelze stránkovat
0x10000000 - sdílená sekce
0x20000000 - spustitelná sekce
0x40000000 - lze číst
0x80000000 - lze zapisovat

Jak je to v paměti

Lineární adresaVelikostVýznam
ImageBase = 0x400000SizeOfImageKód programu, inicializovaný data, resources
0x7D8500000x46000KernelBase.dll
0x7DAB00000x90000gdi32.dll
0x7DC500000x100000user32.dll
0x7DD600000x100000kernel32.dll