Tuesday, June 11, 2019

Windows PE and PDB file format

PE = Program executable
PDB = program database. This file contains information such as symbols information to help troubleshoot the PE file.

windbg (windows debugger) matches the PE file with the PDB file by using a signature that is unique. This signature information is generated by the linker.
The signature is made up of the timestamp  + the pdb age in the older version of pdb format.
In the newer version of the pdb (version 7), the signature is made of the guid  + the pdb age.
guid is much more unique than the timestamp. The pdb age is a integer that gets incremented every time the pdb gets changed.

Useful tools to help display information about the PE file format:
PE Studio   https://www.winitor.com/


PE View     http://wjradburn.com/software/

Here is a tutorial on how to check the debug type of a PE file using the PE view program.
In figure 1, a DLL file is opened using the PE view program. We want to know what is the debug type of the DLL file. For more information about debug type, please check the MSFT link below.
To see where is the debug type information is stored in the file, we first need to check the image optional header (2). Since the DLL file is compiled with debug information, we should see debug directory information in the image optional header (3). The file offset containing the debug directory information is at offset 000001D8 and it has a RVA value of 03756260. The debug directory size is 54.
 Figure 1.

Expand the .rdata section in Figure 2, we see that the image_debug_directory section is starting at RVA 03756260. This is the same RVA value as shown in Figure 1.

Figure 2.

If we change the view from RVA to view offset (1) in Figure3, we will see that each section will start at 0x0 (2) instead of at 03756260 as in Figure 1. In the offset view, the debug type value can be read at offset 0xC, and its value is set to 2, IMAGE_DEBUG_TYPE_CODEVIEW (3). The view offset can be handy if you don't want to remember or deal with the complicate offset values displayed in the file offset or RVA view. You can just move file cursor to the beginning of a section using the file offset value and read x number of bytes as the size of the debug directory indicated in Figure 1. Once you read the whole section into an array, you can start reading each field in the section using the offset value shown in the  view offset. For example, the value of the Pointer to Raw Data field can be read using offset 0x18.

Figure 3.

As illustrated in Figure 3, we can continue to move to the file cursor using the file offset value from the "Pointer to Raw Data" field. This will allow us to read the IMAGE_DEBUG_TYPE_CODEVIEW section which contains more information about the pdb file format. In figure 4, the file offset for IMAGE_DEBUG_TYPE_CODEVIEW is the same as the value for "Pointer to Raw Data" field in figure 3.

Figure 4.

Please check the MSFT PE format documentation to see information about the fields included in a section (1). In this case, the PE signature value for this DLL file is RSDS (2) indicating that the PDB 7.0 version file format.

Excellent links to more information:
http://www.debuginfo.com/articles/debuginfomatch.html  -- excellent article
http://www.debuginfo.com/articles/gendebuginfo.html
http://www.godevtool.com/Other/pdb.htm  -- understanding the format of PDB file
http://bytepointer.com/resources/pecoff_v4.1.htm
https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#optional-header-image-only  -- MSFT documentation of PE file format.

No comments: