Skip to content

Commit

Permalink
Merge pull request #41 from Danking555/main
Browse files Browse the repository at this point in the history
PEB Parsing
  • Loading branch information
skelsec authored Aug 15, 2024
2 parents a5f200f + e0a9a5f commit 23769ed
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 2 deletions.
51 changes: 50 additions & 1 deletion minidump/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MINIDUMP_STREAM_TYPE(enum.Enum):
ceStreamDiagnosisList = 37
LastReservedStream = 0xffff


class MINIDUMP_TYPE(enum.IntFlag):
MiniDumpNormal = 0x00000000
MiniDumpWithDataSegs = 0x00000001
Expand All @@ -63,4 +64,52 @@ class MINIDUMP_TYPE(enum.IntFlag):
MiniDumpWithTokenInformation = 0x00040000
MiniDumpWithModuleHeaders = 0x00080000
MiniDumpFilterTriage = 0x00100000
MiniDumpValidTypeFlags = 0x001fffff
MiniDumpValidTypeFlags = 0x001fffff


OFFSETS = [
{ # x86 offsets
# _TEB offsets
"peb": 0x30,
# _PEB offsets
"being_debugged": 0x2,
"image_base_address": 0x8,
"process_parameters": 0x10,
# _RTL_USER_PROCESS_PARAMETERS offsets
"image_path": 0x38,
"command_line": 0x40,
"window_title": 0x70,
"dll_path": 0x30,
"current_directory": 0x24,
"standard_input": 0x18,
"standard_output": 0x1C,
"standard_error": 0x20,
"environment_variables": 0x48,
# _UNICODE_STRING offsets
"buffer": 0x4,
},
{ # x64 offsets
# _TEB offsets
"peb": 0x60,
# _PEB offsets
"being_debugged": 0x2,
"image_base_address": 0x10,
"process_parameters": 0x20,
# _RTL_USER_PROCESS_PARAMETERS offsets
"image_path": 0x60,
"command_line": 0x70,
"window_title": 0xB0,
"dll_path": 0x50,
"current_directory": 0x38,
"standard_input": 0x20,
"standard_output": 0x28,
"standard_error": 0x30,
"environment_variables": 0x80,
# _UNICODE_STRING offsets
"buffer": 0x8,
},
]


POINTER_SIZE = [4, 8] # x86 (32 bit size pointer) # x64 (64 bit size pointer)

78 changes: 77 additions & 1 deletion minidump/minidumpfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from minidump.minidumpreader import MinidumpFileReader
from minidump.streams import *
from minidump.common_structs import *
from minidump.constants import MINIDUMP_STREAM_TYPE
from minidump.constants import MINIDUMP_STREAM_TYPE, OFFSETS, POINTER_SIZE
from minidump.directory import MINIDUMP_DIRECTORY
from minidump.streams.SystemInfoStream import PROCESSOR_ARCHITECTURE

Expand Down Expand Up @@ -78,6 +78,82 @@ def get_reader(self):
def _parse(self):
self.__parse_header()
self.__parse_directories()
self.__parse_peb()

def __read_unicode_string_property(self, buff_reader, addr, x64):
buff_reader.move(addr)
string_length = int.from_bytes(buff_reader.read(2), "little")
if not string_length:
return ""
buff_reader.move(addr + OFFSETS[x64]["buffer"])
buff_va = int.from_bytes(buff_reader.read(POINTER_SIZE[x64]), "little")
buff_reader.move(buff_va)
return buff_reader.read(string_length).decode("utf-16")

def __parse_peb(self):
self.x64 = (self.memory_segments_64 is not None) or (self.memory_segments and any(mem.start_virtual_address > 0xFFFFFFFF for mem in self.memory_segments))
offset_index = self.x64

reader = self.get_reader()
buff_reader = reader.get_buffered_reader()

buff_reader.move(self.threads.threads[0].Teb + OFFSETS[offset_index]["peb"])

self.peb_address = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

buff_reader.move(self.peb_address + OFFSETS[offset_index]["being_debugged"])
self.being_debugged = int.from_bytes(buff_reader.read(1), "little")

buff_reader.move(self.peb_address + OFFSETS[offset_index]["image_base_address"])
self.image_base_address = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

buff_reader.move(self.peb_address + OFFSETS[offset_index]["process_parameters"])
process_parameters = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

self.image_path = self.__read_unicode_string_property(
buff_reader, process_parameters + OFFSETS[offset_index]["image_path"], self.x64
)

self.command_line = self.__read_unicode_string_property(
buff_reader, process_parameters + OFFSETS[offset_index]["command_line"], self.x64
)

self.window_title = self.__read_unicode_string_property(
buff_reader, process_parameters + OFFSETS[offset_index]["window_title"], self.x64
)

self.dll_path = self.__read_unicode_string_property(buff_reader, process_parameters + OFFSETS[offset_index]["dll_path"],
self.x64)

self.current_directory = self.__read_unicode_string_property(
buff_reader, process_parameters + OFFSETS[offset_index]["current_directory"], self.x64
)

buff_reader.move(process_parameters + OFFSETS[offset_index]["standard_input"])
self.standard_input = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

buff_reader.move(process_parameters + OFFSETS[offset_index]["standard_output"])
self.standard_output = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

buff_reader.move(process_parameters + OFFSETS[offset_index]["standard_error"])
self.standard_error = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")

# Parse Environment Variables from PEB
self.environment_variables = []
buff_reader.move(process_parameters + OFFSETS[offset_index]["environment_variables"])
environment_va = int.from_bytes(buff_reader.read(POINTER_SIZE[self.x64]), "little")
buff_reader.move(environment_va)

env_buffer = buff_reader.read(buff_reader.current_segment.end_address - buff_reader.current_position)
while (env_len := env_buffer.find(b"\x00\x00")) and (env_len != -1):
decoded_env = (env_buffer[:env_len] + b"\x00").decode("utf-16")
name = decoded_env.split("=")[0]
value = decoded_env.split("=")[1]
self.environment_variables.append({"name": name, "value": value})
environment_va += (len(decoded_env) + 1) * 2
buff_reader.move(environment_va)
env_buffer = buff_reader.read(buff_reader.current_segment.end_address - buff_reader.current_position)


def __parse_header(self):
self.header = MinidumpHeader.parse(self.file_handle)
Expand Down

0 comments on commit 23769ed

Please sign in to comment.