filstruktur:
(PE)
[ DOS HEADER (aka MZ header) ]
[ LONG INT ]------------+
... |
[ PE SIGNATUREN ]-------+
[ FILE HEADER ]
[ OPTIONAL HEADER ]
[ SECTION HEADER ]
[ SECTION DATA ]
DOSHEADER:(0x3c byte)
Den här delen är en gammal relik från DOS tiden och är nästan helt ignorerad utav PEladdare, Intressant att notera är dock att om den inte finns så laddas inte PE filen. det behöver inte vara en fullständig MZheader, det räcker med dom första två bytesen ("MZ"), det betyder att man har 58 byte att spara hemlig porr på om man behöver. (ni kan se ett exempel i appendix). Jag tänker inte gå in närmare på vad alla delar av headern betyder då förlegat bara är förnamnet.
LONG INT:(0x4 byte)
direkt efter dosheadern ligger en long int(DWORD), som innehåller en offset från början av filen till PEsignaturen. den är oftast satt till en ganska bra bit efter MZheadern, det är för att få plats med kod som visar ett medelande liknande "This program cannot be run in DOS mode." om programmet skulle köras i DOS. (NOT ibland anses offseten vara en del av MZ headern)
PE SIGNATUREN:
4 byte som ska vara satt till "PE\0\0" på little endian system och "\0\0PE" på big endian. värdet används förutom att avgöra vilken byte order som används för att kontrolera att det är en riktig PEfil.
FILE HEADER:
det här headern är näst intill identisk med fileheadern i COFF, förutom att den första WORDen i PE används för att avgöra vilken maskinvara programmet är skapat för medans den i COFF används som magic number. vilket kanske inte är helt självklart eftersom det magiskavärdet för COFF(0x14c) representerar Intel 386 processorer i PE.
CODE
struct {
unsigned short f_magic; /* magisktnummer / maskin */
unsigned short f_nscns; /* antalet sektioner */
unsigned long f_timdat; /* datum */
unsigned long f_symptr; /* offset till symboltabell */
unsigned long f_nsyms; /* antal poster i symboltabellen */
unsigned short f_opthdr; /* sizeof(optional header) */
unsigned short f_flags; /* flaggor */
};
unsigned short f_magic; /* magisktnummer / maskin */
unsigned short f_nscns; /* antalet sektioner */
unsigned long f_timdat; /* datum */
unsigned long f_symptr; /* offset till symboltabell */
unsigned long f_nsyms; /* antal poster i symboltabellen */
unsigned short f_opthdr; /* sizeof(optional header) */
unsigned short f_flags; /* flaggor */
};
f_magic är satt till något av följande värden:
0x14c - intel 386
0x14d - intel 486
0x14e - intel 586 (aka pentium)
0x160 - R3000 MIPS (little endian)
0x162 - R3000 MIPS (big endian)
0x166 - R4000 MIPS
0x168 - R10000 MIPS
0x184 - DEC Alpha AXP
0x1F0 - IBM PowerPC
intel 386 är nästan uteslutande det som används, men dom andra är också giltiga värden. trots att det inte alltid finns stöd för PE på dessa platformar.
f_nscns visar hur många sektioner det finns i filen, mer om detta senare.
f_timdat det här ska vara satt till datumet filen skapdes, men så ser inte verkligenheten ut den är ofast fylld med nollor eller något som verkar helt slumpmässigt.
f_symptr är en offset till symboltabellen som innehåller debug information om filen, ofast ser man den satt till 0.
f_nsyms antalet poster i symboltabellen, även denna är ofast satt till 0
f_opthdr ska vara satt till storleken på den inte alls så valfria optional header, konstant värde. [ KOLLA UPP ]
f_flags är en bitmask som innehåller lite smått och gott.
0000 0000 0000 0001b - strippade relocs (innuti sektionerna)
0000 0000 0000 0010b - filen är en exe
0000 0000 0000 0100b - kodrads information är borttagen
0000 0000 0000 1000b - debugsymbolerna är borttagna
- till hit är det COFF flaggor -
0000 0000 0001 0000b - programmets RAM kan "swappas" mycket
0000 0000 1000 0000b - oväntad byteorder (big endian på little endian)
0000 0001 0000 0000b - 32bitars maskin
0000 0010 0000 0000b - filen kan enbart köras på sin standard basadress
0000 0100 0000 0000b - filen kan inte köras från cd-rom/floppy etc, kommer kopieras till swap
0000 1000 0000 0000b - filen kan inte köras över nätverk, kommer kopieras till swap
0001 0000 0000 0000b - filen är en drivrutin eller annan systemfil
0010 0000 0000 0000b - filen är en dll
0100 0000 0000 0000b - filen kan inte köras på multiprocessor system
1000 0000 0000 0000b - oväntad byteorder (little endian på big endian)
APPENDIX A:
ett c program som lagrar lite text i MZ utan att förstöra PE imagen.
CODE
#include <stdio.h>
#include <string.h>
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
typedef struct _MZHEADER {
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
} MZHEADER;
int main(int argc, char **argv){
FILE *in;
FILE *out;
long new;
MZHEADER mz;
char tmp = 0x0;
int i;
if(argc!=3)
return 0;
in = fopen(argv[1], "r");
out = fopen(argv[2], "w");
fseek(in, sizeof(MZHEADER), SEEK_SET);
fread(&new, sizeof(long), 1, in);
fseek(in, new, SEEK_SET);
memset(&mz, 0x0, sizeof(MZHEADER));
strcpy((char*)&mz, "SweZine SweZine SweZine SweZine SweZine SweZine. hemlig porr");
mz.e_magic = 0x5A4D;
fwrite(&mz, sizeof(MZHEADER), 1, out);
fwrite(&new, sizeof(long), 1, out);
for(i = 0; i < (new - sizeof(MZHEADER)-sizeof(long)); i++){
fwrite(&tmp, sizeof(char), 1, out);
}
while(fread(&mz, sizeof(MZHEADER), 1, in)!=0){
fwrite(&mz, sizeof(MZHEADER), 1, out);
}
}
#include <string.h>
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
typedef struct _MZHEADER {
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
} MZHEADER;
int main(int argc, char **argv){
FILE *in;
FILE *out;
long new;
MZHEADER mz;
char tmp = 0x0;
int i;
if(argc!=3)
return 0;
in = fopen(argv[1], "r");
out = fopen(argv[2], "w");
fseek(in, sizeof(MZHEADER), SEEK_SET);
fread(&new, sizeof(long), 1, in);
fseek(in, new, SEEK_SET);
memset(&mz, 0x0, sizeof(MZHEADER));
strcpy((char*)&mz, "SweZine SweZine SweZine SweZine SweZine SweZine. hemlig porr");
mz.e_magic = 0x5A4D;
fwrite(&mz, sizeof(MZHEADER), 1, out);
fwrite(&new, sizeof(long), 1, out);
for(i = 0; i < (new - sizeof(MZHEADER)-sizeof(long)); i++){
fwrite(&tmp, sizeof(char), 1, out);
}
while(fread(&mz, sizeof(MZHEADER), 1, in)!=0){
fwrite(&mz, sizeof(MZHEADER), 1, out);
}
}