HyperDbg Debugger
Loading...
Searching...
No Matches
test-pe-parser.cpp File Reference

Test cases for PE parser helpers. More...

#include "pch.h"

Functions

BOOLEAN TestPeParser ()
 Runs all PE parser unit tests and reports pass/fail results.

Detailed Description

Test cases for PE parser helpers.

Author
jtaw5649
Version
0.19
Date
2026-06-01

Function Documentation

◆ TestPeParser()

BOOLEAN TestPeParser ( )

Runs all PE parser unit tests and reports pass/fail results.

Each numbered test case exercises a distinct behaviour of the PE image reader:

  1. A valid PE32+ image initialises successfully and reports 64-bit.
  2. A valid PE32 image initialises successfully and reports 32-bit.
  3. A corrupt DOS magic causes initialisation to fail.
  4. An optional header that is one byte too small causes initialisation to fail.
  5. An e_lfanew value that points past the buffer causes initialisation to fail.
  6. A valid section RVA maps to the correct raw file offset.
  7. Header-range RVA resolution is enforced at SizeOfHeaders boundaries.
  8. An 8-byte section name is always returned null-terminated.
  9. An RVA whose raw mapping extends outside the file is rejected.
Returns
BOOLEAN TRUE if all tests pass, FALSE if any test fails
214{
215 BOOLEAN OverallResult = TRUE;
216 INT32 TestNum = 0;
217 BYTE Buffer[PeFixtureSize] = {0};
218
219 BuildMinimalPe64(Buffer);
220 TestNum++;
221 {
222 PE_IMAGE_READER Reader = {0};
223
224 if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && !PeImageReaderIs32Bit(&Reader))
225 {
226 printf("[+] Test number %d Passed\n", TestNum);
227 }
228 else
229 {
230 printf("[-] Test number %d Failed\n", TestNum);
231 printf("[x] valid PE64 did not initialize as PE32+\n");
232 return FALSE;
233 }
234 }
235
236 BuildMinimalPe32(Buffer);
237 TestNum++;
238 {
239 PE_IMAGE_READER Reader = {0};
240
241 if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && PeImageReaderIs32Bit(&Reader))
242 {
243 printf("[+] Test number %d Passed\n", TestNum);
244 }
245 else
246 {
247 printf("[-] Test number %d Failed\n", TestNum);
248 printf("[x] valid PE32 did not initialize as PE32\n");
249 return FALSE;
250 }
251 }
252
253 BuildMinimalPe64(Buffer);
254 WriteWord(Buffer, 0, 0);
255 TestNum++;
256 {
257 PE_IMAGE_READER Reader = {0};
258
259 if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
260 {
261 printf("[+] Test number %d Passed\n", TestNum);
262 }
263 else
264 {
265 printf("[-] Test number %d Failed\n", TestNum);
266 printf("[x] invalid DOS magic initialized successfully\n");
267 return FALSE;
268 }
269 }
270
271 BuildMinimalPe64(Buffer);
272 WriteWord(Buffer,
273 PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
274 sizeof(IMAGE_OPTIONAL_HEADER64) - 1);
275 TestNum++;
276 {
277 PE_IMAGE_READER Reader = {0};
278
279 if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
280 {
281 printf("[+] Test number %d Passed\n", TestNum);
282 }
283 else
284 {
285 printf("[-] Test number %d Failed\n", TestNum);
286 printf("[x] truncated optional header initialized successfully\n");
287 return FALSE;
288 }
289 }
290
291 BuildMinimalPe64(Buffer);
292 WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeFixtureSize);
293 TestNum++;
294 {
295 PE_IMAGE_READER Reader = {0};
296
297 if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
298 {
299 printf("[+] Test number %d Passed\n", TestNum);
300 }
301 else
302 {
303 printf("[-] Test number %d Failed\n", TestNum);
304 printf("[x] invalid e_lfanew initialized successfully\n");
305 return FALSE;
306 }
307 }
308
309 BuildMinimalPe64(Buffer);
310 SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
311 ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x50, 0x1c0, 0x40);
312 TestNum++;
313 {
314 PE_IMAGE_READER Reader = {0};
315 SIZE_T FileOffset = 0;
316
317 if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
318 PeImageReaderRvaToFileOffset(&Reader, 0x1010, 4, &FileOffset) && FileOffset == 0x1d0)
319 {
320 printf("[+] Test number %d Passed\n", TestNum);
321 }
322 else
323 {
324 printf("[-] Test number %d Failed\n", TestNum);
325 printf("[x] valid section RVA did not map to raw file offset\n");
326 return FALSE;
327 }
328 }
329
330 BuildMinimalPe64(Buffer);
331 SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
332 TestNum++;
333 {
334 PE_IMAGE_READER Reader = {0};
335 SIZE_T FileOffset = 0;
336
337 if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
338 PeImageReaderRvaToFileOffset(&Reader, 0x20, 4, &FileOffset) && FileOffset == 0x20 &&
339 !PeImageReaderRvaToFileOffset(&Reader, 0x1be, 4, &FileOffset))
340 {
341 printf("[+] Test number %d Passed\n", TestNum);
342 }
343 else
344 {
345 printf("[-] Test number %d Failed\n", TestNum);
346 printf("[x] header RVA bounds were not enforced\n");
347 return FALSE;
348 }
349 }
350
351 TestNum++;
352 {
353 IMAGE_SECTION_HEADER SectionHeader = {0};
354 CHAR Name[9];
355
356 FillMemory(Name, sizeof(Name), 'X');
357 CopyMemory(SectionHeader.Name, "ABCDEFGH", IMAGE_SIZEOF_SHORT_NAME);
358 if (PeImageReaderGetSectionName(&SectionHeader, Name, sizeof(Name)) &&
359 strcmp(Name, "ABCDEFGH") == 0 && Name[IMAGE_SIZEOF_SHORT_NAME] == '\0')
360 {
361 printf("[+] Test number %d Passed\n", TestNum);
362 }
363 else
364 {
365 printf("[-] Test number %d Failed\n", TestNum);
366 printf("[x] 8-byte section name was not null-terminated\n");
367 return FALSE;
368 }
369 }
370
371 BuildMinimalPe64(Buffer);
372 SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
373 ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x40, 0x300, 0x20);
374 TestNum++;
375 {
376 PE_IMAGE_READER Reader = {0};
377 SIZE_T FileOffset = 0;
378
379 if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
380 !PeImageReaderRvaToFileOffset(&Reader, 0x1000, 1, &FileOffset))
381 {
382 printf("[+] Test number %d Passed\n", TestNum);
383 }
384 else
385 {
386 printf("[-] Test number %d Failed\n", TestNum);
387 printf("[x] RVA mapping accepted raw pointer outside file\n");
388 OverallResult = FALSE;
389 }
390 }
391
392 return OverallResult;
393}
signed int INT32
Definition BasicTypes.h:50
UCHAR BOOLEAN
Definition BasicTypes.h:35
unsigned char BYTE
Definition BasicTypes.h:40
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned long DWORD
Definition BasicTypes.h:38
char CHAR
Definition BasicTypes.h:33
printf("ho")
BOOLEAN PeImageReaderIs32Bit(PPE_IMAGE_READER Reader)
Returns whether the PE image is a 32-bit (PE32) image.
Definition pe-image-reader.cpp:194
BOOLEAN PeImageReaderRvaToFileOffset(PPE_IMAGE_READER Reader, DWORD Rva, DWORD Length, PSIZE_T FileOffset)
Translates a relative virtual address (RVA) to a raw file offset.
Definition pe-image-reader.cpp:287
BOOLEAN PeImageReaderGetSectionName(const IMAGE_SECTION_HEADER *SectionHeader, CHAR *NameBuffer, SIZE_T NameBufferSize)
Copies the section name from a section header into a null-terminated buffer.
Definition pe-image-reader.cpp:244
BOOLEAN PeImageReaderInitialize(const BYTE *ImageBase, SIZE_T ImageSize, PPE_IMAGE_READER Reader)
Parses and validates all PE headers in an in-memory image buffer.
Definition pe-image-reader.cpp:94
struct _PE_IMAGE_READER PE_IMAGE_READER
struct _IMAGE_FILE_HEADER IMAGE_FILE_HEADER
struct _IMAGE_DOS_HEADER IMAGE_DOS_HEADER
#define IMAGE_SIZEOF_SHORT_NAME
Definition pe-image-reader.h:51
struct _IMAGE_SECTION_HEADER IMAGE_SECTION_HEADER
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition pe-image-reader.h:55