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 /src/miasm/loader/minidump.py | |
| parent | 51c15d3ea2e16d4fc5f0f01a3b9befc66b1f982e (diff) | |
| download | focaccia-miasm-579cf1d03fb932083e6317967d1613d5c2587fb6.tar.gz focaccia-miasm-579cf1d03fb932083e6317967d1613d5c2587fb6.zip | |
Convert to src-layout ta/nix
Diffstat (limited to 'src/miasm/loader/minidump.py')
| -rw-r--r-- | src/miasm/loader/minidump.py | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/src/miasm/loader/minidump.py b/src/miasm/loader/minidump.py new file mode 100644 index 00000000..c16473b4 --- /dev/null +++ b/src/miasm/loader/minidump.py @@ -0,0 +1,545 @@ +"""Constants and structures associated to Minidump format +Based on: http://amnesia.gtisc.gatech.edu/~moyix/minidump.py +""" +from future.utils import viewitems + +from future.builtins import int as int_types +from miasm.loader.new_cstruct import CStruct + +class Enumeration(object): + """Stand for an enumeration type""" + + def __init__(self, enum_info): + """enum_info: {name: value}""" + self._enum_info = enum_info + self._inv_info = dict((v, k) for k, v in viewitems(enum_info)) + + def __getitem__(self, key): + """Helper: assume that string is for key, integer is for value""" + if isinstance(key, int_types): + return self._inv_info[key] + return self._enum_info[key] + + def __getattr__(self, key): + if key in self._enum_info: + return self._enum_info[key] + raise AttributeError + + def from_value(self, value): + return self._inv_info[value] + + +class Rva(CStruct): + """Relative Virtual Address + Note: RVA in Minidump means "file offset" + """ + _fields = [("rva", "u32"), + ] + + +minidumpType = Enumeration({ + # MINIDUMP_TYPE + # https://msdn.microsoft.com/en-us/library/ms680519(v=vs.85).aspx + "MiniDumpNormal" : 0x00000000, + "MiniDumpWithDataSegs" : 0x00000001, + "MiniDumpWithFullMemory" : 0x00000002, + "MiniDumpWithHandleData" : 0x00000004, + "MiniDumpFilterMemory" : 0x00000008, + "MiniDumpScanMemory" : 0x00000010, + "MiniDumpWithUnloadedModules" : 0x00000020, + "MiniDumpWithIndirectlyReferencedMemory" : 0x00000040, + "MiniDumpFilterModulePaths" : 0x00000080, + "MiniDumpWithProcessThreadData" : 0x00000100, + "MiniDumpWithPrivateReadWriteMemory" : 0x00000200, + "MiniDumpWithoutOptionalData" : 0x00000400, + "MiniDumpWithFullMemoryInfo" : 0x00000800, + "MiniDumpWithThreadInfo" : 0x00001000, + "MiniDumpWithCodeSegs" : 0x00002000, + "MiniDumpWithoutAuxiliaryState" : 0x00004000, + "MiniDumpWithFullAuxiliaryState" : 0x00008000, + "MiniDumpWithPrivateWriteCopyMemory" : 0x00010000, + "MiniDumpIgnoreInaccessibleMemory" : 0x00020000, + "MiniDumpWithTokenInformation" : 0x00040000, + "MiniDumpWithModuleHeaders" : 0x00080000, + "MiniDumpFilterTriage" : 0x00100000, + "MiniDumpValidTypeFlags" : 0x001fffff, +}) + +class MinidumpHDR(CStruct): + """MINIDUMP_HEADER + https://msdn.microsoft.com/en-us/library/ms680378(VS.85).aspx + """ + _fields = [("Magic", "u32"), # MDMP + ("Version", "u16"), + ("ImplementationVersion", "u16"), + ("NumberOfStreams", "u32"), + ("StreamDirectoryRva", "Rva"), + ("Checksum", "u32"), + ("TimeDateStamp", "u32"), + ("Flags", "u32") + ] + +class LocationDescriptor(CStruct): + """MINIDUMP_LOCATION_DESCRIPTOR + https://msdn.microsoft.com/en-us/library/ms680383(v=vs.85).aspx + """ + _fields = [("DataSize", "u32"), + ("Rva", "Rva"), + ] + + +streamType = Enumeration({ + # MINIDUMP_STREAM_TYPE + # https://msdn.microsoft.com/en-us/library/ms680394(v=vs.85).aspx + "UnusedStream" : 0, + "ReservedStream0" : 1, + "ReservedStream1" : 2, + "ThreadListStream" : 3, + "ModuleListStream" : 4, + "MemoryListStream" : 5, + "ExceptionStream" : 6, + "SystemInfoStream" : 7, + "ThreadExListStream" : 8, + "Memory64ListStream" : 9, + "CommentStreamA" : 10, + "CommentStreamW" : 11, + "HandleDataStream" : 12, + "FunctionTableStream" : 13, + "UnloadedModuleListStream" : 14, + "MiscInfoStream" : 15, + "MemoryInfoListStream" : 16, + "ThreadInfoListStream" : 17, + "HandleOperationListStream" : 18, + "LastReservedStream" : 0xffff, +}) + +class StreamDirectory(CStruct): + """MINIDUMP_DIRECTORY + https://msdn.microsoft.com/en-us/library/ms680365(VS.85).aspx + """ + _fields = [("StreamType", "u32"), + ("Location", "LocationDescriptor"), + ] + + @property + def pretty_name(self): + return streamType[self.StreamType] + + +class FixedFileInfo(CStruct): + """VS_FIXEDFILEINFO + https://msdn.microsoft.com/en-us/library/ms646997(v=vs.85).aspx + """ + _fields = [("dwSignature", "u32"), + ("dwStrucVersion", "u32"), + ("dwFileVersionMS", "u32"), + ("dwFileVersionLS", "u32"), + ("dwProductVersionMS", "u32"), + ("dwProductVersionLS", "u32"), + ("dwFileFlagsMask", "u32"), + ("dwFileFlags", "u32"), + ("dwFileOS", "u32"), + ("dwFileType", "u32"), + ("dwFileSubtype", "u32"), + ("dwFileDateMS", "u32"), + ("dwFileDateLS", "u32"), + ] + +class MinidumpString(CStruct): + """MINIDUMP_STRING + https://msdn.microsoft.com/en-us/library/ms680395(v=vs.85).aspx + """ + _fields = [("Length", "u32"), + ("Buffer", "u08", lambda string:string.Length), + ] + +class Module(CStruct): + """MINIDUMP_MODULE + https://msdn.microsoft.com/en-us/library/ms680392(v=vs.85).aspx + """ + _fields = [("BaseOfImage", "u64"), + ("SizeOfImage", "u32"), + ("CheckSum", "u32"), + ("TimeDateStamp", "u32"), + ("ModuleNameRva", "Rva"), + ("VersionInfo", "FixedFileInfo"), + ("CvRecord", "LocationDescriptor"), + ("MiscRecord", "LocationDescriptor"), + ("Reserved0", "u64"), + ("Reserved1", "u64"), + ] + + +class ModuleList(CStruct): + """MINIDUMP_MODULE_LIST + https://msdn.microsoft.com/en-us/library/ms680391(v=vs.85).aspx + """ + _fields = [("NumberOfModules", "u32"), + ("Modules", "Module", lambda mlist:mlist.NumberOfModules), + ] + + +class MemoryDescriptor64(CStruct): + """MINIDUMP_MEMORY_DESCRIPTOR64 + https://msdn.microsoft.com/en-us/library/ms680384(v=vs.85).aspx + """ + _fields = [("StartOfMemoryRange", "u64"), + ("DataSize", "u64") + ] + + +class Memory64List(CStruct): + """MINIDUMP_MEMORY64_LIST + https://msdn.microsoft.com/en-us/library/ms680387(v=vs.85).aspx + """ + _fields = [("NumberOfMemoryRanges", "u64"), + ("BaseRva", "u64"), + ("MemoryRanges", "MemoryDescriptor64", + lambda mlist:mlist.NumberOfMemoryRanges), + ] + +class MemoryDescriptor(CStruct): + """MINIDUMP_MEMORY_DESCRIPTOR + https://msdn.microsoft.com/en-us/library/ms680384(v=vs.85).aspx + """ + _fields = [("StartOfMemoryRange", "u64"), + ("Memory", "LocationDescriptor"), + ] + +class MemoryList(CStruct): + """MINIDUMP_MEMORY_LIST + https://msdn.microsoft.com/en-us/library/ms680387(v=vs.85).aspx + """ + _fields = [("NumberOfMemoryRanges", "u32"), + ("MemoryRanges", "MemoryDescriptor", + lambda mlist:mlist.NumberOfMemoryRanges), + ] + +memProtect = Enumeration({ + # MEM PROTECT + # https://msdn.microsoft.com/en-us/library/aa366786(v=vs.85).aspx + "PAGE_NOACCESS" : 0x0001, + "PAGE_READONLY" : 0x0002, + "PAGE_READWRITE" : 0x0004, + "PAGE_WRITECOPY" : 0x0008, + "PAGE_EXECUTE" : 0x0010, + "PAGE_EXECUTE_READ" : 0x0020, + "PAGE_EXECUTE_READWRITE" : 0x0040, + "PAGE_EXECUTE_WRITECOPY" : 0x0080, + "PAGE_GUARD" : 0x0100, + "PAGE_NOCACHE" : 0x0200, + "PAGE_WRITECOMBINE" : 0x0400, +}) + +class MemoryInfo(CStruct): + """MINIDUMP_MEMORY_INFO + https://msdn.microsoft.com/en-us/library/ms680386(v=vs.85).aspx + """ + _fields = [("BaseAddress", "u64"), + ("AllocationBase", "u64"), + ("AllocationProtect", "u32"), + ("__alignment1", "u32"), + ("RegionSize", "u64"), + ("State", "u32"), + ("Protect", "u32"), + ("Type", "u32"), + ("__alignment2", "u32"), + ] + +class MemoryInfoList(CStruct): + """MINIDUMP_MEMORY_INFO_LIST + https://msdn.microsoft.com/en-us/library/ms680385(v=vs.85).aspx + """ + _fields = [("SizeOfHeader", "u32"), + ("SizeOfEntry", "u32"), + ("NumberOfEntries", "u64"), + # Fake field, for easy access to MemoryInfo elements + ("MemoryInfos", "MemoryInfo", + lambda mlist: mlist.NumberOfEntries), + ] + + +contextFlags_x86 = Enumeration({ + "CONTEXT_i386" : 0x00010000, + "CONTEXT_CONTROL" : 0x00010001, + "CONTEXT_INTEGER" : 0x00010002, + "CONTEXT_SEGMENTS" : 0x00010004, + "CONTEXT_FLOATING_POINT" : 0x00010008, + "CONTEXT_DEBUG_REGISTERS" : 0x00010010, + "CONTEXT_EXTENDED_REGISTERS" : 0x00010020, +}) + +class FloatingSaveArea(CStruct): + """FLOATING_SAVE_AREA + http://terminus.rewolf.pl/terminus/structures/ntdll/_FLOATING_SAVE_AREA_x86.html + """ + _fields = [("ControlWord", "u32"), + ("StatusWord", "u32"), + ("TagWord", "u32"), + ("ErrorOffset", "u32"), + ("ErrorSelector", "u32"), + ("DataOffset", "u32"), + ("DataSelector", "u32"), + ("RegisterArea", "80s"), + ("Cr0NpxState", "u32"), + ] + +class Context_x86(CStruct): + """CONTEXT x86 + https://msdn.microsoft.com/en-us/en-en/library/ms679284(v=vs.85).aspx + http://terminus.rewolf.pl/terminus/structures/ntdll/_CONTEXT_x86.html + """ + + MAXIMUM_SUPPORTED_EXTENSION = 512 + + def is_activated(flag): + mask = contextFlags_x86[flag] + def check_context(ctx): + if (ctx.ContextFlags & mask == mask): + return 1 + return 0 + return check_context + + _fields = [("ContextFlags", "u32"), + # DebugRegisters + ("Dr0", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr1", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr2", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr3", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr6", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr7", "u32", is_activated("CONTEXT_DEBUG_REGISTERS")), + + ("FloatSave", "FloatingSaveArea", + is_activated("CONTEXT_FLOATING_POINT")), + + # SegmentRegisters + ("SegGs", "u32", is_activated("CONTEXT_SEGMENTS")), + ("SegFs", "u32", is_activated("CONTEXT_SEGMENTS")), + ("SegEs", "u32", is_activated("CONTEXT_SEGMENTS")), + ("SegDs", "u32", is_activated("CONTEXT_SEGMENTS")), + # IntegerRegisters + ("Edi", "u32", is_activated("CONTEXT_INTEGER")), + ("Esi", "u32", is_activated("CONTEXT_INTEGER")), + ("Ebx", "u32", is_activated("CONTEXT_INTEGER")), + ("Edx", "u32", is_activated("CONTEXT_INTEGER")), + ("Ecx", "u32", is_activated("CONTEXT_INTEGER")), + ("Eax", "u32", is_activated("CONTEXT_INTEGER")), + # ControlRegisters + ("Ebp", "u32", is_activated("CONTEXT_CONTROL")), + ("Eip", "u32", is_activated("CONTEXT_CONTROL")), + ("SegCs", "u32", is_activated("CONTEXT_CONTROL")), + ("EFlags", "u32", is_activated("CONTEXT_CONTROL")), + ("Esp", "u32", is_activated("CONTEXT_CONTROL")), + ("SegSs", "u32", is_activated("CONTEXT_CONTROL")), + + ("ExtendedRegisters", "%ds" % MAXIMUM_SUPPORTED_EXTENSION, + is_activated("CONTEXT_EXTENDED_REGISTERS")), + ] + + +contextFlags_AMD64 = Enumeration({ + "CONTEXT_AMD64" : 0x00100000, + "CONTEXT_CONTROL" : 0x00100001, + "CONTEXT_INTEGER" : 0x00100002, + "CONTEXT_SEGMENTS" : 0x00100004, + "CONTEXT_FLOATING_POINT" : 0x00100008, + "CONTEXT_DEBUG_REGISTERS" : 0x00100010, + "CONTEXT_XSTATE" : 0x00100020, + "CONTEXT_EXCEPTION_ACTIVE" : 0x08000000, + "CONTEXT_SERVICE_ACTIVE" : 0x10000000, + "CONTEXT_EXCEPTION_REQUEST" : 0x40000000, + "CONTEXT_EXCEPTION_REPORTING" : 0x80000000, +}) + + +class M128A(CStruct): + """M128A + http://terminus.rewolf.pl/terminus/structures/ntdll/_M128A_x64.html + """ + _fields = [("Low", "u64"), + ("High", "u64"), + ] + +class Context_AMD64(CStruct): + """CONTEXT AMD64 + https://github.com/duarten/Threadjack/blob/master/WinNT.h + """ + + def is_activated(flag): + mask = contextFlags_AMD64[flag] + def check_context(ctx): + if (ctx.ContextFlags & mask == mask): + return 1 + return 0 + return check_context + + _fields = [ + + # Only used for Convenience + ("P1Home", "u64"), + ("P2Home", "u64"), + ("P3Home", "u64"), + ("P4Home", "u64"), + ("P5Home", "u64"), + ("P6Home", "u64"), + + # Control + ("ContextFlags", "u32"), + ("MxCsr", "u32"), + + # Segment & processor + # [!] activation depends on multiple flags + ("SegCs", "u16", is_activated("CONTEXT_CONTROL")), + ("SegDs", "u16", is_activated("CONTEXT_SEGMENTS")), + ("SegEs", "u16", is_activated("CONTEXT_SEGMENTS")), + ("SegFs", "u16", is_activated("CONTEXT_SEGMENTS")), + ("SegGs", "u16", is_activated("CONTEXT_SEGMENTS")), + ("SegSs", "u16", is_activated("CONTEXT_CONTROL")), + ("EFlags", "u32", is_activated("CONTEXT_CONTROL")), + + # Debug registers + ("Dr0", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr1", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr2", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr3", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr6", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + ("Dr7", "u64", is_activated("CONTEXT_DEBUG_REGISTERS")), + + # Integer registers + # [!] activation depends on multiple flags + ("Rax", "u64", is_activated("CONTEXT_INTEGER")), + ("Rcx", "u64", is_activated("CONTEXT_INTEGER")), + ("Rdx", "u64", is_activated("CONTEXT_INTEGER")), + ("Rbx", "u64", is_activated("CONTEXT_INTEGER")), + ("Rsp", "u64", is_activated("CONTEXT_CONTROL")), + ("Rbp", "u64", is_activated("CONTEXT_INTEGER")), + ("Rsi", "u64", is_activated("CONTEXT_INTEGER")), + ("Rdi", "u64", is_activated("CONTEXT_INTEGER")), + ("R8", "u64", is_activated("CONTEXT_INTEGER")), + ("R9", "u64", is_activated("CONTEXT_INTEGER")), + ("R10", "u64", is_activated("CONTEXT_INTEGER")), + ("R11", "u64", is_activated("CONTEXT_INTEGER")), + ("R12", "u64", is_activated("CONTEXT_INTEGER")), + ("R13", "u64", is_activated("CONTEXT_INTEGER")), + ("R14", "u64", is_activated("CONTEXT_INTEGER")), + ("R15", "u64", is_activated("CONTEXT_INTEGER")), + ("Rip", "u64", is_activated("CONTEXT_CONTROL")), + + # Floating point + ("Header", "M128A", lambda ctx: 2), + ("Legacy", "M128A", lambda ctx: 8), + ("Xmm0", "M128A"), + ("Xmm1", "M128A"), + ("Xmm2", "M128A"), + ("Xmm3", "M128A"), + ("Xmm4", "M128A"), + ("Xmm5", "M128A"), + ("Xmm6", "M128A"), + ("Xmm7", "M128A"), + ("Xmm8", "M128A"), + ("Xmm9", "M128A"), + ("Xmm10", "M128A"), + ("Xmm11", "M128A"), + ("Xmm12", "M128A"), + ("Xmm13", "M128A"), + ("Xmm14", "M128A"), + ("Xmm15", "M128A"), + + + # Vector registers + ("VectorRegister", "M128A", lambda ctx: 16), + ("VectorControl", "u64"), + + # Special debug control regs + ("DebugControl", "u64"), + ("LastBranchToRip", "u64"), + ("LastBranchFromRip", "u64"), + ("LastExceptionToRip", "u64"), + ("LastExceptionFromRip", "u64"), + ] + +processorArchitecture = Enumeration({ + "PROCESSOR_ARCHITECTURE_X86" : 0, + "PROCESSOR_ARCHITECTURE_MIPS" : 1, + "PROCESSOR_ARCHITECTURE_ALPHA" : 2, + "PROCESSOR_ARCHITECTURE_PPC" : 3, + "PROCESSOR_ARCHITECTURE_SHX" : 4, + "PROCESSOR_ARCHITECTURE_ARM" : 5, + "PROCESSOR_ARCHITECTURE_IA64" : 6, + "PROCESSOR_ARCHITECTURE_ALPHA64" : 7, + "PROCESSOR_ARCHITECTURE_MSIL" : 8, + "PROCESSOR_ARCHITECTURE_AMD64" : 9, + "PROCESSOR_ARCHITECTURE_X86_WIN64" : 10, + "PROCESSOR_ARCHITECTURE_UNKNOWN" : 0xffff, +}) + +class Thread(CStruct): + """MINIDUMP_THREAD + https://msdn.microsoft.com/en-us/library/ms680517(v=vs.85).aspx + """ + + arch2context_cls = { + processorArchitecture.PROCESSOR_ARCHITECTURE_X86: Context_x86, + processorArchitecture.PROCESSOR_ARCHITECTURE_AMD64: Context_AMD64, + } + + def parse_context(self, content, offset): + loc_desc = LocationDescriptor.unpack(content, offset, self.parent_head) + + # Use the correct context depending on architecture + systeminfo = self.parent_head.systeminfo + context_cls = self.arch2context_cls.get(systeminfo.ProcessorArchitecture, + None) + if context_cls is None: + raise ValueError("Unsupported architecture: %s" % systeminfo.pretty_processor_architecture) + + ctxt = context_cls.unpack(content, loc_desc.Rva.rva, self.parent_head) + fake_loc_descriptor = LocationDescriptor(DataSize=0, Rva=Rva(rva=0)) + return ctxt, offset + len(fake_loc_descriptor) + + _fields = [("ThreadId", "u32"), + ("SuspendCount", "u32"), + ("PriorityClass", "u32"), + ("Priority", "u32"), + ("Teb", "u64"), + ("Stack", "MemoryDescriptor"), + ("ThreadContext", (parse_context, + lambda thread, value: NotImplemented)), + ] + +class ThreadList(CStruct): + """MINIDUMP_THREAD_LIST + https://msdn.microsoft.com/en-us/library/ms680515(v=vs.85).aspx + """ + _fields = [("NumberOfThreads", "u32"), + ("Threads", "Thread", + lambda mlist: mlist.NumberOfThreads), + ] + + +class SystemInfo(CStruct): + """MINIDUMP_SYSTEM_INFO + https://msdn.microsoft.com/en-us/library/ms680396(v=vs.85).aspx + """ + _fields = [("ProcessorArchitecture", "u16"), + ("ProcessorLevel", "u16"), + ("ProcessorRevision", "u16"), + ("NumberOfProcessors", "u08"), + ("ProductType", "u08"), + ("MajorVersion", "u32"), + ("MinorVersion", "u32"), + ("BuildNumber", "u32"), + ("PlatformId", "u32"), + ("CSDVersionRva", "Rva"), + ("SuiteMask", "u16"), + ("Reserved2", "u16"), + ("VendorId", "u32", lambda sinfo: 3), + ("VersionInformation", "u32"), + ("FeatureInformation", "u32"), + ("AMDExtendedCpuFeatures", "u32"), + ] + + @property + def pretty_processor_architecture(self): + return processorArchitecture[self.ProcessorArchitecture] + |