Skip to content

Commit a38c211

Browse files
author
vdisasmdev
committed
* Handle MZ/PE signatures in endianness-aware way.
* TImageNTHeaders32/TImageNTHeaders64 commented out. It seems not used anymore.
1 parent e487cfd commit a38c211

File tree

6 files changed

+74
-36
lines changed

6 files changed

+74
-36
lines changed

PE.Image.Saving.pas

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function DoDosHdr(PE: TPEImage; AStream: TStream): boolean;
4343
DosBlockSize: integer;
4444
begin
4545
h := PE.DOSHeader;
46-
h^.e_magic := MZ_SIGNATURE;
46+
h^.e_magic.SetMZ;
4747
h^.e_lfanew := PE.LFANew;
4848

4949
// Write DOS header.
@@ -58,13 +58,11 @@ function DoDosHdr(PE: TPEImage; AStream: TStream): boolean;
5858
{ NT }
5959

6060
function DoFileHdr(PE: TPEImage; AStream: TStream): boolean;
61-
const
62-
sig: uint32 = PE00_SIGNATURE;
6361
begin
64-
Result := False;
65-
if StreamWrite(AStream, sig, SizeOf(sig)) then
62+
if StreamWrite(AStream, PE00_SIGNATURE, SizeOf(PE00_SIGNATURE)) then
6663
if StreamWrite(AStream, PE.FileHeader^, SizeOf(PE.FileHeader^)) then
67-
Result := true;
64+
exit(true);
65+
exit(false);
6866
end;
6967

7068
{ Optional }

PE.Image.pas

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -960,21 +960,20 @@ class function TPEImage.IsPE(const FileName: string): boolean;
960960
class function TPEImage.IsPE(AStream: TStream; Ofs: UInt64): boolean;
961961
var
962962
dos: TImageDOSHeader;
963-
pe00: uint32;
963+
peSig: TNTSignature;
964964
begin
965-
if AStream.Seek(Ofs, TSeekOrigin.soBeginning) <> Ofs then
965+
if not StreamSeek(AStream, Ofs) then
966966
exit(false);
967967

968-
if (AStream.Read(dos, SizeOf(dos)) = SizeOf(dos)) then
969-
if (dos.e_magic = MZ_SIGNATURE) then
968+
if StreamRead(AStream, dos, SizeOf(dos)) then
969+
if dos.e_magic.IsMZ then
970970
begin
971971
Ofs := Ofs + dos.e_lfanew;
972972
if Ofs >= AStream.Size then
973973
exit(false);
974-
if AStream.Seek(Ofs, TSeekOrigin.soBeginning) = Ofs then
975-
if AStream.Read(pe00, SizeOf(pe00)) = SizeOf(pe00) then
976-
if pe00 = PE00_SIGNATURE then
977-
exit(true);
974+
if StreamSeek(AStream, Ofs) then
975+
if StreamRead(AStream, peSig, SizeOf(peSig)) then
976+
exit(peSig.IsPE00);
978977
end;
979978
exit(false);
980979
end;
@@ -1184,10 +1183,10 @@ function TPEImage.ReadEx(var Buffer; Size: cardinal): boolean;
11841183

11851184
function TPEImage.ReadAnsiString: string;
11861185
var
1187-
len: Integer;
1186+
Len: integer;
11881187
begin
1189-
if not ReadAnsiStringLen(0, len, result) then
1190-
result := '';
1188+
if not ReadAnsiStringLen(0, Len, Result) then
1189+
Result := '';
11911190
end;
11921191

