diff options
| author | Theofilos Augoustis <theofilos.augoustis@gmail.com> | 2025-10-14 09:09:29 +0000 |
|---|---|---|
| committer | Theofilos Augoustis <theofilos.augoustis@gmail.com> | 2025-10-14 09:09:29 +0000 |
| commit | 579cf1d03fb932083e6317967d1613d5c2587fb6 (patch) | |
| tree | 629f039935382a2a7391bce9253f6c9968159049 /miasm/loader/minidump_init.py | |
| parent | 51c15d3ea2e16d4fc5f0f01a3b9befc66b1f982e (diff) | |
| download | focaccia-miasm-579cf1d03fb932083e6317967d1613d5c2587fb6.tar.gz focaccia-miasm-579cf1d03fb932083e6317967d1613d5c2587fb6.zip | |
Convert to src-layout ta/nix
Diffstat (limited to 'miasm/loader/minidump_init.py')
| -rw-r--r-- | miasm/loader/minidump_init.py | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/miasm/loader/minidump_init.py b/miasm/loader/minidump_init.py deleted file mode 100644 index dd37f730..00000000 --- a/miasm/loader/minidump_init.py +++ /dev/null @@ -1,194 +0,0 @@ -""" -High-level abstraction of Minidump file -""" -from builtins import range -import struct - -from miasm.loader.strpatchwork import StrPatchwork -from miasm.loader import minidump as mp - - -class MemorySegment(object): - """Stand for a segment in memory with additional information""" - - def __init__(self, offset, memory_desc, module=None, memory_info=None): - self.offset = offset - self.memory_desc = memory_desc - self.module = module - self.memory_info = memory_info - self.minidump = self.memory_desc.parent_head - - @property - def address(self): - return self.memory_desc.StartOfMemoryRange - - @property - def size(self): - if isinstance(self.memory_desc, mp.MemoryDescriptor64): - return self.memory_desc.DataSize - elif isinstance(self.memory_desc, mp.MemoryDescriptor): - return self.memory_desc.Memory.DataSize - raise TypeError - - @property - def name(self): - if not self.module: - return "" - name = mp.MinidumpString.unpack(self.minidump._content, - self.module.ModuleNameRva.rva, - self.minidump) - return b"".join( - struct.pack("B", x) for x in name.Buffer - ).decode("utf-16") - - @property - def content(self): - return self.minidump._content[self.offset:self.offset + self.size] - - @property - def protect(self): - if self.memory_info: - return self.memory_info.Protect - return None - - @property - def pretty_protect(self): - if self.protect is None: - return "UNKNOWN" - return mp.memProtect[self.protect] - - -class Minidump(object): - """Stand for a Minidump file - - Here is a few limitation: - - only < 4GB Minidump are supported (LocationDescriptor handling) - - only Stream relative to memory mapping are implemented - - Official description is available on MSDN: - https://msdn.microsoft.com/en-us/library/ms680378(VS.85).aspx - """ - - _sex = 0 - _wsize = 32 - - def __init__(self, minidump_str): - self._content = StrPatchwork(minidump_str) - - # Specific streams - self.modulelist = None - self.memory64list = None - self.memorylist = None - self.memoryinfolist = None - self.systeminfo = None - - # Get information - self.streams = [] - self.threads = None - self.parse_content() - - # Memory information - self.memory = {} # base address (virtual) -> Memory information - self.build_memory() - - def parse_content(self): - """Build structures corresponding to current content""" - - # Header - offset = 0 - self.minidumpHDR = mp.MinidumpHDR.unpack(self._content, offset, self) - assert self.minidumpHDR.Magic == 0x504d444d - - # Streams - base_offset = self.minidumpHDR.StreamDirectoryRva.rva - empty_stream = mp.StreamDirectory( - StreamType=0, - Location=mp.LocationDescriptor( - DataSize=0, - Rva=mp.Rva(rva=0) - ) - ) - streamdir_size = len(empty_stream) - for i in range(self.minidumpHDR.NumberOfStreams): - stream_offset = base_offset + i * streamdir_size - stream = mp.StreamDirectory.unpack(self._content, stream_offset, self) - self.streams.append(stream) - - # Launch specific action depending on the stream - datasize = stream.Location.DataSize - offset = stream.Location.Rva.rva - if stream.StreamType == mp.streamType.ModuleListStream: - self.modulelist = mp.ModuleList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.MemoryListStream: - self.memorylist = mp.MemoryList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.Memory64ListStream: - self.memory64list = mp.Memory64List.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.MemoryInfoListStream: - self.memoryinfolist = mp.MemoryInfoList.unpack(self._content, offset, self) - elif stream.StreamType == mp.streamType.SystemInfoStream: - self.systeminfo = mp.SystemInfo.unpack(self._content, offset, self) - - # Some streams need the SystemInfo stream to work - for stream in self.streams: - datasize = stream.Location.DataSize - offset = stream.Location.Rva.rva - if (self.systeminfo is not None and - stream.StreamType == mp.streamType.ThreadListStream): - self.threads = mp.ThreadList.unpack(self._content, offset, self) - - - def build_memory(self): - """Build an easier to use memory view based on ModuleList and - Memory64List streams""" - - addr2module = dict((module.BaseOfImage, module) - for module in (self.modulelist.Modules if - self.modulelist else [])) - addr2meminfo = dict((memory.BaseAddress, memory) - for memory in (self.memoryinfolist.MemoryInfos if - self.memoryinfolist else [])) - - mode64 = self.minidumpHDR.Flags & mp.minidumpType.MiniDumpWithFullMemory - - if mode64: - offset = self.memory64list.BaseRva - memranges = self.memory64list.MemoryRanges - else: - memranges = self.memorylist.MemoryRanges - - for memory in memranges: - if not mode64: - offset = memory.Memory.Rva.rva - - # Create a MemorySegment with augmented information - base_address = memory.StartOfMemoryRange - module = addr2module.get(base_address, None) - meminfo = addr2meminfo.get(base_address, None) - self.memory[base_address] = MemorySegment(offset, memory, - module, meminfo) - - if mode64: - offset += memory.DataSize - - # Sanity check - if mode64: - assert all(addr in self.memory for addr in addr2module) - - def get(self, virt_start, virt_stop): - """Return the content at the (virtual addresses) - [virt_start:virt_stop]""" - - # Find the corresponding memory segment - for addr in self.memory: - if virt_start <= addr <= virt_stop: - break - else: - return b"" - - memory = self.memory[addr] - shift = addr - virt_start - last = virt_stop - addr - if last > memory.size: - raise RuntimeError("Multi-page not implemented") - - return self._content[memory.offset + shift:memory.offset + last] |