Skip to content

Commit 9165529

Browse files
author
vdisasmdev
committed
+ More checks for resource parsing. Fixes loading of some malformed images.
* Minor typos fixed.
1 parent 5638b4d commit 9165529

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

PE.Common.pas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ interface
122122
SCategoryLoadFromFile = 'LoadFromFile';
123123
SCategoryDOSHeader = 'DOS Header';
124124
SCategorySections = 'Sections';
125-
SCategoryDataDirecory = 'Data Direcories';
125+
SCategoryDataDirecory = 'Data Directories';
126+
SCategoryResources = 'Resources';
126127

127128
implementation
128129

PE.DataDirectories.pas

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ procedure TDataDirectories.LoadDirectoriesFromStream;
197197
SizeToEOF: uint64;
198198
Size: uint32;
199199
i: integer;
200+
needToNullDir: boolean;
200201
begin
201202
SizeToEOF := (Stream.Size - Stream.Position);
202203

@@ -235,14 +236,27 @@ procedure TDataDirectories.LoadDirectoriesFromStream;
235236
// Check RVAs.
236237
for i := 0 to self.Count - 1 do
237238
begin
238-
if not TPEImage(FPE).RVAExists(FItems[i].RVA) then
239+
// Empty dir is ok.
240+
if FItems[i].IsEmpty then
241+
continue;
242+
243+
needToNullDir := False;
244+
245+
if (FItems[i].Size = 0) and (FItems[i].RVA <> 0) then
246+
begin
247+
Msg.Write(SCategoryDataDirecory, 'Directory # %d has size = 0.', [i]);
248+
needToNullDir := true;
249+
end
250+
else if not TPEImage(FPE).RVAExists(FItems[i].RVA) then
251+
begin
252+
Msg.Write(SCategoryDataDirecory, 'Directory # %d RVA is not in image.', [i]);
253+
needToNullDir := true;
254+
end;
255+
256+
if needToNullDir and (PO_NULL_INVALID_DIRECTORY in TPEImage(FPE).Options) then
239257
begin
240-
Msg.Write(SCategoryDataDirecory, 'Directory # %d is not in image.', [i]);
241-
if PO_NULL_INVALID_DIRECTORY in TPEImage(FPE).Options then
242-
begin
243-
FItems[i] := NULL_IMAGE_DATA_DIRECTORY;
244-
Msg.Write(SCategoryDataDirecory, 'Directory # %d nulled.', [i]);
245-
end;
258+
FItems[i] := NULL_IMAGE_DATA_DIRECTORY;
259+
Msg.Write(SCategoryDataDirecory, 'Directory # %d nulled.', [i]);
246260
end;
247261
end;
248262
end;
@@ -254,7 +268,7 @@ function TDataDirectories.SaveToStream(Index: integer; Stream: TStream): boolean
254268
if Get(Index, @Dir) then
255269
begin
256270
TPEImage(FPE).SaveRegionToStream(Stream, Dir.VirtualAddress, Dir.Size);
257-
exit(True);
271+
exit(true);
258272
end;
259273
exit(False);
260274
end;

PE.Parser.Resources.pas

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function TPEResourcesParser.LogInvalidResourceSizesTraverse(
5151
begin
5252
if Node.IsLeaf then
5353
if not TResourceTreeLeafNode(Node).ValidSize then
54-
TPEImage(FPE).Msg.Write('Bad size of resource (probably packed): %s', [Node.GetPath]);
54+
TPEImage(FPE).Msg.Write(SCategoryResources, 'Bad size of resource (probably packed): %s', [Node.GetPath]);
5555

5656
Result := True;
5757
end;
@@ -66,6 +66,7 @@ function TPEResourcesParser.Parse: TParserResult;
6666
// Check if directory present.
6767
if not Img.DataDirectories.Get(DDIR_RESOURCE, @dir) then
6868
exit(PR_OK);
69+
6970
if dir.IsEmpty then
7071
exit(PR_OK);
7172

@@ -108,7 +109,15 @@ function TPEResourcesParser.ReadEntry(
108109
if not(Img.SeekRVA(RVA + Index * SizeOf(Entry)) and
109110
Img.ReadEx(@Entry, SizeOf(Entry))) then
110111
begin
111-
Img.Msg.Write('Bad resource entry.');
112+
Img.Msg.Write(SCategoryResources, 'Bad resource entry.');
113+
exit;
114+
end;
115+
116+
// Check if RVA is correct.
117+
DataRVA := Entry.DataEntryRVA + FBaseRVA;
118+
if not Img.RVAExists(DataRVA) then
119+
begin
120+
Img.Msg.Write(SCategoryResources, 'Bad entry RVA.');
112121
exit;
113122
end;
114123

@@ -119,7 +128,7 @@ function TPEResourcesParser.ReadEntry(
119128
DataRVA := Entry.DataEntryRVA + FBaseRVA;
120129
if not(Img.SeekRVA(DataRVA) and Img.ReadEx(@DataEntry, SizeOf(DataEntry))) then
121130
begin
122-
Img.Msg.Write('Bad resource leaf node.');
131+
Img.Msg.Write(SCategoryResources, 'Bad resource leaf node.');
123132
exit;
124133
end;
125134
LeafNode := TResourceTreeLeafNode.CreateFromEntry(FPE, DataEntry);
@@ -159,7 +168,7 @@ function TPEResourcesParser.ReadEntry(
159168
NameRVA := Entry.NameRVA + FBaseRVA;
160169
if not Img.SeekRVA(NameRVA) then
161170
begin
162-
Img.Msg.Write('Failed to read resource name.');
171+
Img.Msg.Write(SCategoryResources, 'Failed to read resource name.');
163172
exit(nil);
164173
end;
165174
Result.Name := Img.ReadUnicodeStringLenPfx2;
@@ -190,7 +199,7 @@ function TPEResourcesParser.ReadNode(
190199
// Read Directory Table.
191200
if not(Img.SeekRVA(RVA) and Img.ReadEx(@RDT, SizeOf(RDT))) then
192201
begin
193-
Img.Msg.Write('Failed to read resource directory table.');
202+
Img.Msg.Write(SCategoryResources, 'Failed to read resource directory table.');
194203
exit(PR_ERROR);
195204
end;
196205

@@ -201,14 +210,18 @@ function TPEResourcesParser.ReadNode(
201210
// Read named entries.
202211
for i := 1 to RDT.NumberOfNameEntries do
203212
begin
204-
ReadEntry(ParentNode, RVA, n, EK_NAME, @RDT);
213+
if ReadEntry(ParentNode, RVA, n, EK_NAME, @RDT) = nil then
214+
exit(PR_ERROR);
215+
205216
inc(n);
206217
end;
207218

208219
// Read Id entries.
209220
for i := 1 to RDT.NumberOfIDEntries do
210221
begin
211-
ReadEntry(ParentNode, RVA, n, EK_ID, @RDT);
222+
if ReadEntry(ParentNode, RVA, n, EK_ID, @RDT) = nil then
223+
exit(PR_ERROR);
224+
212225
inc(n);
213226
end;
214227

0 commit comments

Comments
 (0)