11931192
function TPEImage.ReadAnsiStringLen(MaxLen: integer; out Len: integer; out Str: string): boolean;
@@ -1228,7 +1227,7 @@ function TPEImage.ReadAnsiStringLen(MaxLen: integer; out Len: integer; out Str:
12281227
Str := string(pBegin);
12291228

12301229
// Include null at end.
1231-
inc(len);
1230+
inc(Len);
12321231

12331232
// Move current position.
12341233
inc(FPositionRVA, Len);
@@ -1464,7 +1463,7 @@ function TPEImage.LoadFromStream(AStream: TStream; AParseStages: TParserFlags;
14641463
OptHdrSizeRead: int32; // w/o directories
14651464
Stage: TParserFlag;
14661465
Parser: TPEParser;
1467-
Signature: uint32;
1466+
Signature: TNTSignature;
14681467
DOSBlockSize: uint32;
14691468
begin
14701469
Result := false;
@@ -1535,7 +1534,7 @@ function TPEImage.LoadFromStream(AStream: TStream; AParseStages: TParserFlags;
15351534
if not StreamRead(AStream, Signature, SizeOf(Signature)) then
15361535
exit;
15371536
// Check signature.
1538-
if Signature <> PE00_SIGNATURE then
1537+
if not Signature.IsPE00 then
15391538
exit; // not PE file
15401539

15411540
// Load File Header.

PE.MemoryStream.pas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,12 @@ class function TPEMemoryStream.GetModuleImageSize(ModulePtr: PByte): uint32;
193193
begin
194194
dos := PImageDOSHeader(ModulePtr);
195195

196-
if dos.e_magic <> MZ_SIGNATURE then
196+
if not dos.e_magic.IsMZ then
197197
raise Exception.Create('Not PE image');
198198

199199
nt := PImageNTHeaders(ModulePtr + dos^.e_lfanew);
200200

201-
if nt.Signature <> PE00_SIGNATURE then
201+
if not nt.Signature.IsPE00 then
202202
raise Exception.Create('Not PE image');
203203

204204
Result := nt^.OptionalHeader.pe32.SizeOfImage;

PE.Parser.Headers.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ implementation
2020

2121
function LoadDosHeader;
2222
begin
23-
Result := StreamRead(AStream, AHdr, SizeOf(AHdr)) and (AHdr.e_magic = MZ_SIGNATURE);
23+
Result := StreamRead(AStream, AHdr, SizeOf(AHdr)) and AHdr.e_magic.IsMZ;
2424
end;
2525

2626
function LoadFileHeader;

PE.Types.DOSHeader.pas

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
interface
44

5-
const
6-
MZ_SIGNATURE = $5A4D;
7-
ZM_SIGNATURE = $4D5A;
5+
type
6+
TDOSMagic = packed record
7+
public
8+
function IsMZ: boolean; inline;
9+
procedure SetMZ; inline;
10+
public
11+
case integer of
12+
0:
13+
(chars: array [0 .. 1] of AnsiChar);
14+
end;
815

916
type
1017
TImageDOSHeader = packed record
11-
e_magic: uint16; // Magic number.
18+
e_magic: TDOSMagic; // Magic number.
1219
e_cblp: uint16; // Bytes on last page of file.
1320
e_cp: uint16; // Pages in file.
1421
e_crlc: uint16; // Relocations.
@@ -40,4 +47,17 @@ interface
4047

4148
implementation
4249

50+
{ TDOSMagic }
51+
52+
function TDOSMagic.IsMZ: boolean;
53+
begin
54+
result := self.chars = 'MZ';
55+
end;
56+
57+
procedure TDOSMagic.SetMZ;
58+
begin
59+
self.chars[0] := 'M';
60+
self.chars[1] := 'Z';
61+
end;
62+
4363
end.

PE.Types.NTHeaders.pas

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,52 @@ interface
66
PE.Types.FileHeader,
77
PE.Types.OptionalHeader;
88

9-
const
10-
PE00_SIGNATURE = $00004550;
11-
129
type
10+
{
1311
TImageNTHeaders32 = packed record
14-
Signature: uint32;
15-
FileHeader: TImageFileHeader;
12+
Signature: uint32;
13+
FileHeader: TImageFileHeader;
1614
OptionalHeader: TImageOptionalHeader32;
1715
end;
16+
1817
PImageNTHeaders32 = ^TImageNTHeaders32;
1918
2019
TImageNTHeaders64 = packed record
21-
Signature: uint32;
22-
FileHeader: TImageFileHeader;
20+
Signature: uint32;
21+
FileHeader: TImageFileHeader;
2322
OptionalHeader: TImageOptionalHeader64;
2423
end;
24+
2525
PImageNTHeaders64 = ^TImageNTHeaders64;
26+
}
27+
28+
TNTSignature = record
29+
public
30+
function IsPE00: boolean; inline;
31+
public
32+
case integer of
33+
0:
34+
(chars: array [0 .. 3] of AnsiChar);
35+
end;
2636

2737
TImageNTHeaders = packed record
28-
Signature: uint32;
29-
FileHeader: TImageFileHeader;
38+
Signature: TNTSignature;
39+
FileHeader: TImageFileHeader;
3040
OptionalHeader: TImageOptionalHeader;
3141
end;
42+
3243
PImageNTHeaders = ^TImageNTHeaders;
3344

45+
const
46+
PE00_SIGNATURE: TNTSignature = (chars: 'PE'#0#0);
47+
3448
implementation
3549

50+
{ TNTSignature }
51+
52+
function TNTSignature.IsPE00: boolean;
53+
begin
54+
result := self.chars = PE00_SIGNATURE.chars;
55+
end;
56+
3657
end.

0 commit comments

Comments
 (0)