Pdbconv: Use both pefile and volatility to get the guid

This commit is contained in:
Mike Auty
2020-12-01 01:21:36 +00:00
committed by ikelos
parent 65310eb841
commit d77399b82b
+27 -10
View File
@@ -3,6 +3,7 @@
#
import binascii
import io
import json
import logging
import lzma
@@ -16,6 +17,7 @@ from volatility.framework import constants, interfaces
from volatility.framework.configuration.requirements import SymbolTableRequirement
from volatility.framework.symbols import intermed
from volatility.framework.symbols.windows import pdbconv
from volatility.framework.symbols.windows.extensions import pe
vollog = logging.getLogger(__name__)
@@ -124,21 +126,36 @@ class PDBUtility:
if mz_sig != b"MZ":
return None
nt_header_start = ord(layer.read(offset + 0x3C, 1))
optional_header_size = struct.unpack('<H', layer.read(offset + nt_header_start + 0x14, 2))[0]
# Just enough to tell us the max size
pe_header = layer.read(offset, nt_header_start + 0x16 + optional_header_size)
pe_data = pefile.PE(data = pe_header)
max_size = pe_data.OPTIONAL_HEADER.SizeOfImage
pe_table_name = intermed.IntermediateSymbolTable.create(context,
'pdbutility',
"windows",
"pe",
class_types = pe.class_types)
dos_header = context.object(pe_table_name + constants.BANG + '_IMAGE_DOS_HEADER', offset = offset,
layer_name = layer_name)
mz_data = io.BytesIO()
for offset, data in dos_header.reconstruct():
mz_data.seek(offset)
mz_data.write(data)
mz_data = bytes(mz_data.getbuffer())
pe_data = pefile.PE(data = mz_data)
# Proper data
pe_header = layer.read(offset, max_size)
pe_data = pefile.PE(data = pe_header)
if not hasattr(pe_data, 'DIRECTORY_ENTRY_DEBUG') or not len(pe_data.DIRECTORY_ENTRY_DEBUG):
return None
# Extract the data
debug_entry = pe_data.DIRECTORY_ENTRY_DEBUG[0].entry
debug_data = pe_data.DIRECTORY_ENTRY_DEBUG[0]
# We don't fix up subvalues in reconstruction
# This resets the PointerToRawData to the AddressOfRawData
pe_data.set_dword_at_offset(debug_data.struct.get_field_absolute_offset('PointerToRawData'),
debug_data.struct.AddressOfRawData)
debug_entry = debug_data.entry
if debug_entry is None:
return None
pdb_name = debug_entry.PdbFileName.decode("utf-8").strip('\x00')
age = debug_entry.Age
guid = "{:x}{:x}{:x}{}".format(debug_entry.Signature_Data1, debug_entry.Signature_Data2,