Skip to content

Commit 2f360ed

Browse files
committed
fix(PE): IMAGE_LOAD_CONFIG_DIR reader
1 parent b6a19c6 commit 2f360ed

2 files changed

Lines changed: 84 additions & 61 deletions

File tree

‎mz/pe/dirs/config.c‎

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,83 @@
22
#include <string.h>
33

44
static bool _pe_read_config_dir32(RDReader* r, PELoadConfigDirectory32* v) {
5+
*v = (PELoadConfigDirectory32){0}; // keep missing fields = 0
6+
57
rd_reader_read_le32(r, &v->Size);
6-
rd_reader_read_le32(r, &v->TimeDateStamp);
7-
rd_reader_read_le16(r, &v->MajorVersion);
8-
rd_reader_read_le16(r, &v->MinorVersion);
9-
rd_reader_read_le32(r, &v->GlobalFlagsClear);
10-
rd_reader_read_le32(r, &v->GlobalFlagsSet);
11-
rd_reader_read_le32(r, &v->CriticalSectionDefaultTimeout);
12-
rd_reader_read_le32(r, &v->DeCommitFreeBlockThreshold);
13-
rd_reader_read_le32(r, &v->DeCommitTotalFreeThreshold);
14-
rd_reader_read_le32(r, &v->LockPrefixTable);
15-
rd_reader_read_le32(r, &v->MaximumAllocationSize);
16-
rd_reader_read_le32(r, &v->VirtualMemoryThreshold);
17-
rd_reader_read_le32(r, &v->ProcessHeapFlags);
18-
rd_reader_read_le32(r, &v->ProcessAffinityMask);
19-
rd_reader_read_le16(r, &v->CSDVersion);
20-
rd_reader_read_le16(r, &v->Reserved1);
21-
rd_reader_read_le32(r, &v->EditList);
22-
rd_reader_read_le32(r, &v->SecurityCookie);
23-
rd_reader_read_le32(r, &v->SEHandlerTable);
24-
rd_reader_read_le32(r, &v->SEHandlerCount);
25-
rd_reader_read_le32(r, &v->GuardCFCheckFunctionPointer);
26-
rd_reader_read_le32(r, &v->Reserved2);
27-
rd_reader_read_le32(r, &v->GuardCFFunctionTable);
28-
rd_reader_read_le32(r, &v->GuardCFFunctionCount);
29-
rd_reader_read_le32(r, &v->GuardFlags);
8+
if(rd_reader_has_error(r) || v->Size < 4) return false;
9+
10+
if(v->Size >= 64) {
11+
rd_reader_read_le32(r, &v->TimeDateStamp);
12+
rd_reader_read_le16(r, &v->MajorVersion);
13+
rd_reader_read_le16(r, &v->MinorVersion);
14+
rd_reader_read_le32(r, &v->GlobalFlagsClear);
15+
rd_reader_read_le32(r, &v->GlobalFlagsSet);
16+
rd_reader_read_le32(r, &v->CriticalSectionDefaultTimeout);
17+
rd_reader_read_le32(r, &v->DeCommitFreeBlockThreshold);
18+
rd_reader_read_le32(r, &v->DeCommitTotalFreeThreshold);
19+
rd_reader_read_le32(r, &v->LockPrefixTable);
20+
rd_reader_read_le32(r, &v->MaximumAllocationSize);
21+
rd_reader_read_le32(r, &v->VirtualMemoryThreshold);
22+
rd_reader_read_le32(r, &v->ProcessHeapFlags);
23+
rd_reader_read_le32(r, &v->ProcessAffinityMask);
24+
rd_reader_read_le16(r, &v->CSDVersion);
25+
rd_reader_read_le16(r, &v->Reserved1);
26+
rd_reader_read_le32(r, &v->EditList);
27+
rd_reader_read_le32(r, &v->SecurityCookie);
28+
}
29+
30+
if(v->Size >= 72) {
31+
rd_reader_read_le32(r, &v->SEHandlerTable);
32+
rd_reader_read_le32(r, &v->SEHandlerCount);
33+
}
34+
35+
if(v->Size >= 92) {
36+
rd_reader_read_le32(r, &v->GuardCFCheckFunctionPointer);
37+
rd_reader_read_le32(r, &v->Reserved2);
38+
rd_reader_read_le32(r, &v->GuardCFFunctionTable);
39+
rd_reader_read_le32(r, &v->GuardCFFunctionCount);
40+
rd_reader_read_le32(r, &v->GuardFlags);
41+
}
3042

3143
return !rd_reader_has_error(r);
3244
}
3345

3446
static bool _pe_read_config_dir64(RDReader* r, PELoadConfigDirectory64* v) {
47+
*v = (PELoadConfigDirectory64){0}; // keep missing fields = 0
48+
3549
rd_reader_read_le32(r, &v->Size);
36-
rd_reader_read_le32(r, &v->TimeDateStamp);
37-
rd_reader_read_le16(r, &v->MajorVersion);
38-
rd_reader_read_le16(r, &v->MinorVersion);
39-
rd_reader_read_le32(r, &v->GlobalFlagsClear);
40-
rd_reader_read_le32(r, &v->GlobalFlagsSet);
41-
rd_reader_read_le32(r, &v->CriticalSectionDefaultTimeout);
42-
rd_reader_read_le64(r, &v->DeCommitFreeBlockThreshold);
43-
rd_reader_read_le64(r, &v->DeCommitTotalFreeThreshold);
44-
rd_reader_read_le64(r, &v->LockPrefixTable);
45-
rd_reader_read_le64(r, &v->MaximumAllocationSize);
46-
rd_reader_read_le64(r, &v->VirtualMemoryThreshold);
47-
rd_reader_read_le64(r, &v->ProcessAffinityMask);
48-
rd_reader_read_le64(r, &v->ProcessHeapFlags);
49-
rd_reader_read_le16(r, &v->CSDVersion);
50-
rd_reader_read_le16(r, &v->Reserved1);
51-
rd_reader_read_le64(r, &v->EditList);
52-
rd_reader_read_le64(r, &v->SecurityCookie);
53-
rd_reader_read_le64(r, &v->SEHandlerTable);
54-
rd_reader_read_le64(r, &v->SEHandlerCount);
55-
rd_reader_read_le64(r, &v->GuardCFCheckFunctionPointer);
56-
rd_reader_read_le64(r, &v->Reserved2);
57-
rd_reader_read_le64(r, &v->GuardCFFunctionTable);
58-
rd_reader_read_le64(r, &v->GuardCFFunctionCount);
59-
rd_reader_read_le32(r, &v->GuardFlags);
50+
if(rd_reader_has_error(r) || v->Size < 4) return false;
51+
52+
if(v->Size >= 112) {
53+
rd_reader_read_le32(r, &v->TimeDateStamp);
54+
rd_reader_read_le16(r, &v->MajorVersion);
55+
rd_reader_read_le16(r, &v->MinorVersion);
56+
rd_reader_read_le32(r, &v->GlobalFlagsClear);
57+
rd_reader_read_le32(r, &v->GlobalFlagsSet);
58+
rd_reader_read_le32(r, &v->CriticalSectionDefaultTimeout);
59+
rd_reader_read_le64(r, &v->DeCommitFreeBlockThreshold);
60+
rd_reader_read_le64(r, &v->DeCommitTotalFreeThreshold);
61+
rd_reader_read_le64(r, &v->LockPrefixTable);
62+
rd_reader_read_le64(r, &v->MaximumAllocationSize);
63+
rd_reader_read_le64(r, &v->VirtualMemoryThreshold);
64+
rd_reader_read_le64(r, &v->ProcessAffinityMask);
65+
rd_reader_read_le32(r, &v->ProcessHeapFlags);
66+
rd_reader_read_le16(r, &v->CSDVersion);
67+
rd_reader_read_le16(r, &v->Reserved1);
68+
rd_reader_read_le64(r, &v->EditList);
69+
rd_reader_read_le64(r, &v->SecurityCookie);
70+
}
71+
72+
if(v->Size >= 148) {
73+
rd_reader_read_le64(r, &v->SEHandlerTable);
74+
rd_reader_read_le64(r, &v->SEHandlerCount);
75+
rd_reader_read_le64(r, &v->GuardCFCheckFunctionPointer);
76+
rd_reader_read_le64(r, &v->Reserved2);
77+
rd_reader_read_le64(r, &v->GuardCFFunctionTable);
78+
rd_reader_read_le64(r, &v->GuardCFFunctionCount);
79+
}
80+
81+
if(v->Size >= 152) rd_reader_read_le32(r, &v->GuardFlags);
6082

6183
return !rd_reader_has_error(r);
6284
}

‎mz/pe/dirs/config.h‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ typedef struct PELoadConfigDirectory32 {
77
u16 MajorVersion, MinorVersion;
88
u32 GlobalFlagsClear, GlobalFlagsSet, CriticalSectionDefaultTimeout;
99
u32 DeCommitFreeBlockThreshold, DeCommitTotalFreeThreshold;
10-
u32 LockPrefixTable; // VA
10+
u32 LockPrefixTable;
1111
u32 MaximumAllocationSize, VirtualMemoryThreshold;
1212
u32 ProcessHeapFlags, ProcessAffinityMask;
1313
u16 CSDVersion, Reserved1;
14-
u32 EditList; // VA
15-
u32 SecurityCookie; // VA
16-
u32 SEHandlerTable; // VA
14+
u32 EditList;
15+
u32 SecurityCookie;
16+
u32 SEHandlerTable;
1717
u32 SEHandlerCount;
18-
u32 GuardCFCheckFunctionPointer; // VA
18+
u32 GuardCFCheckFunctionPointer;
1919
u32 Reserved2;
20-
u32 GuardCFFunctionTable; // VA
20+
u32 GuardCFFunctionTable;
2121
u32 GuardCFFunctionCount, GuardFlags;
2222
} PELoadConfigDirectory32;
2323

@@ -26,17 +26,18 @@ typedef struct PELoadConfigDirectory64 {
2626
u16 MajorVersion, MinorVersion;
2727
u32 GlobalFlagsClear, GlobalFlagsSet, CriticalSectionDefaultTimeout;
2828
u64 DeCommitFreeBlockThreshold, DeCommitTotalFreeThreshold;
29-
u64 LockPrefixTable; // VA
29+
u64 LockPrefixTable;
3030
u64 MaximumAllocationSize, VirtualMemoryThreshold;
31-
u64 ProcessAffinityMask, ProcessHeapFlags;
31+
u64 ProcessAffinityMask;
32+
u32 ProcessHeapFlags;
3233
u16 CSDVersion, Reserved1;
33-
u64 EditList; // VA
34-
u64 SecurityCookie; // VA
35-
u64 SEHandlerTable; // VA
34+
u64 EditList;
35+
u64 SecurityCookie;
36+
u64 SEHandlerTable;
3637
u64 SEHandlerCount;
37-
u64 GuardCFCheckFunctionPointer; // VA
38+
u64 GuardCFCheckFunctionPointer;
3839
u64 Reserved2;
39-
u64 GuardCFFunctionTable; // VA
40+
u64 GuardCFFunctionTable;
4041
u64 GuardCFFunctionCount;
4142
u32 GuardFlags;
4243
} PELoadConfigDirectory64;

0 commit comments

Comments
 (0)