├── MinidumpLoader ├── Module.manifest ├── ghidra_scripts │ └── README.txt ├── src │ ├── main │ │ ├── resources │ │ │ └── images │ │ │ │ └── README.txt │ │ ├── java │ │ │ └── net │ │ │ │ └── jubjubnest │ │ │ │ └── minidump │ │ │ │ ├── contrib │ │ │ │ ├── pe │ │ │ │ │ ├── package.html │ │ │ │ │ ├── resource │ │ │ │ │ │ ├── package.html │ │ │ │ │ │ ├── ResourceStringInfo.java │ │ │ │ │ │ ├── ResourceDirectoryStringU.java │ │ │ │ │ │ └── ResourceDirectoryString.java │ │ │ │ │ ├── OffsetValidator.java │ │ │ │ │ ├── InvalidNTHeaderException.java │ │ │ │ │ ├── MachineName.java │ │ │ │ │ ├── debug │ │ │ │ │ │ ├── S_COMPILE.java │ │ │ │ │ │ ├── S_BLOCK32.java │ │ │ │ │ │ ├── S_END.java │ │ │ │ │ │ ├── OMFAlignSym.java │ │ │ │ │ │ ├── S_ALIGN.java │ │ │ │ │ │ ├── UnknownSymbol.java │ │ │ │ │ │ ├── S_CONSTANT32.java │ │ │ │ │ │ ├── S_UDT32_NEW.java │ │ │ │ │ │ ├── DebugSymbol.java │ │ │ │ │ │ ├── S_DATAREF.java │ │ │ │ │ │ ├── S_UDT32.java │ │ │ │ │ │ ├── S_GDATA32_NEW.java │ │ │ │ │ │ ├── S_LABEL32.java │ │ │ │ │ │ ├── OMFLibrary.java │ │ │ │ │ │ ├── S_BPREL32_NEW.java │ │ │ │ │ │ ├── S_OBJNAME.java │ │ │ │ │ │ ├── S_LDATA32_NEW.java │ │ │ │ │ │ ├── OMFDirEntry.java │ │ │ │ │ │ ├── DataSym32.java │ │ │ │ │ │ ├── DebugFixupElement.java │ │ │ │ │ │ ├── DataSym32_new.java │ │ │ │ │ │ └── DebugFixup.java │ │ │ │ │ ├── rich │ │ │ │ │ │ ├── MSProductType.java │ │ │ │ │ │ ├── RichHeaderUtils.java │ │ │ │ │ │ ├── RichProduct.java │ │ │ │ │ │ ├── RichHeaderRecord.java │ │ │ │ │ │ ├── CompId.java │ │ │ │ │ │ ├── MSRichProductInfoDataType.java │ │ │ │ │ │ └── RichTableRecordDataType.java │ │ │ │ │ ├── cli │ │ │ │ │ │ ├── CliRepresentable.java │ │ │ │ │ │ ├── tables │ │ │ │ │ │ │ ├── CliAbstractTableRow.java │ │ │ │ │ │ │ ├── indexes │ │ │ │ │ │ │ │ ├── CliIndexHasSemantics.java │ │ │ │ │ │ │ │ ├── CliIndexHasFieldMarshall.java │ │ │ │ │ │ │ │ ├── CliIndexMemberForwarded.java │ │ │ │ │ │ │ │ ├── CliIndexMethodDefOrRef.java │ │ │ │ │ │ │ │ ├── CliIndexTypeOrMethodDef.java │ │ │ │ │ │ │ │ ├── CliIndexHasConstant.java │ │ │ │ │ │ │ │ ├── CliIndexTypeDefOrRef.java │ │ │ │ │ │ │ │ ├── CliIndexCustomAttributeType.java │ │ │ │ │ │ │ │ ├── CliIndexHasDeclSecurity.java │ │ │ │ │ │ │ │ ├── CliIndexImplementation.java │ │ │ │ │ │ │ │ ├── CliIndexResolutionScope.java │ │ │ │ │ │ │ │ ├── CliIndexMemberRefParent.java │ │ │ │ │ │ │ │ ├── CliCodedIndexUtils.java │ │ │ │ │ │ │ │ └── CliIndexHasCustomAttribute.java │ │ │ │ │ │ │ ├── CliTableAssemblyProcessor.java │ │ │ │ │ │ │ ├── CliTableModuleRef.java │ │ │ │ │ │ │ ├── CliTableFieldRVA.java │ │ │ │ │ │ │ ├── CliTableFieldLayout.java │ │ │ │ │ │ │ ├── CliTableAssemblyRefProcessor.java │ │ │ │ │ │ │ ├── CliTableAssemblyOS.java │ │ │ │ │ │ │ ├── CliTableEventMap.java │ │ │ │ │ │ │ ├── CliTableClassLayout.java │ │ │ │ │ │ │ ├── CliTypeTable.java │ │ │ │ │ │ │ ├── CliTableNestedClass.java │ │ │ │ │ │ │ ├── CliTablePropertyMap.java │ │ │ │ │ │ │ ├── CliTableParam.java │ │ │ │ │ │ │ └── CliTableAssemblyRefOS.java │ │ │ │ │ │ └── blobs │ │ │ │ │ │ │ ├── CliSigTypeSpec.java │ │ │ │ │ │ │ └── CliSigField.java │ │ │ │ │ ├── ROMHeader.java │ │ │ │ │ ├── PeMarkupable.java │ │ │ │ │ ├── DelayImportInfo.java │ │ │ │ │ ├── ImportInfo.java │ │ │ │ │ ├── DefaultDataDirectory.java │ │ │ │ │ └── ExportInfo.java │ │ │ │ └── new_ │ │ │ │ │ ├── ModuleBaseOffset32DataType.java │ │ │ │ │ ├── ModuleBaseOffset64DataType.java │ │ │ │ │ ├── ImageLoadInfo.java │ │ │ │ │ ├── ModuleBaseMap.java │ │ │ │ │ └── AbstractModuleBaseOffsetDataType.java │ │ │ │ ├── data │ │ │ │ ├── ThreadContext.java │ │ │ │ └── ObjectMapResolver.java │ │ │ │ ├── plugin │ │ │ │ ├── MinidumpPluginPackage.java │ │ │ │ ├── ModuleListItem.java │ │ │ │ ├── ModuleList.java │ │ │ │ ├── parser │ │ │ │ │ ├── RuntimeFunction.java │ │ │ │ │ └── RuntimeInfo.java │ │ │ │ ├── ModuleListModel.java │ │ │ │ ├── StackListItem.java │ │ │ │ ├── ModuleViewPlugin.java │ │ │ │ ├── StackList.java │ │ │ │ └── ThreadViewPlugin.java │ │ │ │ ├── loader │ │ │ │ └── parser │ │ │ │ │ ├── MinidumpMemoryDescriptor.java │ │ │ │ │ ├── StringReader.java │ │ │ │ │ ├── MinidumpLocationDescriptor.java │ │ │ │ │ ├── MinidumpThread.java │ │ │ │ │ ├── MinidumpMemory64Descriptor.java │ │ │ │ │ ├── MinidumpModuleList.java │ │ │ │ │ ├── MinidumpThreadList.java │ │ │ │ │ ├── MinidumpHeader.java │ │ │ │ │ ├── MinidumpMemoryInfoList.java │ │ │ │ │ ├── MinidumpMemory64List.java │ │ │ │ │ ├── VsFixedFileInfo.java │ │ │ │ │ ├── ThreadInformationBlock.java │ │ │ │ │ ├── MinidumpMemoryInfo.java │ │ │ │ │ └── MinidumpModule.java │ │ │ │ └── analyzer │ │ │ │ ├── SymbolInfo.java │ │ │ │ ├── SubTaskMonitor.java │ │ │ │ ├── FindSymbolsFileChooser.java │ │ │ │ └── ModuleParser.java │ │ └── help │ │ │ └── help │ │ │ └── topics │ │ │ └── minidumploader │ │ │ └── help.html │ └── test │ │ └── java │ │ └── README.test.txt ├── extension.properties ├── lib │ └── README.txt ├── os │ ├── linux64 │ │ └── README.txt │ ├── osx64 │ │ └── README.txt │ └── win64 │ │ └── README.txt ├── data │ └── README.txt └── build.gradle ├── .gitignore ├── images └── readme.png ├── NOTICE └── README.md /MinidumpLoader/Module.manifest: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.metadata 2 | /*/.project 3 | /*/.settings 4 | /*/bin 5 | -------------------------------------------------------------------------------- /images/readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rantanen/ghidra-minidump-loader/HEAD/images/readme.png -------------------------------------------------------------------------------- /MinidumpLoader/ghidra_scripts/README.txt: -------------------------------------------------------------------------------- 1 | Java source directory to hold module-specific Ghidra scripts. 2 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/resources/images/README.txt: -------------------------------------------------------------------------------- 1 | The "src/resources/images" directory is intended to hold all image/icon files used by 2 | this module. 3 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Classes for parsing PE headers. 4 | 5 | 6 | -------------------------------------------------------------------------------- /MinidumpLoader/extension.properties: -------------------------------------------------------------------------------- 1 | name=@extname@ 2 | description=Tools for analyzing Windows Minidump files. 3 | author=Mikko Rantanen 4 | createdOn= 5 | version=@extversion@ 6 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/resource/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Classes for parsing PE resource data structures. 4 | 5 | 6 | -------------------------------------------------------------------------------- /MinidumpLoader/src/test/java/README.test.txt: -------------------------------------------------------------------------------- 1 | The "test" directory is intended to hold unit test cases. The package structure within 2 | this folder should correspond to that found in the "src" folder. 3 | -------------------------------------------------------------------------------- /MinidumpLoader/lib/README.txt: -------------------------------------------------------------------------------- 1 | The "lib" directory is intended to hold Jar files which this module 2 | is dependent upon. This directory may be eliminated from a specific 3 | module if no other Jar files are needed. 4 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/data/ThreadContext.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.data; 2 | 3 | public interface ThreadContext { 4 | 5 | public int getType(); 6 | public byte[] toBytes(); 7 | } 8 | -------------------------------------------------------------------------------- /MinidumpLoader/os/linux64/README.txt: -------------------------------------------------------------------------------- 1 | The "os/linux64" directory is intended to hold Linux native binaries 2 | which this module is dependent upon. This directory may be eliminated for a specific 3 | module if native binaries are not provided for the corresponding platform. 4 | -------------------------------------------------------------------------------- /MinidumpLoader/os/osx64/README.txt: -------------------------------------------------------------------------------- 1 | The "os/osx64" directory is intended to hold macOS (OS X) native binaries 2 | which this module is dependent upon. This directory may be eliminated for a specific 3 | module if native binaries are not provided for the corresponding platform. 4 | -------------------------------------------------------------------------------- /MinidumpLoader/os/win64/README.txt: -------------------------------------------------------------------------------- 1 | The "os/win64" directory is intended to hold MS Windows native binaries (.exe) 2 | which this module is dependent upon. This directory may be eliminated for a specific 3 | module if native binaries are not provided for the corresponding platform. 4 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/MinidumpPluginPackage.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import javax.swing.Icon; 4 | 5 | import ghidra.framework.plugintool.util.PluginPackage; 6 | import resources.ResourceManager; 7 | 8 | public class MinidumpPluginPackage extends PluginPackage { 9 | public static final String NAME = "Minidump"; 10 | 11 | protected MinidumpPluginPackage(String name, Icon icon, String description) { 12 | super(NAME, ResourceManager.loadImage("images/vcard.png"), 13 | "Plugins for working with Windows Minidump files."); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/ModuleListItem.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import ghidra.program.model.address.Address; 4 | import ghidra.program.model.listing.Program; 5 | import net.jubjubnest.minidump.data.ModuleData; 6 | 7 | class ModuleListItem { 8 | 9 | public String name; 10 | public Address baseAddress; 11 | public String symbolPath; 12 | public boolean symbolsLoaded; 13 | 14 | public ModuleListItem(Program program, ModuleData data) { 15 | this.name = data.name; 16 | this.symbolPath = data.loadedSymbols; 17 | this.symbolsLoaded = data.loadedSymbols != null; 18 | this.baseAddress = data.baseAddress; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Ghidra Minidump Loader 2 | 3 | The Ghidra Minidump Loader is released under Apache License, Version 2.0. 4 | 5 | Copyright 2020 Mikko Rantanen and Contributors. 6 | 7 | --- 8 | 9 | Ghidra 10 | 11 | This product includes software developed at National Security Agency 12 | (https://www.nsa.gov) 13 | 14 | Portions of this product were created by the U.S. Government and not subject to 15 | U.S. copyright protections under 17 U.S.C. 16 | 17 | The remaining portions are copyright their respective authors and have been 18 | contributed under the terms of one or more open source licenses, and made 19 | available to you under the terms of those licenses. (See LICENSE) 20 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpMemoryDescriptor.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class MinidumpMemoryDescriptor { 6 | 7 | public static final int RECORD_SIZE = 8 + MinidumpLocationDescriptor.RECORD_SIZE; 8 | 9 | public static MinidumpMemoryDescriptor parse(ByteBuffer byteBuffer) { 10 | var mem = new MinidumpMemoryDescriptor(); 11 | 12 | mem.startOfMemoryRange = byteBuffer.getLong(); 13 | mem.memory = MinidumpLocationDescriptor.parse(byteBuffer); 14 | 15 | return mem; 16 | } 17 | 18 | public long startOfMemoryRange; 19 | public MinidumpLocationDescriptor memory; 20 | } 21 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/analyzer/SymbolInfo.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.analyzer; 2 | 3 | import ghidra.app.util.pdb.PdbProgramAttributes; 4 | import net.jubjubnest.minidump.analyzer.PdbResolver.PdbResult; 5 | import net.jubjubnest.minidump.data.ModuleData; 6 | 7 | class SymbolInfo { 8 | 9 | SymbolInfo(ModuleData m, PdbProgramAttributes attributes, PdbResult result) { 10 | if (m == null || attributes == null) { 11 | throw new IllegalArgumentException(); 12 | } 13 | 14 | module = m; 15 | this.attributes = attributes; 16 | if (result != null) { 17 | this.result = result; 18 | } 19 | } 20 | 21 | ModuleData module; 22 | PdbProgramAttributes attributes; 23 | PdbResult result; 24 | String message; 25 | } -------------------------------------------------------------------------------- /MinidumpLoader/data/README.txt: -------------------------------------------------------------------------------- 1 | The "data" directory is intended to hold data files that will be used by this module and will 2 | not end up in the .jar file, but will be present in the zip or tar file. Typically, data 3 | files are placed here rather than in the resources directory if the user may need to edit them. 4 | 5 | An optional data/languages directory can exist for the purpose of containing various Sleigh language 6 | specification files and importer opinion files. 7 | 8 | The data/buildLanguage.xml is used for building the contents of the data/languages directory. 9 | 10 | The skel language definition has been commented-out within the skel.ldefs file so that the 11 | skeleton language does not show-up within Ghidra. 12 | 13 | See the Sleigh language documentation (docs/languages/index.html) for details Sleigh language 14 | specification syntax. 15 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/ModuleList.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import java.util.List; 4 | 5 | import docking.widgets.table.GTable; 6 | import ghidra.program.model.listing.Program; 7 | 8 | class ModuleList extends GTable { 9 | 10 | private List items; 11 | private ModuleListModel model; 12 | 13 | public ModuleList() { 14 | } 15 | 16 | public void setFrames(List items, Program program) { 17 | 18 | this.items = items; 19 | model = new ModuleListModel(items); 20 | this.setModel(model); 21 | } 22 | 23 | public ModuleListItem getModule(int idx) { 24 | return items.get(idx); 25 | } 26 | 27 | @Override 28 | public boolean isCellEditable(int row, int column) { 29 | return false; 30 | } 31 | 32 | @Override 33 | public boolean getColumnSelectionAllowed() { 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/OffsetValidator.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe; 18 | 19 | public interface OffsetValidator { 20 | 21 | public boolean checkPointer(long ptr); 22 | 23 | public boolean checkRVA(long rva); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/StringReader.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | import java.nio.charset.Charset; 7 | 8 | import ghidra.app.util.bin.ByteProvider; 9 | 10 | public class StringReader { 11 | public static String readString(long offset, ByteProvider provider) throws IOException { 12 | var headerBytes = provider.readBytes(offset, 4); 13 | var byteBuffer = ByteBuffer.wrap(headerBytes); 14 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 15 | 16 | var size = byteBuffer.getInt(); 17 | if (size % 2 == 1) 18 | throw new IOException("Invalid string data"); 19 | 20 | var dataBytes = provider.readBytes(offset + 4, size); 21 | var charset = Charset.forName("UTF-16LE"); 22 | var dataBuffer = ByteBuffer.wrap(dataBytes); 23 | return charset.decode(dataBuffer).toString(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/new_/ModuleBaseOffset32DataType.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.contrib.new_; 2 | 3 | import ghidra.program.model.data.DWordDataType; 4 | import ghidra.program.model.data.DataType; 5 | import ghidra.program.model.data.DataTypeManager; 6 | 7 | public class ModuleBaseOffset32DataType extends AbstractModuleBaseOffsetDataType { 8 | 9 | private static DataType datatype = DWordDataType.dataType; 10 | public ModuleBaseOffset32DataType() { 11 | this(null); 12 | } 13 | 14 | public ModuleBaseOffset32DataType(DataTypeManager dtm) { 15 | super(null, generateName(datatype), dtm); 16 | } 17 | 18 | @Override 19 | DataType getScalarDataType() { 20 | return datatype; 21 | } 22 | 23 | @Override 24 | public DataType clone(DataTypeManager dtm) { 25 | if (dtm == getDataTypeManager()) { 26 | return this; 27 | } 28 | 29 | return new ModuleBaseOffset32DataType(dtm); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/new_/ModuleBaseOffset64DataType.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.contrib.new_; 2 | 3 | import ghidra.program.model.data.DataType; 4 | import ghidra.program.model.data.DataTypeManager; 5 | import ghidra.program.model.data.QWordDataType; 6 | 7 | public class ModuleBaseOffset64DataType extends AbstractModuleBaseOffsetDataType { 8 | 9 | private static DataType datatype = QWordDataType.dataType; 10 | public ModuleBaseOffset64DataType() { 11 | this(null); 12 | } 13 | 14 | public ModuleBaseOffset64DataType(DataTypeManager dtm) { 15 | super(null, generateName(datatype), dtm); 16 | } 17 | 18 | @Override 19 | DataType getScalarDataType() { 20 | return datatype; 21 | } 22 | 23 | @Override 24 | public DataType clone(DataTypeManager dtm) { 25 | if (dtm == getDataTypeManager()) { 26 | return this; 27 | } 28 | 29 | return new ModuleBaseOffset64DataType(dtm); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/data/ObjectMapResolver.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.data; 2 | 3 | import ghidra.program.model.listing.Program; 4 | import ghidra.program.model.util.ObjectPropertyMap; 5 | import ghidra.program.model.util.PropertyMapManager; 6 | import ghidra.util.Saveable; 7 | import ghidra.util.exception.DuplicateNameException; 8 | 9 | public class ObjectMapResolver { 10 | 11 | public static ObjectPropertyMap getModuleDataMap(Program program, String name, Class recordClass, boolean create) { 12 | PropertyMapManager manager = program.getUsrPropertyManager(); 13 | ObjectPropertyMap map = manager.getObjectPropertyMap(name); 14 | if (map != null || !create) { 15 | return map; 16 | } 17 | 18 | try { 19 | return manager.createObjectPropertyMap(name, recordClass); 20 | } catch (DuplicateNameException e) { 21 | return manager.getObjectPropertyMap(name); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/InvalidNTHeaderException.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe; 18 | 19 | /** 20 | * An exception class to handle encountering 21 | * invalid NT Headers. 22 | * 23 | * @see net.jubjubnest.minidump.contrib.pe.NTHeader 24 | * 25 | * 26 | */ 27 | public class InvalidNTHeaderException extends Exception { 28 | } 29 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpLocationDescriptor.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | 9 | public class MinidumpLocationDescriptor { 10 | public static final int RECORD_SIZE = 4 + 4; 11 | 12 | public static MinidumpLocationDescriptor parse(long offset, ByteProvider provider) throws IOException { 13 | var bytes = provider.readBytes(offset, RECORD_SIZE); 14 | var byteBuffer = ByteBuffer.wrap(bytes); 15 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 16 | return parse(byteBuffer); 17 | } 18 | 19 | public static MinidumpLocationDescriptor parse(ByteBuffer byteBuffer) { 20 | var descriptor = new MinidumpLocationDescriptor(); 21 | descriptor.size = byteBuffer.getInt(); 22 | descriptor.offset = byteBuffer.getInt(); 23 | return descriptor; 24 | } 25 | 26 | public int size; 27 | public int offset; 28 | } 29 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/MachineName.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe; 18 | 19 | import ghidra.util.Conv; 20 | 21 | /** 22 | * 23 | */ 24 | class MachineName { 25 | 26 | static String getName(short machine) { 27 | return getName(machine & Conv.SHORT_MASK); 28 | } 29 | 30 | static String getName(int machine) { 31 | return new String("" + machine); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_COMPILE.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | /** 20 | * 21 | */ 22 | class S_COMPILE extends DebugSymbol { 23 | 24 | static S_COMPILE createS_COMPILE(short length, short type) { 25 | return new S_COMPILE(length, type); 26 | } 27 | 28 | private S_COMPILE(short length, short type) { 29 | processDebugSymbol(length, type); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_BLOCK32.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | /** 20 | * 21 | */ 22 | class S_BLOCK32 extends DebugSymbol { 23 | 24 | static S_BLOCK32 createS_BLOCK32(short length, short type) { 25 | return new S_BLOCK32(length, type); 26 | } 27 | 28 | private S_BLOCK32(short length, short type) { 29 | processDebugSymbol(length, type); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/help/help/topics/minidumploader/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | Skeleton Help File for a Module 13 | 14 | 15 | 16 | 17 |

Skeleton Help File for a Module

18 | 19 |

This is a simple skeleton help topic. For a better description of what should and should not 20 | go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your 21 | favorite help topic. In general, language modules do not have their own help topics.

22 | 23 | 24 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpThread.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class MinidumpThread { 6 | 7 | public static final int RECORD_SIZE = 4 + 4 + 4 + 4 + 8 + MinidumpMemoryDescriptor.RECORD_SIZE 8 | + MinidumpLocationDescriptor.RECORD_SIZE; 9 | 10 | public static MinidumpThread parse(ByteBuffer byteBuffer) { 11 | var thread = new MinidumpThread(); 12 | 13 | thread.threadId = byteBuffer.getInt(); 14 | thread.suspendCount = byteBuffer.getInt(); 15 | thread.priorityClass = byteBuffer.getInt(); 16 | thread.priority = byteBuffer.getInt(); 17 | thread.teb = byteBuffer.getLong(); 18 | thread.stack = MinidumpMemoryDescriptor.parse(byteBuffer); 19 | thread.threadContext = MinidumpLocationDescriptor.parse(byteBuffer); 20 | 21 | return thread; 22 | } 23 | 24 | public int threadId; 25 | public int suspendCount; 26 | public int priorityClass; 27 | public int priority; 28 | public long teb; 29 | public MinidumpMemoryDescriptor stack; 30 | public MinidumpLocationDescriptor threadContext; 31 | } 32 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpMemory64Descriptor.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | 9 | public class MinidumpMemory64Descriptor { 10 | 11 | public static final int RECORD_SIZE = 8 + 8; 12 | 13 | public static MinidumpMemory64Descriptor parse(long offset, ByteProvider provider, long dataOffset) throws IOException { 14 | var bytes = provider.readBytes(offset, RECORD_SIZE); 15 | var byteBuffer = ByteBuffer.wrap(bytes); 16 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 17 | return parse(byteBuffer, dataOffset); 18 | } 19 | 20 | public static MinidumpMemory64Descriptor parse(ByteBuffer byteBuffer, long dataOffset) { 21 | var descriptor = new MinidumpMemory64Descriptor(); 22 | descriptor.baseAddress = byteBuffer.getLong(); 23 | descriptor.segmentSize = byteBuffer.getLong(); 24 | descriptor.dataOffset = dataOffset; 25 | return descriptor; 26 | } 27 | 28 | public long baseAddress; 29 | public long segmentSize; 30 | public long dataOffset; 31 | } 32 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/MSProductType.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | public enum MSProductType { 19 | CXX_Compiler("C++ Compiler"), 20 | C_Compiler("C Compiler"), 21 | Assembler("Assembler"), 22 | Import("Linker"), 23 | Export("Linker"), 24 | ImportExport("Linker"), 25 | Linker("Linker"), 26 | CVTRes("CVTRes"), 27 | 28 | Unknown("Unknown"); 29 | 30 | private final String desc; 31 | 32 | private MSProductType(String d) { 33 | this.desc = d; 34 | } 35 | 36 | public String toString() { 37 | return desc; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/RichHeaderUtils.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | import java.util.Map; 19 | 20 | public class RichHeaderUtils { 21 | 22 | private static Map richIds = null; 23 | 24 | private RichHeaderUtils() { 25 | // Prevent instantiation of static utility class 26 | } 27 | 28 | public static RichProduct getProduct(int id) { 29 | if (richIds == null) { 30 | richIds = RichProductIdLoader.loadProductIdStore(); 31 | if (richIds == null) { 32 | return null; 33 | } 34 | } 35 | 36 | return richIds.get(id); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/parser/RuntimeFunction.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin.parser; 2 | 3 | import java.io.IOException; 4 | 5 | import ghidra.app.util.bin.BinaryReader; 6 | import ghidra.app.util.bin.ByteProvider; 7 | import ghidra.program.model.address.Address; 8 | 9 | public class RuntimeFunction { 10 | 11 | public Address imageBase; 12 | public Address startOfFunction; 13 | public Address endOfFunction; 14 | public Address runtimeInfo; 15 | 16 | public static RuntimeFunction parse(Address imageBase, BinaryReader reader) throws IOException { 17 | return new RuntimeFunction( 18 | imageBase, 19 | imageBase.add(reader.readNextInt()), 20 | imageBase.add(reader.readNextInt()), 21 | imageBase.add(reader.readNextInt())); 22 | } 23 | 24 | public RuntimeFunction(Address base, Address startFn, Address endFn, Address rtInfo) { 25 | imageBase = base; 26 | startOfFunction = startFn; 27 | endOfFunction = endFn; 28 | runtimeInfo = rtInfo; 29 | } 30 | 31 | public RuntimeInfo readRuntimeInfo(ByteProvider bytes) throws IOException { 32 | BinaryReader reader = new BinaryReader(bytes, true); 33 | reader.setPointerIndex(runtimeInfo.getOffset()); 34 | return RuntimeInfo.parse(imageBase, reader); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/CliRepresentable.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli; 17 | 18 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 19 | 20 | /** 21 | * Describes the methods necessary to get a long and short representation, with or without an metadata stream. 22 | * This is used in the token analyzer to cut down on duplication across modules. 23 | */ 24 | public interface CliRepresentable { 25 | public String getRepresentation(); 26 | public String getShortRepresentation(); 27 | public String getRepresentation(CliStreamMetadata stream); 28 | public String getShortRepresentation(CliStreamMetadata stream); 29 | } 30 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpModuleList.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import ghidra.app.util.bin.ByteProvider; 10 | 11 | public class MinidumpModuleList { 12 | 13 | public static final int DESCRIPTOR_SIZE = 4; 14 | 15 | public static MinidumpModuleList parse(long offset, ByteProvider provider) throws IOException { 16 | var bytes = provider.readBytes(offset, DESCRIPTOR_SIZE); 17 | var byteBuffer = ByteBuffer.wrap(bytes); 18 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 19 | 20 | var list = new MinidumpModuleList(); 21 | list.moduleCount = byteBuffer.getInt(); 22 | 23 | var moduleBytes = provider.readBytes(offset + DESCRIPTOR_SIZE, MinidumpModule.RECORD_SIZE * list.moduleCount); 24 | var moduleBuffer = ByteBuffer.wrap(moduleBytes); 25 | moduleBuffer.order(ByteOrder.LITTLE_ENDIAN); 26 | 27 | var modules = new ArrayList(); 28 | for (int i = 0; i < list.moduleCount; i++) { 29 | modules.add(MinidumpModule.parse(moduleBuffer, provider)); 30 | } 31 | list.modules = modules; 32 | 33 | return list; 34 | } 35 | 36 | public int moduleCount; 37 | public List modules; 38 | } 39 | -------------------------------------------------------------------------------- /MinidumpLoader/build.gradle: -------------------------------------------------------------------------------- 1 | // Builds a Ghidra Extension for a given Ghidra installation. 2 | // 3 | // An absolute path to the Ghidra installation directory must be supplied either by setting the 4 | // GHIDRA_INSTALL_DIR environment variable or Gradle project property: 5 | // 6 | // > export GHIDRA_INSTALL_DIR= 7 | // > gradle 8 | // 9 | // or 10 | // 11 | // > gradle -PGHIDRA_INSTALL_DIR= 12 | // 13 | // Gradle should be invoked from the directory of the project to build. Please see the 14 | // application.gradle.version property in /Ghidra/application.properties 15 | // for the correction version of Gradle to use for the Ghidra installation you specify. 16 | 17 | //----------------------START "DO NOT MODIFY" SECTION------------------------------ 18 | def ghidraInstallDir 19 | 20 | if (System.env.GHIDRA_INSTALL_DIR) { 21 | ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR 22 | } 23 | else if (project.hasProperty("GHIDRA_INSTALL_DIR")) { 24 | ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR") 25 | } 26 | 27 | if (ghidraInstallDir) { 28 | apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle" 29 | } 30 | else { 31 | throw new GradleException("GHIDRA_INSTALL_DIR is not defined!") 32 | } 33 | //----------------------END "DO NOT MODIFY" SECTION------------------------------- 34 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/ModuleListModel.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import java.util.List; 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | 7 | import ghidra.util.exception.NotYetImplementedException; 8 | 9 | class ModuleListModel extends AbstractTableModel { 10 | 11 | private List items; 12 | private String[] headers = new String[] { 13 | "Name", 14 | "Symbols", 15 | }; 16 | 17 | public ModuleListModel(List items) { 18 | this.items = items; 19 | } 20 | 21 | @Override 22 | public String getColumnName(int column) { 23 | return headers[column]; 24 | } 25 | 26 | @Override 27 | public int getRowCount() { 28 | return items.size(); 29 | } 30 | 31 | @Override 32 | public int getColumnCount() { 33 | return 2; 34 | } 35 | 36 | @Override 37 | public Object getValueAt(int rowIndex, int columnIndex) { 38 | ModuleListItem item = items.get(rowIndex); 39 | 40 | switch (columnIndex) { 41 | case 0: 42 | return item.name; 43 | case 1: 44 | if (item.symbolPath == null) { 45 | return "No symbols"; 46 | } 47 | 48 | if (item.symbolsLoaded) { 49 | return "Loaded: " + item.symbolPath; 50 | } 51 | return "Located: " + item.symbolPath; 52 | default: 53 | throw new NotYetImplementedException(); 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpThreadList.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import ghidra.app.util.bin.ByteProvider; 10 | 11 | public class MinidumpThreadList { 12 | 13 | public static final int DESCRIPTOR_SIZE = 4; 14 | 15 | public static MinidumpThreadList parse(long offset, ByteProvider provider) throws IOException { 16 | var bytes = provider.readBytes(offset, DESCRIPTOR_SIZE); 17 | var byteBuffer = ByteBuffer.wrap(bytes); 18 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 19 | 20 | var list = new MinidumpThreadList(); 21 | list.numberOfThreads = byteBuffer.getInt(); 22 | 23 | long entriesStart = offset + DESCRIPTOR_SIZE; 24 | var segmentBytes = provider.readBytes(entriesStart, list.numberOfThreads * MinidumpThread.RECORD_SIZE); 25 | var segmentBuffer = ByteBuffer.wrap(segmentBytes); 26 | segmentBuffer.order(ByteOrder.LITTLE_ENDIAN); 27 | 28 | list.threads = new ArrayList(list.numberOfThreads); 29 | for (int i = 0; i < list.numberOfThreads; i++) { 30 | list.threads.add(MinidumpThread.parse(segmentBuffer)); 31 | } 32 | 33 | return list; 34 | } 35 | 36 | public int numberOfThreads; 37 | public List threads; 38 | } 39 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/ROMHeader.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe; 18 | 19 | /** 20 | * A class to represent the 21 | * IMAGE_ROM_HEADERS 22 | * struct as defined in 23 | * winnt.h. 24 | * 25 | *
26 |  * typedef struct _IMAGE_ROM_HEADERS {
27 |  *    IMAGE_FILE_HEADER FileHeader;
28 |  *    IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
29 |  * } IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
30 |  * 
31 | */ 32 | class ROMHeader { 33 | private FileHeader fileHeader; 34 | private OptionalHeaderROM optionalHeader; 35 | 36 | public FileHeader getFileHeader() { 37 | return fileHeader; 38 | } 39 | public OptionalHeaderROM getOptionalHeader() { 40 | return optionalHeader; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/RichProduct.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | public class RichProduct { 19 | private final CompId compid; 20 | private final String productVersion; 21 | private final MSProductType productType; 22 | 23 | public RichProduct(int compid, String version, MSProductType type) { 24 | this.compid = new CompId(compid); 25 | this.productVersion = version; 26 | this.productType = type; 27 | } 28 | 29 | public CompId getCompid() { 30 | return compid; 31 | } 32 | 33 | public String getProductVersion() { 34 | return productVersion; 35 | } 36 | 37 | public MSProductType getProductType() { 38 | return productType; 39 | } 40 | 41 | public String toString() { 42 | return getProductVersion() + " -- " + getProductType(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/new_/ImageLoadInfo.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.contrib.new_; 2 | 3 | import ghidra.framework.options.Options; 4 | import ghidra.program.model.listing.Program; 5 | import net.jubjubnest.minidump.contrib.pe.PortableExecutable.SectionLayout; 6 | 7 | public class ImageLoadInfo { 8 | public String imageName; 9 | public long imageBase; 10 | public boolean sharedProgram; 11 | public SectionLayout sectionLayout; 12 | 13 | public ImageLoadInfo() { 14 | imageName = null; 15 | imageBase = 0; 16 | sharedProgram = false; 17 | sectionLayout = SectionLayout.FILE; 18 | } 19 | 20 | public ImageLoadInfo(String moduleName, long moduleOffset) { 21 | imageName = moduleName; 22 | imageBase = moduleOffset; 23 | sharedProgram = true; 24 | sectionLayout = SectionLayout.MEMORY; 25 | } 26 | 27 | public String prefixName(String name) { 28 | return name; 29 | 30 | /* 31 | if (sharedProgram == false) 32 | return name; 33 | return imageName.toUpperCase() + "::" + name; 34 | */ 35 | } 36 | 37 | public Options getModuleOptions(Program program) { 38 | Options programOptions = program.getOptions(Program.PROGRAM_INFO); 39 | if (sharedProgram == false) { 40 | return programOptions; 41 | } 42 | 43 | Options moduleOptions = programOptions.getOptions("Module Information"); 44 | return moduleOptions.getOptions(imageName.replace('.', '_')); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpHeader.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | 9 | public class MinidumpHeader { 10 | public static final long RECORD_SIZE = 4 + 2 + 2 + 4 + 4 + 4 + 4 + 8; 11 | 12 | public static MinidumpHeader parse(long offset, ByteProvider provider) throws IOException { 13 | var bytes = provider.readBytes(offset, RECORD_SIZE); 14 | var byteBuffer = ByteBuffer.wrap(bytes); 15 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 16 | return parse(byteBuffer); 17 | } 18 | 19 | public static MinidumpHeader parse(ByteBuffer byteBuffer) { 20 | @SuppressWarnings("unused") 21 | int _signature = byteBuffer.getInt(); 22 | @SuppressWarnings("unused") 23 | short _internalVersion = byteBuffer.getShort(); 24 | 25 | var header = new MinidumpHeader(); 26 | header.version = byteBuffer.getShort(); 27 | header.streamsCount = byteBuffer.getInt(); 28 | header.streamsOffset = byteBuffer.getInt(); 29 | header.checksum = byteBuffer.getInt(); 30 | header.timestamp = byteBuffer.getInt(); 31 | header.flags = byteBuffer.getLong(); 32 | return header; 33 | } 34 | 35 | public int version; 36 | public int streamsCount; 37 | public int streamsOffset; 38 | public int checksum; 39 | public int timestamp; 40 | public long flags; 41 | } 42 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/RichHeaderRecord.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | import net.jubjubnest.minidump.contrib.pe.RichTable; 19 | 20 | /** 21 | * An element of a {@link RichTable} 22 | */ 23 | public class RichHeaderRecord { 24 | 25 | private final int recordIndex; 26 | private final CompId compid; 27 | private final int count; 28 | 29 | public RichHeaderRecord(int recordIndex, int compid, int count) { 30 | this.recordIndex = recordIndex; 31 | this.compid = new CompId(compid); 32 | this.count = count; 33 | } 34 | 35 | public int getIndex() { 36 | return recordIndex; 37 | } 38 | 39 | public CompId getCompId() { 40 | return this.compid; 41 | } 42 | 43 | public int getObjectCount() { 44 | return count; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return compid + " Count: " + count; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/StackListItem.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.ByteOrder; 5 | 6 | import ghidra.program.model.address.Address; 7 | import ghidra.program.model.listing.Program; 8 | import ghidra.program.model.mem.MemoryAccessException; 9 | 10 | class StackListItem { 11 | Address stackPointer; 12 | Address instructionPointer; 13 | Address returnPointer; 14 | long functionOffset; 15 | String module; 16 | 17 | public StackListItem( 18 | Address stackPointer, 19 | Address instructionPointer, 20 | Address returnPointer, 21 | long functionOffset, 22 | String module) { 23 | this.stackPointer = stackPointer; 24 | this.instructionPointer = instructionPointer; 25 | this.returnPointer = returnPointer; 26 | this.functionOffset = functionOffset; 27 | this.module = module; 28 | } 29 | 30 | public Address getReturnAddress(Program program) { 31 | var langDesc = program.getLanguage().getLanguageDescription(); 32 | var ptrSize = langDesc.getSize(); 33 | var buffer = new byte[ptrSize / 8]; 34 | try { 35 | program.getMemory().getBytes(this.returnPointer, buffer); 36 | } catch (MemoryAccessException e) { 37 | return null; 38 | } 39 | 40 | long addr = 0; 41 | var bb = ByteBuffer.wrap(buffer); 42 | bb.order(ByteOrder.LITTLE_ENDIAN); 43 | if (buffer.length == 8) { 44 | addr = bb.getLong(); 45 | } else { 46 | addr = bb.getInt(); 47 | } 48 | return this.returnPointer.getNewAddress(addr); 49 | } 50 | } -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliAbstractTableRow.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import net.jubjubnest.minidump.contrib.pe.cli.CliRepresentable; 19 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 20 | 21 | /** 22 | * Generic Metadata table row. Subclasses should provided implementations for the actual 23 | * table rows. 24 | */ 25 | public abstract class CliAbstractTableRow implements CliRepresentable { 26 | 27 | @Override 28 | public abstract String getRepresentation(); 29 | 30 | @Override 31 | public String getShortRepresentation() { 32 | return getRepresentation(); 33 | } 34 | 35 | @Override 36 | public String getRepresentation(CliStreamMetadata stream) { 37 | return getRepresentation(); 38 | } 39 | 40 | @Override 41 | public String getShortRepresentation(CliStreamMetadata stream) { 42 | return getRepresentation(stream); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_END.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.format.*; 20 | import ghidra.util.*; 21 | 22 | /** 23 | * 24 | */ 25 | class S_END extends DebugSymbol { 26 | 27 | static S_END createS_END(short length, short type, 28 | FactoryBundledWithBinaryReader reader, int ptr) { 29 | S_END s_end = (S_END) reader.getFactory().create(S_END.class); 30 | s_end.initS_END(length, type, reader, ptr); 31 | return s_end; 32 | } 33 | 34 | /** 35 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 36 | */ 37 | public S_END() {} 38 | 39 | private void initS_END(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) { 40 | processDebugSymbol(length, type); 41 | Msg.debug(this, reader.getPointerIndex()+" -- "+ptr); 42 | this.name = "END"; 43 | this.offset = 0; 44 | this.section = 0; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpMemoryInfoList.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import ghidra.app.util.bin.ByteProvider; 10 | 11 | public class MinidumpMemoryInfoList { 12 | 13 | // Memory info list doesn't have fixed size, instead it carries size information 14 | // as part of the data. 15 | 16 | public static MinidumpMemoryInfoList parse(long offset, ByteProvider provider) throws IOException { 17 | var bytes = provider.readBytes(offset, 4 + 4 + 8); 18 | var byteBuffer = ByteBuffer.wrap(bytes); 19 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 20 | 21 | var list = new MinidumpMemoryInfoList(); 22 | list.headerSize = byteBuffer.getInt(); 23 | list.entrySize = byteBuffer.getInt(); 24 | list.entryCount = byteBuffer.getLong(); 25 | 26 | list.descriptors = new ArrayList((int) list.entryCount); 27 | long entriesStart = offset + list.headerSize; 28 | for (int i = 0; i < list.entryCount; i++) { 29 | 30 | var segmentBytes = provider.readBytes(entriesStart + list.entrySize * i, list.entrySize); 31 | var segmentBuffer = ByteBuffer.wrap(segmentBytes); 32 | segmentBuffer.order(ByteOrder.LITTLE_ENDIAN); 33 | 34 | list.descriptors.add(MinidumpMemoryInfo.parse(segmentBuffer)); 35 | } 36 | 37 | return list; 38 | } 39 | 40 | public int headerSize; 41 | public int entrySize; 42 | public long entryCount; 43 | 44 | public List descriptors; 45 | } 46 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpMemory64List.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import ghidra.app.util.bin.ByteProvider; 10 | 11 | public class MinidumpMemory64List { 12 | 13 | public static final int DESCRIPTOR_SIZE = 8 + 8; 14 | 15 | public static MinidumpMemory64List parse(long offset, ByteProvider provider) throws IOException { 16 | var bytes = provider.readBytes(offset, DESCRIPTOR_SIZE); 17 | var byteBuffer = ByteBuffer.wrap(bytes); 18 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 19 | 20 | var list = new MinidumpMemory64List(); 21 | list.memoryRangeCount = byteBuffer.getLong(); 22 | list.dataOffset = byteBuffer.getLong(); 23 | 24 | list.descriptors = new ArrayList((int) list.memoryRangeCount); 25 | var segmentBytes = provider.readBytes(offset + DESCRIPTOR_SIZE, 26 | list.memoryRangeCount * MinidumpMemory64Descriptor.RECORD_SIZE); 27 | var segmentBuffer = ByteBuffer.wrap(segmentBytes); 28 | segmentBuffer.order(ByteOrder.LITTLE_ENDIAN); 29 | 30 | var dataOffset = list.dataOffset; 31 | for (int i = 0; i < list.memoryRangeCount; i++) { 32 | var descriptor = MinidumpMemory64Descriptor.parse(segmentBuffer, dataOffset); 33 | dataOffset += descriptor.segmentSize; 34 | list.descriptors.add(descriptor); 35 | } 36 | 37 | return list; 38 | } 39 | 40 | public long memoryRangeCount; 41 | public long dataOffset; 42 | 43 | public List descriptors; 44 | } -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/ModuleViewPlugin.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import ghidra.app.events.ProgramActivatedPluginEvent; 4 | import ghidra.app.plugin.PluginCategoryNames; 5 | import ghidra.app.plugin.ProgramPlugin; 6 | import ghidra.app.services.GoToService; 7 | import ghidra.framework.plugintool.PluginEvent; 8 | import ghidra.framework.plugintool.PluginInfo; 9 | import ghidra.framework.plugintool.PluginTool; 10 | import ghidra.framework.plugintool.util.PluginStatus; 11 | import ghidra.program.model.listing.Program; 12 | 13 | //@formatter:off 14 | @PluginInfo( 15 | status = PluginStatus.STABLE, 16 | packageName = MinidumpPluginPackage.NAME, 17 | category = PluginCategoryNames.NAVIGATION, 18 | shortDescription = "Display Minidump loaded module information.", 19 | description = "Display Minidump loaded module information." 20 | ) 21 | //@formatter:on 22 | public class ModuleViewPlugin extends ProgramPlugin { 23 | 24 | ModuleViewProvider modulesProvider; 25 | GoToService goToService; 26 | Program program; 27 | 28 | public ModuleViewPlugin(PluginTool tool) { 29 | super(tool, false, false); 30 | modulesProvider = new ModuleViewProvider(this, getName()); 31 | } 32 | 33 | @Override 34 | public void init() { 35 | super.init(); 36 | goToService = tool.getService(GoToService.class); 37 | } 38 | 39 | @Override 40 | public void processEvent(PluginEvent event) 41 | { 42 | if (event instanceof ProgramActivatedPluginEvent) 43 | { 44 | var ev = (ProgramActivatedPluginEvent)event; 45 | program = ev.getActiveProgram(); 46 | modulesProvider.programActivated(program); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/VsFixedFileInfo.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | 9 | /** 10 | * VS_FIXEDFILEINFO 11 | * 12 | * https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo 13 | */ 14 | public class VsFixedFileInfo { 15 | 16 | public static final int RECORD_SIZE = 4 + 4 + 8 + 8 + 4 + 4 + 4 + 4 + 4 + 8; 17 | 18 | public static VsFixedFileInfo parse(long offset, ByteProvider provider) throws IOException { 19 | var bytes = provider.readBytes(offset, RECORD_SIZE); 20 | var byteBuffer = ByteBuffer.wrap(bytes); 21 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 22 | return parse(byteBuffer); 23 | } 24 | 25 | public static VsFixedFileInfo parse(ByteBuffer byteBuffer) { 26 | var info = new VsFixedFileInfo(); 27 | info.signature = byteBuffer.getInt(); 28 | info.structVersion = byteBuffer.getInt(); 29 | info.fileVersion = byteBuffer.getLong(); 30 | info.productVersion = byteBuffer.getLong(); 31 | info.flagsMask = byteBuffer.getInt(); 32 | info.flags = byteBuffer.getInt(); 33 | info.fileOs = byteBuffer.getInt(); 34 | info.fileType = byteBuffer.getInt(); 35 | info.fileSubtype = byteBuffer.getInt(); 36 | info.fileDate = byteBuffer.getLong(); 37 | return info; 38 | } 39 | 40 | public int signature; 41 | public int structVersion; 42 | public long fileVersion; 43 | public long productVersion; 44 | public int flagsMask; 45 | public int flags; 46 | public int fileOs; 47 | public int fileType; 48 | public int fileSubtype; 49 | public long fileDate; 50 | } 51 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/ThreadInformationBlock.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.ByteOrder; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | import ghidra.app.util.opinion.LoadSpec; 9 | import ghidra.program.model.lang.LanguageNotFoundException; 10 | 11 | /** 12 | * Windows TIB 13 | */ 14 | public class ThreadInformationBlock { 15 | 16 | public static final int RECORD_SIZE = 8 + 8 + 8; 17 | 18 | public static ThreadInformationBlock parse(LoadSpec loadSpec, long offset, ByteProvider provider) throws IOException { 19 | var bytes = provider.readBytes(offset, RECORD_SIZE); 20 | var byteBuffer = ByteBuffer.wrap(bytes); 21 | byteBuffer.order(ByteOrder.LITTLE_ENDIAN); 22 | return parse(loadSpec, byteBuffer); 23 | } 24 | 25 | public static ThreadInformationBlock parse(LoadSpec loadSpec, ByteBuffer byteBuffer) { 26 | boolean is64 = true; 27 | try { 28 | is64 = loadSpec.getLanguageCompilerSpec().getLanguage().getLanguageDescription().getSize() == 64; 29 | } catch (LanguageNotFoundException e) { 30 | // Assume 64. 31 | } 32 | 33 | var info = new ThreadInformationBlock(); 34 | if(is64) { 35 | info.sehFrame = byteBuffer.getLong(); 36 | info.stackBase = byteBuffer.getLong(); 37 | info.stackLimit = byteBuffer.getLong(); 38 | } else { 39 | info.sehFrame = byteBuffer.getInt(); 40 | info.stackBase = byteBuffer.getInt(); 41 | info.stackLimit = byteBuffer.getInt(); 42 | } 43 | return info; 44 | } 45 | 46 | public long sehFrame; 47 | public long stackBase; 48 | public long stackLimit; 49 | // ... and more. The stack limits are what we are interested in. 50 | } 51 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/blobs/CliSigTypeSpec.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.blobs; 17 | 18 | import java.io.IOException; 19 | 20 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 21 | import ghidra.program.model.data.DataType; 22 | import ghidra.util.exception.InvalidInputException; 23 | 24 | public class CliSigTypeSpec extends CliAbstractSig { 25 | 26 | public CliSigType type; 27 | 28 | public CliSigTypeSpec(CliBlob blob) throws IOException { 29 | super(blob); 30 | 31 | try { 32 | type = readCliType(blob.getContentsReader()); 33 | } 34 | catch (InvalidInputException e) { 35 | type = null; 36 | } 37 | } 38 | 39 | @Override 40 | public String getContentsName() { 41 | return "TypeSpec"; 42 | } 43 | 44 | @Override 45 | public String getContentsComment() { 46 | return "Describes a type."; 47 | } 48 | 49 | @Override 50 | public DataType getContentsDataType() { 51 | return type.getDefinitionDataType(); 52 | } 53 | 54 | @Override 55 | public String getRepresentationCommon(CliStreamMetadata stream, boolean isShort) { 56 | return "TypeSpec: " + getRepresentationOf(type, stream, isShort); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/analyzer/SubTaskMonitor.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.analyzer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import ghidra.util.task.TaskMonitor; 7 | import ghidra.util.task.WrappingTaskMonitor; 8 | 9 | class SubTaskMonitor extends WrappingTaskMonitor { 10 | 11 | private String title; 12 | private String message; 13 | 14 | private List replaceRules = new ArrayList<>(); 15 | 16 | static class RegexRule { 17 | public RegexRule(String pattern, String replace) { 18 | this.pattern = pattern; 19 | this.replace = replace; 20 | } 21 | 22 | public String pattern; 23 | public String replace; 24 | } 25 | 26 | public SubTaskMonitor(String title, TaskMonitor delegate) { 27 | this(title, null, delegate); 28 | } 29 | 30 | public SubTaskMonitor(String title, String message, TaskMonitor delegate) { 31 | super(delegate); 32 | this.title = title; 33 | this.message = message; 34 | updateMessage(); 35 | } 36 | 37 | public void addReplaceRule(String pattern, String replace) { 38 | this.replaceRules.add(new RegexRule(pattern, replace)); 39 | } 40 | 41 | public void setMessage(String message) { 42 | this.message = message; 43 | updateMessage(); 44 | } 45 | 46 | @Override 47 | public String getMessage() { 48 | return message; 49 | } 50 | 51 | private void updateMessage() { 52 | StringBuilder builder = new StringBuilder(this.title); 53 | if (message != null) { 54 | String replacedMessage = message; 55 | for (RegexRule rule : replaceRules) { 56 | replacedMessage = replacedMessage.replaceAll(rule.pattern, rule.replace); 57 | } 58 | builder.append(": ").append(replacedMessage); 59 | } else { 60 | builder.append("..."); 61 | } 62 | 63 | super.setMessage(builder.toString()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/PeMarkupable.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.importer.MessageLog; 21 | import ghidra.program.model.listing.Program; 22 | import ghidra.program.model.mem.MemoryAccessException; 23 | import ghidra.program.model.util.CodeUnitInsertionException; 24 | import ghidra.util.exception.DuplicateNameException; 25 | import ghidra.util.task.TaskMonitor; 26 | 27 | /** 28 | * Common interface for standardizing the markup of a PE structure. 29 | */ 30 | public interface PeMarkupable { 31 | 32 | /** 33 | * Marks up a PE structure. 34 | * 35 | * @param program The program to markup. 36 | * @param isBinary True if the program is binary; otherwise, false. 37 | * @param monitor The monitor. 38 | * @param log The log. 39 | * @param ntHeader The PE's NT Header structure. 40 | * @throws DuplicateNameException 41 | * @throws CodeUnitInsertionException 42 | * @throws IOException 43 | * @throws MemoryAccessException 44 | */ 45 | public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log, 46 | NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException, 47 | IOException, MemoryAccessException; 48 | } 49 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/parser/RuntimeInfo.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin.parser; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import ghidra.app.util.bin.BinaryReader; 8 | import ghidra.program.model.address.Address; 9 | 10 | public class RuntimeInfo { 11 | 12 | public static final long HEADER_SIZE = 4; 13 | 14 | public static RuntimeInfo parse(Address baseAddress, BinaryReader reader) throws IOException { 15 | 16 | var ri = new RuntimeInfo(); 17 | int versionAndFlags = reader.readNextByte(); 18 | ri.version = (byte)(versionAndFlags & 0x03); 19 | ri.flags = (byte)((versionAndFlags & 0xf4) >> 3); 20 | 21 | ri.prolog = reader.readNextByte(); 22 | ri.unwindCodesCount = reader.readNextByte(); 23 | 24 | int frameRegisterData = reader.readNextByte(); 25 | ri.frameRegister = (byte)(frameRegisterData & 0x0f); 26 | ri.frameRegisterOffset = (byte)((frameRegisterData & 0xf0) >> 4); 27 | 28 | List unwindCodes = new ArrayList<>(); 29 | for (byte i = 0; i < ri.unwindCodesCount; ) { 30 | var code = UnwindCode.parse(reader, ri.frameRegisterOffset); 31 | if (code == null) 32 | break; 33 | unwindCodes.add(code); 34 | i += code.opcodeSize; 35 | if (i > ri.unwindCodesCount) 36 | throw new IOException("Too many unwind codes"); 37 | } 38 | ri.unwindCodes = unwindCodes; 39 | 40 | // Check for chained unwind info. 41 | if ((ri.flags & 0x04) != 0) { 42 | ri.parentFunction = RuntimeFunction.parse(baseAddress, reader); 43 | } 44 | 45 | return ri; 46 | } 47 | 48 | public byte version; 49 | public byte flags; 50 | public byte prolog; 51 | public byte unwindCodesCount; 52 | public byte frameRegister; 53 | public byte frameRegisterOffset; 54 | public RuntimeFunction parentFunction; 55 | 56 | public List unwindCodes; 57 | } 58 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/DelayImportInfo.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe; 17 | 18 | /** 19 | * A class to hold the information extracted from a 20 | * delay import descriptor. 21 | * 22 | * NOTE: 23 | * This class is simply a storage class created for 24 | * parsing the PE header data structures. 25 | * It does not map back to a PE data data structure. 26 | * 27 | * 28 | */ 29 | public class DelayImportInfo { 30 | private long ordinal; 31 | private String name; 32 | 33 | DelayImportInfo(long ordinal) { 34 | this.ordinal = ordinal; 35 | } 36 | 37 | DelayImportInfo(int ordinal, String name) { 38 | this.ordinal = ordinal; 39 | this.name = name; 40 | } 41 | 42 | /** 43 | * Returns the ordinal number of the imported DLL. 44 | * @return the ordinal number of the imported DLL 45 | */ 46 | public long getOrdinal() { 47 | return ordinal; 48 | } 49 | 50 | /** 51 | * Returns the name of the imported DLL. 52 | * @return the name of the imported DLL 53 | */ 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | /** 59 | * Returns true if the import is 'by name'. 60 | * @return true if the import is 'by name' 61 | */ 62 | public boolean hasName() { 63 | return name != null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/OMFAlignSym.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | 22 | import java.io.*; 23 | 24 | /** 25 | * A class to represent the Object Module Format (OMF) alignment symbol. 26 | * 27 | */ 28 | public class OMFAlignSym { 29 | private short length; 30 | private byte [] pad; 31 | 32 | static OMFAlignSym createOMFAlignSym( 33 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 34 | OMFAlignSym omfAlignSym = (OMFAlignSym) reader.getFactory().create(OMFAlignSym.class); 35 | omfAlignSym.initOMFAlignSym(reader, ptr); 36 | return omfAlignSym; 37 | } 38 | 39 | /** 40 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 41 | */ 42 | public OMFAlignSym() {} 43 | 44 | private void initOMFAlignSym(FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 45 | length = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 46 | pad = reader.readByteArray(ptr, length); 47 | } 48 | 49 | /** 50 | * Returns the alignment padding bytes. 51 | * @return the alignment padding bytes 52 | */ 53 | public byte [] getPad() { 54 | return pad; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexHasSemantics.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexHasSemantics { 27 | private static final int bitsUsed = 1; 28 | private static final CliTypeTable tables[] = { CliTypeTable.Event, CliTypeTable.Property }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexHasFieldMarshall.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexHasFieldMarshall { 27 | private static final int bitsUsed = 1; 28 | private static final CliTypeTable tables[] = { CliTypeTable.Field, CliTypeTable.Param }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexMemberForwarded.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexMemberForwarded { 27 | private static final int bitsUsed = 1; 28 | private static final CliTypeTable tables[] = { CliTypeTable.Field, CliTypeTable.MethodDef }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexMethodDefOrRef.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexMethodDefOrRef { 27 | private static final int bitsUsed = 1; 28 | private static final CliTypeTable tables[] = { CliTypeTable.MethodDef, CliTypeTable.MemberRef }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexTypeOrMethodDef.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexTypeOrMethodDef { 27 | private static final int bitsUsed = 1; 28 | private static final CliTypeTable tables[] = { CliTypeTable.TypeDef, CliTypeTable.MethodDef }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_ALIGN.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.format.*; 20 | 21 | import java.io.*; 22 | 23 | /** 24 | * 25 | * 26 | */ 27 | class S_ALIGN extends DebugSymbol { 28 | private byte [] pad; 29 | 30 | static S_ALIGN createS_ALIGN(short length, short type, 31 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 32 | S_ALIGN s_align = (S_ALIGN) reader.getFactory().create(S_ALIGN.class); 33 | s_align.initS_ALIGN(length, type, reader, ptr); 34 | return s_align; 35 | } 36 | 37 | /** 38 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 39 | */ 40 | public S_ALIGN() {} 41 | 42 | private void initS_ALIGN(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 43 | processDebugSymbol(length, type); 44 | 45 | if (type != DebugCodeViewConstants.S_ALIGN) { 46 | throw new IllegalArgumentException("Incorrect type!"); 47 | } 48 | 49 | this.pad = reader.readByteArray(ptr, length); 50 | } 51 | 52 | public boolean isEOT() { 53 | for (int i = 0 ; i < pad.length ; ++i) { 54 | if (pad[i] != 0xff) { 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/UnknownSymbol.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.format.*; 20 | import ghidra.util.*; 21 | 22 | import java.io.*; 23 | 24 | /** 25 | * 26 | */ 27 | class UnknownSymbol extends DebugSymbol{ 28 | private byte [] unknown; 29 | 30 | static UnknownSymbol createUnknownSymbol(short length, short type, 31 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 32 | UnknownSymbol unknownSymbol = (UnknownSymbol) reader.getFactory().create(UnknownSymbol.class); 33 | unknownSymbol.initUnknownSymbol(length, type, reader, ptr); 34 | return unknownSymbol; 35 | } 36 | 37 | /** 38 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 39 | */ 40 | public UnknownSymbol() {} 41 | 42 | private void initUnknownSymbol(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 43 | processDebugSymbol(length, type); 44 | try { 45 | unknown = reader.readByteArray(ptr, Conv.shortToInt(length)); 46 | } 47 | catch (RuntimeException e) { 48 | Msg.error(this, "Unexpected Exception: " + e.getMessage(), e); 49 | } 50 | } 51 | 52 | public byte[] getUnknown() { 53 | return unknown; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexHasConstant.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexHasConstant { 27 | private static final int bitsUsed = 2; 28 | private static final CliTypeTable tables[] = { CliTypeTable.Field, CliTypeTable.Param, CliTypeTable.Property }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexTypeDefOrRef.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexTypeDefOrRef { 27 | private static final int bitsUsed = 2; 28 | private static final CliTypeTable tables[] = { CliTypeTable.TypeDef, CliTypeTable.TypeRef, CliTypeTable.TypeSpec }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/CompId.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | public class CompId { 19 | private final int id; 20 | private final int productId; 21 | private final int buildNumber; 22 | 23 | public CompId(int id) { 24 | this.id = id; 25 | this.productId = id >> 16; 26 | this.buildNumber = id & 0x0000FFFF; 27 | } 28 | 29 | public int getValue() { 30 | return id; 31 | } 32 | 33 | public int getProductId() { 34 | return productId; 35 | } 36 | 37 | public String getProductDescription() { 38 | 39 | RichProduct prod = RichHeaderUtils.getProduct(getProductId()); 40 | 41 | StringBuilder sb = new StringBuilder(); 42 | 43 | String prodVersion = 44 | prod == null ? "Unknown Product (" + Integer.toHexString(getProductId()) + ")" 45 | : prod.getProductVersion(); 46 | MSProductType prodType = prod == null ? MSProductType.Unknown : prod.getProductType(); 47 | 48 | if (prodType != MSProductType.Unknown) { 49 | sb.append(prodType).append(" from ").append(prodVersion); 50 | } 51 | else { 52 | sb.append(prodVersion); 53 | } 54 | 55 | return sb.toString(); 56 | 57 | } 58 | 59 | public int getBuildNumber() { 60 | return buildNumber; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return getProductDescription() + ", build " + getBuildNumber(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexCustomAttributeType.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexCustomAttributeType { 27 | private static final int bitsUsed = 3; 28 | private static final CliTypeTable tables[] = { null, null, CliTypeTable.MethodDef, CliTypeTable.MemberRef }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexHasDeclSecurity.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexHasDeclSecurity { 27 | private static final int bitsUsed = 2; 28 | private static final CliTypeTable tables[] = { CliTypeTable.TypeDef, CliTypeTable.MethodDef, CliTypeTable.Assembly }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexImplementation.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexImplementation { 27 | private static final int bitsUsed = 2; 28 | private static final CliTypeTable tables[] = { CliTypeTable.File, CliTypeTable.AssemblyRef, CliTypeTable.ExportedType }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexResolutionScope.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexResolutionScope { 27 | private static final int bitsUsed = 2; 28 | private static final CliTypeTable tables[] = { CliTypeTable.Module, CliTypeTable.ModuleRef, CliTypeTable.AssemblyRef, CliTypeTable.TypeRef }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_CONSTANT32.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_CONSTANT32 extends DebugSymbol { 29 | 30 | static S_CONSTANT32 createS_CONSTANT32(short length, short type, 31 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 32 | S_CONSTANT32 s_constant32 = (S_CONSTANT32) reader.getFactory().create(S_CONSTANT32.class); 33 | s_constant32.initS_CONSTANT32(length, type, reader, ptr); 34 | return s_constant32; 35 | } 36 | 37 | /** 38 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 39 | */ 40 | public S_CONSTANT32() {} 41 | 42 | private void initS_CONSTANT32(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 43 | processDebugSymbol(length, type); 44 | 45 | int unknown1 = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 46 | short unknown2 = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 47 | 48 | byte nameLen = reader.readByte(ptr); ptr+=BinaryReader.SIZEOF_BYTE; 49 | 50 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 51 | 52 | Msg.debug(this, "S_CONSTANT32: "+unknown1+" - "+unknown2); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_UDT32_NEW.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_UDT32_NEW extends DebugSymbol { 29 | private int symType; 30 | 31 | static S_UDT32_NEW createS_UDT32_NEW(short length, short type, 32 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 33 | S_UDT32_NEW s_udt32_new = (S_UDT32_NEW) reader.getFactory().create(S_UDT32_NEW.class); 34 | s_udt32_new.initS_UDT32_NEW(length, type, reader, ptr); 35 | return s_udt32_new; 36 | } 37 | 38 | /** 39 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 40 | */ 41 | public S_UDT32_NEW() {} 42 | 43 | private void initS_UDT32_NEW(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 44 | processDebugSymbol(length, type); 45 | 46 | symType = reader.readInt(ptr); ptr += BinaryReader.SIZEOF_INT; 47 | 48 | byte nameLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 49 | 50 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 51 | } 52 | 53 | /** 54 | * @return symType - the type of symbol 55 | */ 56 | int getSymType() { 57 | return symType; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexMemberRefParent.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexMemberRefParent extends CliCodedIndexUtils { 27 | private static final int bitsUsed = 3; 28 | private static final CliTypeTable tables[] = { CliTypeTable.TypeDef, CliTypeTable.TypeRef, CliTypeTable.ModuleRef, CliTypeTable.MethodDef, CliTypeTable.TypeSpec }; 29 | 30 | public static DataType toDataType(CliStreamMetadata stream) { 31 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 32 | } 33 | 34 | public static int getRowIndex(int codedIndex) { 35 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 36 | } 37 | 38 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 39 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 40 | } 41 | 42 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 43 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/DebugSymbol.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | /** 20 | * A base class for Object Module Format (OMF) symbols. 21 | * 22 | */ 23 | public abstract class DebugSymbol { 24 | protected short length; 25 | protected short type; 26 | protected String name; 27 | protected short section; 28 | protected int offset; 29 | 30 | protected DebugSymbol() { } 31 | 32 | protected void processDebugSymbol(short length, short type) { 33 | this.length = length; 34 | this.type = type; 35 | } 36 | 37 | /** 38 | * Returns the length of the symbol. 39 | * @return the length of the symbol 40 | */ 41 | public short getLength() { 42 | return length; 43 | } 44 | 45 | /** 46 | * Returns the type of the symbol. 47 | * @return the type of the symbol 48 | */ 49 | public short getType() { 50 | return type; 51 | } 52 | 53 | /** 54 | * Returns the name of the symbol. 55 | * @return the name of the symbol 56 | */ 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | /** 62 | * Returns the section number. 63 | * @return the section number 64 | */ 65 | public short getSection() { 66 | return section; 67 | } 68 | 69 | /** 70 | * Returns the offset. 71 | * @return the offset 72 | */ 73 | public int getOffset() { 74 | return offset; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/StackList.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.plugin; 2 | 3 | import java.awt.event.MouseAdapter; 4 | import java.awt.event.MouseEvent; 5 | import java.util.List; 6 | 7 | import javax.swing.table.TableColumnModel; 8 | 9 | import docking.widgets.table.GTable; 10 | import ghidra.program.model.listing.Program; 11 | 12 | class StackList extends GTable { 13 | 14 | private ThreadViewPlugin plugin; 15 | private List frames; 16 | private StackListModel model; 17 | 18 | public StackList(ThreadViewPlugin plugin) { 19 | this.plugin = plugin; 20 | 21 | this.addMouseListener(new MouseAdapter() { 22 | @Override 23 | public void mouseClicked(MouseEvent e) { 24 | if (e.getClickCount() == 2) { 25 | boolean goToStack = StackList.this.getSelectedColumn() == 0; 26 | navigateStack(StackList.this.getSelectedRow(), goToStack); 27 | } 28 | } 29 | }); 30 | } 31 | 32 | public void setFrames(List frames, Program program) { 33 | 34 | this.frames = frames; 35 | model = new StackListModel(frames, program); 36 | this.setModel(model); 37 | TableColumnModel columns = getColumnModel(); 38 | columns.getColumn(0).setPreferredWidth(100); 39 | columns.getColumn(1).setPreferredWidth(1000); 40 | columns.getColumn(2).setPreferredWidth(100); 41 | columns.getColumn(3).setPreferredWidth(100); 42 | } 43 | 44 | public void updateAnalysis(Program program) { 45 | if (model != null) { 46 | model.updateAnalysis(program); 47 | } 48 | } 49 | 50 | private void navigateStack(int item, boolean goToStack) { 51 | var frame = frames.get(item); 52 | if (frame == null) 53 | return; 54 | if (goToStack) { 55 | plugin.goToService.goTo(frame.stackPointer); 56 | } else { 57 | plugin.goToService.goTo(frame.instructionPointer); 58 | } 59 | } 60 | 61 | @Override 62 | public boolean isCellEditable(int row, int column) { 63 | return false; 64 | } 65 | 66 | @Override 67 | public boolean getColumnSelectionAllowed() { 68 | return false; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_DATAREF.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | 22 | import java.io.*; 23 | 24 | /** 25 | * 26 | * 27 | */ 28 | class S_DATAREF extends DebugSymbol { 29 | private int checksum; 30 | 31 | static S_DATAREF createS_DATAREF(short length, short type, 32 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 33 | S_DATAREF s_dataref = (S_DATAREF) reader.getFactory().create(S_DATAREF.class); 34 | s_dataref.initS_DATAREF(length, type, reader, ptr); 35 | return s_dataref; 36 | } 37 | 38 | /** 39 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 40 | */ 41 | public S_DATAREF() {} 42 | 43 | private void initS_DATAREF(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 44 | processDebugSymbol(length, type); 45 | 46 | if (type != DebugCodeViewConstants.S_DATAREF) { 47 | throw new IllegalArgumentException("Incorrect type!"); 48 | } 49 | 50 | this.checksum = reader.readInt (ptr); ptr += BinaryReader.SIZEOF_INT; 51 | this.offset = reader.readInt (ptr); ptr += BinaryReader.SIZEOF_INT; 52 | this.section = reader.readShort(ptr); ptr += BinaryReader.SIZEOF_SHORT; 53 | } 54 | 55 | public int getChecksum() { 56 | return checksum; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_UDT32.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_UDT32 extends DebugSymbol { 29 | private int checksum; 30 | private byte typeLen; 31 | 32 | static S_UDT32 createS_UDT32(short length, short type, 33 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 34 | S_UDT32 s_udt32 = (S_UDT32) reader.getFactory().create(S_UDT32.class); 35 | s_udt32.initS_UDT32(length, type, reader, ptr); 36 | return s_udt32; 37 | } 38 | 39 | /** 40 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 41 | */ 42 | public S_UDT32() {} 43 | 44 | private void initS_UDT32(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 45 | processDebugSymbol(length, type); 46 | 47 | if (type != DebugCodeViewConstants.S_UDT32) { 48 | throw new IllegalArgumentException("Incorrect type!"); 49 | } 50 | 51 | this.checksum = reader.readInt(ptr); ptr += BinaryReader.SIZEOF_INT; 52 | this.typeLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 53 | this.name = reader.readAsciiString(ptr, Conv.byteToInt(typeLen)); 54 | } 55 | 56 | public int getChecksum() { 57 | return checksum; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_GDATA32_NEW.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_GDATA32_NEW extends DebugSymbol { 29 | 30 | static S_GDATA32_NEW createS_GDATA32_NEW(short length, short type, 31 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 32 | S_GDATA32_NEW s_gdata32_new = (S_GDATA32_NEW) reader.getFactory().create(S_GDATA32_NEW.class); 33 | s_gdata32_new.initS_GDATA32_NEW(length, type, reader, ptr); 34 | return s_gdata32_new; 35 | } 36 | 37 | /** 38 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 39 | */ 40 | public S_GDATA32_NEW() {} 41 | 42 | private void initS_GDATA32_NEW(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 43 | processDebugSymbol(length, type); 44 | 45 | int unknown = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 46 | 47 | offset = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 48 | section = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 49 | 50 | byte nameLen = reader.readByte(ptr); ptr+=BinaryReader.SIZEOF_BYTE; 51 | 52 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 53 | 54 | Msg.debug(this, "S_DATA32_NEW: "+unknown); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableAssemblyProcessor.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.*; 23 | 24 | /** 25 | * Describes the AssemblyProcessor table. It is apparently ignored by the CLI and shouldn't be found in an assembly. 26 | */ 27 | public class CliTableAssemblyProcessor extends CliAbstractTable { 28 | public class CliAssemblyProcessorRow extends CliAbstractTableRow { 29 | public int processor; 30 | 31 | public CliAssemblyProcessorRow(int processor) { 32 | this.processor = processor; 33 | } 34 | 35 | @Override 36 | public String getRepresentation() { 37 | return String.format("Processor %d", processor); 38 | } 39 | } 40 | public CliTableAssemblyProcessor(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 41 | super(reader, stream, tableId); 42 | for (int i = 0; i < this.numRows; i++) { 43 | rows.add(new CliAssemblyProcessorRow(reader.readNextInt())); 44 | } 45 | } 46 | 47 | @Override 48 | public DataType getRowDataType() { 49 | return toDataType(); 50 | } 51 | 52 | @Override 53 | public DataType toDataType() { 54 | Structure rowDt = new StructureDataType(new CategoryPath(PATH), "AssemblyProcessor Row", 0); 55 | rowDt.add(DWORD, "Processor", null); 56 | return new ArrayDataType(rowDt, this.numRows, rowDt.getLength()); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/resource/ResourceStringInfo.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.resource; 18 | 19 | /** 20 | * A class to hold the information extracted from a 21 | * resource data directory. 22 | * 23 | * NOTE: 24 | * This class is simply a storage class created for 25 | * parsing the PE header data structures. 26 | * It does not map back to a PE data data structure. 27 | * 28 | * 29 | */ 30 | public class ResourceStringInfo { 31 | private int address; 32 | private String string; 33 | private int length; 34 | /** 35 | * Constructor. 36 | * @param address the adjusted address where the resource exists 37 | * @param string the resource string 38 | * @param length the length of the resource 39 | */ 40 | public ResourceStringInfo(int address, String string, int length) { 41 | this.address = address; 42 | this.string = string; 43 | this.length = length; 44 | } 45 | /** 46 | * Returns the adjusted address where the resource exists. 47 | * @return the adjusted address where the resource exists 48 | */ 49 | public int getAddress() { 50 | return address; 51 | } 52 | /** 53 | * Returns the resource string. 54 | * @return the resource string 55 | */ 56 | public String getString() { 57 | return string; 58 | } 59 | /** 60 | * Returns the length of the resource. 61 | * @return the length of the resource 62 | */ 63 | public int getLength() { 64 | return length; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/MSRichProductInfoDataType.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | import ghidra.docking.settings.Settings; 19 | import ghidra.program.model.data.*; 20 | import ghidra.program.model.mem.MemBuffer; 21 | 22 | class MSRichProductInfoDataType extends StructureDataType { 23 | 24 | private final CompId compid; 25 | 26 | public MSRichProductInfoDataType(CompId compid) { 27 | this(compid, null); 28 | } 29 | 30 | public MSRichProductInfoDataType(CompId compid, DataTypeManager dtm) { 31 | super(new CategoryPath("/PE"), "ProductInfo", 0, dtm); 32 | this.compid = compid; 33 | initialize(); 34 | } 35 | 36 | @Override 37 | public boolean hasLanguageDependantLength() { 38 | return false; 39 | } 40 | 41 | @Override 42 | public MSRichProductInfoDataType clone(DataTypeManager dtm) { 43 | if (dtm == getDataTypeManager()) { 44 | return this; 45 | } 46 | return new MSRichProductInfoDataType(compid, dtm); 47 | } 48 | 49 | @Override 50 | public String getMnemonic(Settings settings) { 51 | return "Product Info"; 52 | } 53 | 54 | @Override 55 | public int getLength() { 56 | return 4; 57 | } 58 | 59 | @Override 60 | public String getDescription() { 61 | return "Product Info"; 62 | } 63 | 64 | @Override 65 | public Object getValue(MemBuffer buf, Settings settings, int length) { 66 | return compid; 67 | } 68 | 69 | private void initialize() { 70 | add(new MSRichProductIDDataType(compid), 2, "product", null); 71 | add(new MSRichProductBuildNumberDataType(compid), 2, "buildNumber", null); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_LABEL32.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_LABEL32 extends DebugSymbol { 29 | private byte flags; 30 | 31 | static S_LABEL32 createS_LABEL32(short length, short type, 32 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 33 | S_LABEL32 s_label32 = (S_LABEL32) reader.getFactory().create(S_LABEL32.class); 34 | s_label32.initS_LABEL32(length, type, reader, ptr); 35 | return s_label32; 36 | } 37 | 38 | /** 39 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 40 | */ 41 | public S_LABEL32() {} 42 | 43 | private void initS_LABEL32(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 44 | processDebugSymbol(length, type); 45 | 46 | offset = reader.readInt(ptr); ptr += BinaryReader.SIZEOF_INT; 47 | section = reader.readShort(ptr); ptr += BinaryReader.SIZEOF_SHORT; 48 | flags = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 49 | 50 | byte nameLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 51 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 52 | Msg.debug(this, "Created label symbol: " +name); 53 | 54 | } 55 | /** 56 | * @return the flags of this S_LABEL32 symbol 57 | */ 58 | byte getFlags() { 59 | return flags; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/ImportInfo.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe; 17 | 18 | public class ImportInfo { 19 | private int address; 20 | private String comment; 21 | private String dll; 22 | private String name; 23 | private boolean isBound; 24 | 25 | ImportInfo(int address, String cmt, String dll, String name, boolean isBound) { 26 | this.address = address; 27 | this.comment = cmt; 28 | this.dll = dll.toUpperCase(); 29 | this.name = name; 30 | this.isBound = isBound; 31 | } 32 | 33 | /** 34 | * Returns the adjusted address where the import occurs. 35 | * @return the adjusted address where the import occurs 36 | */ 37 | public int getAddress() { 38 | return address; 39 | } 40 | 41 | /** 42 | * Returns a comment string containing extra information about the import. 43 | * @return a comment string containing extra information about the import 44 | */ 45 | public String getComment() { 46 | return comment; 47 | } 48 | 49 | /** 50 | * Returns the name of the imported DLL. 51 | * @return the name of the imported DLL 52 | */ 53 | public String getDLL() { 54 | return dll; 55 | } 56 | 57 | /** 58 | * Returns the name of the imported symbol. 59 | * @return the name of the imported symbol 60 | */ 61 | public String getName() { 62 | return name; 63 | } 64 | 65 | /** 66 | * Returns true if this is a bound import. 67 | * @return true if this is a bound import 68 | */ 69 | public boolean isBound() { 70 | return isBound; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableModuleRef.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the ModuleRef table. Each row is a reference to an external module. 27 | */ 28 | public class CliTableModuleRef extends CliAbstractTable { 29 | public class CliModuleRefRow extends CliAbstractTableRow { 30 | public int nameIndex; 31 | 32 | public CliModuleRefRow(int nameIndex) { 33 | this.nameIndex = nameIndex; 34 | } 35 | 36 | @Override 37 | public String getRepresentation() { 38 | return String.format("ModuleRef %s", metadataStream.getStringsStream().getString(nameIndex)); 39 | } 40 | } 41 | 42 | public CliTableModuleRef(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 43 | super(reader, stream, tableId); 44 | for (int i = 0; i < this.numRows; i++) { 45 | CliModuleRefRow row = new CliModuleRefRow(readStringIndex(reader)); 46 | rows.add(row); 47 | strings.add(row.nameIndex); 48 | } 49 | reader.setPointerIndex(this.readerOffset); 50 | } 51 | 52 | @Override 53 | public StructureDataType getRowDataType() { 54 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "ModuleRef Row", 0); 55 | rowDt.add(metadataStream.getStringIndexDataType(), "Name", "index into String heap"); 56 | return rowDt; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpMemoryInfo.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public class MinidumpMemoryInfo { 6 | 7 | // Memory info doesn't have definite record size, instead the module info struct 8 | // specifies the size of the entries. 9 | 10 | public static MinidumpMemoryInfo parse(ByteBuffer byteBuffer) { 11 | var module = new MinidumpMemoryInfo(); 12 | 13 | module.baseAddress = byteBuffer.getLong(); 14 | module.allocationBase = byteBuffer.getLong(); 15 | module.allocationProtect = byteBuffer.getInt(); 16 | module.__alignment1 = byteBuffer.getInt(); 17 | module.regionSize = byteBuffer.getLong(); 18 | module.state = byteBuffer.getInt(); 19 | module.protect = byteBuffer.getInt(); 20 | module.type = byteBuffer.getInt(); 21 | module.__alignment2 = byteBuffer.getInt(); 22 | 23 | return module; 24 | } 25 | 26 | public long baseAddress; 27 | public long allocationBase; 28 | public int allocationProtect; 29 | public int __alignment1; 30 | public long regionSize; 31 | public int state; 32 | public int protect; 33 | public int type; 34 | public int __alignment2; 35 | 36 | public final static int MEM_STATE_COMMIT = 0x1000; 37 | public final static int MEM_STATE_FREE = 0x10000; 38 | public final static int MEM_STATE_RESERVE = 0x2000; 39 | 40 | public final static int MEM_TYPE_IMAGE = 0x1000000; 41 | public final static int MEM_TYPE_MAPPED = 0x40000; 42 | public final static int MEM_TYPE_PRIVATE = 0x20000; 43 | 44 | public final static int PAGE_EXECUTE = 0x10; 45 | public final static int PAGE_EXECUTE_READ = 0x20; 46 | public final static int PAGE_EXECUTE_READWRITE = 0x40; 47 | public final static int PAGE_EXECUTE_WRITECOPY = 0x80; 48 | public final static int PAGE_NOACCESS = 0x01; 49 | public final static int PAGE_READONLY = 0x02; 50 | public final static int PAGE_READWRITE = 0x04; 51 | public final static int PAGE_WRITECOPY = 0x08; 52 | public final static int PAGE_TARGETS_INVALID = 0x40000000; 53 | public final static int PAGE_TARGETS_NO_UPDATE = 0x40000000; 54 | public final static int PAGE_GUARD = 0x100; 55 | public final static int PAGE_NOCACHE = 0x200; 56 | public final static int PAGE_WRITECOMBINE = 0x400; 57 | } 58 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/plugin/ThreadViewPlugin.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.plugin; 17 | 18 | import ghidra.app.events.ProgramActivatedPluginEvent; 19 | import ghidra.app.plugin.PluginCategoryNames; 20 | import ghidra.app.plugin.ProgramPlugin; 21 | import ghidra.app.services.GoToService; 22 | import ghidra.framework.plugintool.*; 23 | import ghidra.framework.plugintool.util.PluginStatus; 24 | import ghidra.program.model.listing.Program; 25 | 26 | //@formatter:off 27 | @PluginInfo( 28 | status = PluginStatus.STABLE, 29 | packageName = MinidumpPluginPackage.NAME, 30 | category = PluginCategoryNames.NAVIGATION, 31 | shortDescription = "Displays Minidump Thread information.", 32 | description = "Lists Thread information contained in the Minidump and resolves the call stacks for each thread." 33 | ) 34 | //@formatter:on 35 | public class ThreadViewPlugin extends ProgramPlugin { 36 | 37 | ThreadViewProvider threadsProvider; 38 | GoToService goToService; 39 | Program program; 40 | 41 | /** 42 | * Plugin constructor. 43 | * 44 | * @param tool The plugin tool that this plugin is added to. 45 | */ 46 | public ThreadViewPlugin(PluginTool tool) { 47 | super(tool, false, false); 48 | threadsProvider = new ThreadViewProvider(this, getName()); 49 | } 50 | 51 | @Override 52 | public void init() { 53 | super.init(); 54 | goToService = tool.getService(GoToService.class); 55 | } 56 | 57 | @Override 58 | public void processEvent(PluginEvent event) 59 | { 60 | if (event instanceof ProgramActivatedPluginEvent) 61 | { 62 | var ev = (ProgramActivatedPluginEvent)event; 63 | program = ev.getActiveProgram(); 64 | threadsProvider.programActivated(program); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableFieldRVA.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the FieldRVA table. Each row gives the RVA location of an initial value for each Field. 27 | */ 28 | public class CliTableFieldRVA extends CliAbstractTable { 29 | public class CliFieldRVARow extends CliAbstractTableRow { 30 | public int rva; 31 | public int fieldIndex; 32 | 33 | public CliFieldRVARow(int rva, int fieldIndex) { 34 | super(); 35 | this.rva = rva; 36 | this.fieldIndex = fieldIndex; 37 | } 38 | 39 | @Override 40 | public String getRepresentation() { 41 | return String.format("Field %s RVA %x", getRowRepresentationSafe(CliTypeTable.Field, fieldIndex), rva); 42 | } 43 | } 44 | 45 | public CliTableFieldRVA(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 46 | super(reader, stream, tableId); 47 | for (int i = 0; i < this.numRows; i++) { 48 | rows.add(new CliFieldRVARow(reader.readNextInt(), readTableIndex(reader, CliTypeTable.Field))); 49 | } 50 | reader.setPointerIndex(this.readerOffset); 51 | } 52 | 53 | @Override 54 | public StructureDataType getRowDataType() { 55 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "FieldRVA Row", 0); 56 | rowDt.add(DWORD, "RVA", null); 57 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.Field), "Field", "index into Field table"); 58 | return rowDt; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/OMFLibrary.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | import java.util.*; 25 | 26 | /** 27 | * A class to represent the Object Module Format (OMF) Library data structure. 28 | * 29 | */ 30 | public class OMFLibrary { 31 | private String [] libs; 32 | 33 | static OMFLibrary createOMFLibrary( 34 | FactoryBundledWithBinaryReader reader, int ptr, int numBytes) 35 | throws IOException { 36 | OMFLibrary omfLibrary = (OMFLibrary) reader.getFactory().create(OMFLibrary.class); 37 | omfLibrary.initOMFLibrary(reader, ptr, numBytes); 38 | return omfLibrary; 39 | } 40 | 41 | /** 42 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 43 | */ 44 | public OMFLibrary() {} 45 | 46 | private void initOMFLibrary(FactoryBundledWithBinaryReader reader, int ptr, int numBytes) throws IOException { 47 | ArrayList libList = new ArrayList(); 48 | while (numBytes > 0) { 49 | byte len = reader.readByte(ptr); 50 | ptr+=BinaryReader.SIZEOF_BYTE; 51 | numBytes-=BinaryReader.SIZEOF_BYTE; 52 | int length = Conv.byteToInt(len); 53 | String lib = reader.readAsciiString(ptr, length); 54 | ptr+=length; 55 | numBytes-=length; 56 | libList.add(lib); 57 | } 58 | libs = new String[libList.size()]; 59 | libList.toArray(libs); 60 | } 61 | 62 | /** 63 | * Returns the array of library names. 64 | * @return the array of library name 65 | */ 66 | public String [] getLibraries() { 67 | return libs; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableFieldLayout.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the FieldLayout table. Serves a similar purpose to ClassLayout; it's useful when passing to unmanaged code. 27 | */ 28 | public class CliTableFieldLayout extends CliAbstractTable { 29 | public class CliFieldLayoutRow extends CliAbstractTableRow { 30 | public int offset; 31 | public int fieldIndex; 32 | 33 | public CliFieldLayoutRow(int offset, int fieldIndex) { 34 | super(); 35 | this.offset = offset; 36 | this.fieldIndex = fieldIndex; 37 | } 38 | 39 | @Override 40 | public String getRepresentation() { 41 | return String.format("Field %s Offset %d", getRowRepresentationSafe(CliTypeTable.Field, fieldIndex), offset); 42 | } 43 | } 44 | 45 | public CliTableFieldLayout(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 46 | super(reader, stream, tableId); 47 | for (int i = 0; i < this.numRows; i++) { 48 | rows.add(new CliFieldLayoutRow(reader.readNextInt(), readTableIndex(reader, CliTypeTable.Field))); 49 | } 50 | reader.setPointerIndex(this.readerOffset); 51 | } 52 | 53 | @Override 54 | public StructureDataType getRowDataType() { 55 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "FieldLayout Row", 0); 56 | rowDt.add(DWORD, "Offset", null); 57 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.Field), "Field", null); 58 | return rowDt; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/loader/parser/MinidumpModule.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.loader.parser; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.ByteBuffer; 6 | 7 | import ghidra.app.util.bin.ByteProvider; 8 | 9 | public class MinidumpModule { 10 | 11 | public static final int RECORD_SIZE = 8 + 4 + 4 + 4 + 4 + VsFixedFileInfo.RECORD_SIZE + MinidumpLocationDescriptor.RECORD_SIZE 12 | + MinidumpLocationDescriptor.RECORD_SIZE + 8 + 8; 13 | 14 | public static MinidumpModule parse(ByteBuffer byteBuffer, ByteProvider provider) throws IOException { 15 | var module = new MinidumpModule(); 16 | module.imageBase = byteBuffer.getLong(); 17 | module.imageSize = byteBuffer.getInt(); 18 | module.checksum = byteBuffer.getInt(); 19 | module.timestamp = byteBuffer.getInt(); 20 | module.moduleNameRva = byteBuffer.getInt(); 21 | module.versionInfo = VsFixedFileInfo.parse(byteBuffer); 22 | module.cvRecord = MinidumpLocationDescriptor.parse(byteBuffer); 23 | module.miscRecord = MinidumpLocationDescriptor.parse(byteBuffer); 24 | module.reserved0 = byteBuffer.getLong(); 25 | module.reserved1 = byteBuffer.getLong(); 26 | 27 | module.name = StringReader.readString(module.moduleNameRva, provider); 28 | 29 | return module; 30 | } 31 | 32 | public String getBaseName() { 33 | return getFilename(new File(this.name).getPath()); 34 | } 35 | 36 | private String getFilename(String fullPath) { 37 | // Remove any trailing slashes 38 | String editedPath = fullPath; 39 | editedPath = editedPath.replaceAll("[\\/]$", ""); 40 | 41 | int lastIndexForwardSlash = editedPath.lastIndexOf('/'); 42 | int lastIndexBackSlash = editedPath.lastIndexOf('\\'); 43 | 44 | if (lastIndexForwardSlash == -1 && lastIndexBackSlash == -1) { 45 | return editedPath; 46 | } 47 | 48 | int indexToUse = (lastIndexForwardSlash > lastIndexBackSlash) ? lastIndexForwardSlash 49 | : lastIndexBackSlash; 50 | 51 | return editedPath.substring(indexToUse + 1); 52 | } 53 | 54 | 55 | public long imageBase; 56 | public int imageSize; 57 | public int checksum; 58 | public int timestamp; 59 | public int moduleNameRva; 60 | public VsFixedFileInfo versionInfo; 61 | public MinidumpLocationDescriptor cvRecord; 62 | public MinidumpLocationDescriptor miscRecord; 63 | public long reserved0; 64 | public long reserved1; 65 | 66 | public String name; 67 | } 68 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/new_/ModuleBaseMap.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.contrib.new_; 2 | 3 | import ghidra.program.model.address.Address; 4 | import ghidra.program.model.address.AddressIterator; 5 | import ghidra.program.model.listing.Program; 6 | import ghidra.program.model.util.IntPropertyMap; 7 | import ghidra.program.model.util.PropertyMapManager; 8 | import ghidra.util.exception.DuplicateNameException; 9 | import ghidra.util.exception.NoValueException; 10 | 11 | public class ModuleBaseMap { 12 | 13 | static final String MODULE_LIMITS_MAP_NAME = "MODULEBASEOFFSET_MODULE_LIMITS"; 14 | static final int MODULE_START = 1; 15 | static final int MODULE_END = 0; 16 | 17 | public static void markModule(Program program, Address start, Address end) { 18 | PropertyMapManager manager = program.getUsrPropertyManager(); 19 | 20 | IntPropertyMap map = manager.getIntPropertyMap(MODULE_LIMITS_MAP_NAME); 21 | if (map == null) { 22 | try { 23 | map = manager.createIntPropertyMap(MODULE_LIMITS_MAP_NAME); 24 | } catch (DuplicateNameException e) { 25 | map = manager.getIntPropertyMap(MODULE_LIMITS_MAP_NAME); 26 | } 27 | } 28 | 29 | map.add(start, MODULE_START); 30 | map.add(end, MODULE_END); 31 | } 32 | 33 | public static Address getModuleBase(Program program, Address addr) { 34 | PropertyMapManager manager = program.getUsrPropertyManager(); 35 | 36 | IntPropertyMap map = manager.getIntPropertyMap(MODULE_LIMITS_MAP_NAME); 37 | if (map == null) { 38 | return null; 39 | } 40 | 41 | AddressIterator iter = map.getPropertyIterator(addr, false); 42 | Address closest = iter.next(); 43 | 44 | int flag; 45 | try { 46 | flag = map.getInt(closest); 47 | } catch (NoValueException e) { 48 | // The address used in lookup should have value according to the map. 49 | throw new RuntimeException(e); 50 | } 51 | 52 | // If the previous record is start of module we'll return that. 53 | if (flag == MODULE_START) { 54 | return closest; 55 | } 56 | 57 | // No start of module record found. 58 | 59 | // There's a chance the user queried the exact end-of-module address, which is still 60 | // inclusive to the current module. If this happened, we'll continue iterating backwards 61 | // to acquire the start-of-module address. 62 | if (closest.equals(addr)) { 63 | return iter.next(); 64 | } 65 | 66 | return null; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_BPREL32_NEW.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * A class to represent the S_BPREL32_NEW data structure. 27 | * 28 | */ 29 | public class S_BPREL32_NEW extends DebugSymbol { 30 | private short variableType; 31 | private short symbolType; 32 | 33 | static S_BPREL32_NEW createS_BPREL32_NEW(short length, short type, 34 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 35 | S_BPREL32_NEW s_bprel32_new = (S_BPREL32_NEW) reader.getFactory().create(S_BPREL32_NEW.class); 36 | s_bprel32_new.initS_BPREL32_NEW(length, type, reader, ptr); 37 | return s_bprel32_new; 38 | } 39 | 40 | /** 41 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 42 | */ 43 | public S_BPREL32_NEW() {} 44 | 45 | private void initS_BPREL32_NEW(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 46 | processDebugSymbol(length, type); 47 | 48 | offset = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 49 | variableType = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 50 | symbolType = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 51 | 52 | byte nameLen = reader.readByte (ptr); ptr+=BinaryReader.SIZEOF_BYTE; 53 | 54 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 55 | } 56 | 57 | /** 58 | * Returns the variable type. 59 | * @return the variable type 60 | */ 61 | public short getVariableType() { 62 | return variableType; 63 | } 64 | short getSymbolType() { 65 | return symbolType; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliCodedIndexUtils.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.*; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliCodedIndexUtils { 27 | public static DataType toDataType(CliStreamMetadata stream, int bitsUsed, CliTypeTable tables[]) { 28 | int maxForWord = (1 << (WordDataType.dataType.getLength()*8 - bitsUsed)) - 1; 29 | for (CliTypeTable table : tables) { 30 | if (table != null && stream.getNumberRowsForTable(table) > maxForWord) 31 | return DWordDataType.dataType; 32 | } 33 | return WordDataType.dataType; 34 | } 35 | 36 | public static CliTypeTable getTableName(int codedIndex, int bitsUsed, CliTypeTable tables[]) throws InvalidInputException { 37 | int mask = (2 << (bitsUsed - 1)) - 1; // 2 << (bitsUsed-1) == 2^(bitsUsed) 38 | int tableBits = codedIndex & mask; 39 | if (tableBits >= tables.length) 40 | throw new InvalidInputException("The coded index is not valid for this index type. There is no TableName for the bit pattern."); 41 | return tables[tableBits]; 42 | } 43 | 44 | public static int getRowIndex(int codedIndex, int bitsUsed) { 45 | return codedIndex >> bitsUsed; 46 | } 47 | 48 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream, int bitsUsed, CliTypeTable tables[]) throws IOException { 49 | if (toDataType(stream, bitsUsed, tables).getLength() == WordDataType.dataType.getLength()) { 50 | return reader.readNextShort(); 51 | } 52 | return reader.readNextInt(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/indexes/CliIndexHasCustomAttribute.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables.indexes; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.CliTypeTable; 23 | import ghidra.program.model.data.DataType; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliIndexHasCustomAttribute { 27 | private static final int bitsUsed = 5; 28 | private static final CliTypeTable tables[] = { CliTypeTable.MethodDef, CliTypeTable.Field, CliTypeTable.TypeRef, CliTypeTable.TypeDef, CliTypeTable.Param, 29 | CliTypeTable.InterfaceImpl, CliTypeTable.MemberRef, CliTypeTable.Module, null, CliTypeTable.Property, CliTypeTable.Event, CliTypeTable.StandAloneSig, 30 | CliTypeTable.ModuleRef, CliTypeTable.TypeSpec, CliTypeTable.Assembly, CliTypeTable.AssemblyRef, CliTypeTable.File, CliTypeTable.ExportedType, 31 | CliTypeTable.ManifestResource }; // TODO: null should be TableName.Permission, but this is not well-described in the standard 32 | 33 | public static DataType toDataType(CliStreamMetadata stream) { 34 | return CliCodedIndexUtils.toDataType(stream, bitsUsed, tables); 35 | } 36 | 37 | public static int getRowIndex(int codedIndex) { 38 | return CliCodedIndexUtils.getRowIndex(codedIndex, bitsUsed); 39 | } 40 | 41 | public static CliTypeTable getTableName(int codedIndex) throws InvalidInputException { 42 | return CliCodedIndexUtils.getTableName(codedIndex, bitsUsed, tables); 43 | } 44 | 45 | public static int readCodedIndex(BinaryReader reader, CliStreamMetadata stream) throws IOException { 46 | return CliCodedIndexUtils.readCodedIndex(reader, stream, bitsUsed, tables); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableAssemblyRefProcessor.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.*; 23 | 24 | /** 25 | * Describes the AssemblyRefProcessor table. Apparently it is ignored by the CLI and shouldn't be present in an assembly. 26 | */ 27 | public class CliTableAssemblyRefProcessor extends CliAbstractTable { 28 | public class CliAssemblyRefProcessorRow extends CliAbstractTableRow { 29 | public int processor; 30 | public int assemblyRefIndex; 31 | 32 | public CliAssemblyRefProcessorRow(int processor, int assemblyRefIndex) { 33 | super(); 34 | this.processor = processor; 35 | this.assemblyRefIndex = assemblyRefIndex; 36 | } 37 | 38 | @Override 39 | public String getRepresentation() { 40 | return String.format("Processor %d AssemblyRef: %s", processor, 41 | getRowRepresentationSafe(CliTypeTable.AssemblyRef, assemblyRefIndex)); 42 | } 43 | } 44 | 45 | public CliTableAssemblyRefProcessor(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 46 | super(reader, stream, tableId); 47 | for (int i = 0; i < this.numRows; i++) { 48 | rows.add(new CliAssemblyRefProcessorRow(reader.readNextInt(), readTableIndex(reader, CliTypeTable.AssemblyRef))); 49 | } 50 | } 51 | 52 | @Override 53 | public DataType getRowDataType() { 54 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "AssemblyRefProcessor Row", 0); 55 | rowDt.add(DWORD, "Processor", null); 56 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.AssemblyRef), "AssemblyRef", "index into AssemblyRef table"); 57 | return rowDt; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_OBJNAME.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_OBJNAME extends DebugSymbol { 29 | private int signature; 30 | private byte nameLen; 31 | private byte [] padding; 32 | 33 | static S_OBJNAME createS_OBJNAME(short length, short type, 34 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 35 | S_OBJNAME s_objname = (S_OBJNAME) reader.getFactory().create(S_OBJNAME.class); 36 | s_objname.initS_OBJNAME(length, type, reader, ptr); 37 | return s_objname; 38 | } 39 | 40 | /** 41 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 42 | */ 43 | public S_OBJNAME() {} 44 | 45 | private void initS_OBJNAME(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 46 | processDebugSymbol(length, type); 47 | 48 | signature = reader.readInt(ptr); ptr += BinaryReader.SIZEOF_INT; 49 | nameLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 50 | name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); ptr += nameLen + 1; 51 | 52 | int sizeOfPadding = BinaryReader.SIZEOF_SHORT+ 53 | BinaryReader.SIZEOF_INT+ 54 | BinaryReader.SIZEOF_INT+ 55 | BinaryReader.SIZEOF_INT+ 56 | BinaryReader.SIZEOF_BYTE+ 57 | Conv.byteToInt(nameLen)+1; 58 | 59 | padding = reader.readByteArray(ptr, sizeOfPadding); 60 | } 61 | 62 | public int getSignature() { 63 | return signature; 64 | } 65 | public byte getNameLen() { 66 | return nameLen; 67 | } 68 | public byte [] getPadding() { 69 | return padding; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Windows Minidump loader for Ghidra 2 | 3 | ### Work in progress 4 | 5 | ![Ghidra UI](images/readme.png) 6 | 7 | # Feature status 8 | 9 | ## Loader 10 | 11 | - [x] Find the modules in the Minidump and load each module separately with the 12 | PE loader. 13 | - [x] Position the modules to their correct runtime addresses. 14 | - [x] Replace the use of `ImageBaseOffset..` data types with 15 | `ModuleBaseOffset..`. 16 | - [x] Store the module boundaries in the `UserData`. 17 | - [x] Load the private memory as its own fragment. 18 | - [x] Parse the thread information and separate the thread stacks as their own 19 | fragments. 20 | - [x] Find the thread information from the dump and store that into `UserData`. 21 | 22 | ## Thread view 23 | 24 | - [x] Display threads and their RSP/RIP registers. 25 | - [x] Implement stack walking based on exception handling `UNWIND_INFO` 26 | - [x] `UNWIND_CODE` based walking. 27 | - [x] Chained `RUNTIME_FUNCTION` support. 28 | - [ ] Frame register support. 29 | - [ ] 32-bit support. 30 | 31 | ## Other 32 | 33 | See open issues on GitHub. 34 | 35 | # Changes to Ghidra packages 36 | 37 | The implementation depends heavily on the built-in `PeLoader` and 38 | `PortableExecutable` but required some changes to them: 39 | 40 | - Support loading modules to other base addresses than `Program.imageBase`. 41 | - Support loading modules separately from processing them. 42 | - Support linking import symbols directly into memory locations if target 43 | memory is present. 44 | - Support for `ModuleBaseOffsetXY` data types. 45 | 46 | The goal would be to have these changes upstreamed to Ghidra in the future to 47 | avoid the need to duplicate the implementation of the whole `..format.pe.*` 48 | package in the repository. However this work might need some clean up to bring 49 | the current changes up to Ghidra standard. The current changes to the Ghidra 50 | files are made with the goal to keep actual code changes to minimum with no 51 | concern for single-responsibility principle, etc. 52 | 53 | ## License 54 | 55 | The majority of the source code under this repository is covered by the Apache 56 | 2.0 License as described in the LICENSE file. The `contrib` package (excluding 57 | the `contrib.new_` contents) is copied over from Ghidra and is covered under 58 | [Ghidra's Apache 2.0 License][apache-ghidra]. 59 | 60 | [apache-ghidra]: 61 | https://github.com/NationalSecurityAgency/ghidra/blob/8f8c3cfa1406cc4a78b55dac4bb284ab01333bae/LICENSE 62 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/analyzer/FindSymbolsFileChooser.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.analyzer; 2 | 3 | import java.awt.Component; 4 | import java.io.File; 5 | 6 | import docking.widgets.filechooser.GhidraFileChooser; 7 | import docking.widgets.filechooser.GhidraFileChooserMode; 8 | import ghidra.app.util.pdb.PdbProgramAttributes; 9 | import ghidra.util.SystemUtilities; 10 | import ghidra.util.filechooser.ExtensionFileFilter; 11 | import ghidra.util.task.TaskMonitor; 12 | import ghidra.util.worker.Job; 13 | import ghidra.util.worker.Worker; 14 | import net.jubjubnest.minidump.analyzer.PdbResolver.PdbResult; 15 | 16 | class FindSymbolsFileChooser extends GhidraFileChooser { 17 | 18 | private final PdbProgramAttributes pdbAttributes; 19 | private Worker worker = Worker.createGuiWorker(); 20 | private boolean useModulePdbPath; 21 | 22 | private File rootDirectory; 23 | private PdbResult result; 24 | 25 | public FindSymbolsFileChooser(Component parent, PdbProgramAttributes pdbAttributes, boolean useModulePdbPath) { 26 | super(parent); 27 | this.pdbAttributes = pdbAttributes; 28 | this.useModulePdbPath = useModulePdbPath; 29 | 30 | setTitle("Locate " + pdbAttributes.getPdbFile()); 31 | setApproveButtonText("Select PDB"); 32 | setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY); 33 | setFileFilter(new ExtensionFileFilter(new String[] { "pdb" }, "Program Database Files")); 34 | } 35 | 36 | @Override 37 | public void setCurrentDirectory(File directory) { 38 | super.setCurrentDirectory(directory); 39 | 40 | if (useModulePdbPath) { 41 | worker.schedule(new CheckPdbPath(directory)); 42 | } 43 | } 44 | 45 | public PdbResult getValidatedResult() { 46 | return result; 47 | } 48 | 49 | public File getValidatedRoot() { 50 | return rootDirectory; 51 | } 52 | 53 | private class CheckPdbPath extends Job { 54 | 55 | private File currentDirectory; 56 | public CheckPdbPath(File currentDirectory) { 57 | this.currentDirectory = currentDirectory; 58 | } 59 | 60 | @Override 61 | public void run(TaskMonitor monitor) { 62 | 63 | PdbResult candidateResult = PdbResolver.tryFindSymbols(currentDirectory, pdbAttributes, monitor); 64 | if (candidateResult != null) { 65 | SystemUtilities.runSwingLater(() -> { 66 | rootDirectory = currentDirectory; 67 | result = candidateResult; 68 | setSelectedFile(result.file); 69 | close(); 70 | }); 71 | } 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/rich/RichTableRecordDataType.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.rich; 17 | 18 | import ghidra.docking.settings.Settings; 19 | import ghidra.program.model.data.*; 20 | import ghidra.program.model.mem.MemBuffer; 21 | 22 | class RichTableRecordDataType extends StructureDataType { 23 | 24 | private final RichHeaderRecord record; 25 | 26 | public RichTableRecordDataType(RichHeaderRecord record) { 27 | this(null, record); 28 | } 29 | 30 | public RichTableRecordDataType(DataTypeManager dtm, RichHeaderRecord record) { 31 | super(new CategoryPath("/PE"), "MSRichRecord", 0, dtm); 32 | this.record = record; 33 | 34 | initialize(); 35 | } 36 | 37 | @Override 38 | public boolean hasLanguageDependantLength() { 39 | return false; 40 | } 41 | 42 | @Override 43 | public RichTableRecordDataType clone(DataTypeManager dtm) { 44 | if (dtm == getDataTypeManager()) { 45 | return this; 46 | } 47 | return new RichTableRecordDataType(dtm, record); 48 | } 49 | 50 | @Override 51 | public String getMnemonic(Settings settings) { 52 | return "MSRichRecord"; 53 | } 54 | 55 | @Override 56 | public int getLength() { 57 | return 8; 58 | } 59 | 60 | @Override 61 | public String getDescription() { 62 | return "MS Rich Table Record"; 63 | } 64 | 65 | @Override 66 | public Object getValue(MemBuffer buf, Settings settings, int length) { 67 | return record; 68 | } 69 | 70 | @Override 71 | public String getRepresentation(MemBuffer buf, Settings settings, int length) { 72 | return ""; 73 | } 74 | 75 | @Override 76 | public DataType copy(DataTypeManager dtm) { 77 | return clone(dtm); 78 | } 79 | 80 | private void initialize() { 81 | add(new MSRichProductInfoDataType(record.getCompId()), 4, "productInfo", null); 82 | add(new RichObjectCountDataType(record.getObjectCount()), 4, "objectCount", null); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableAssemblyOS.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.*; 23 | 24 | /** 25 | * Describes the AssemblyOS table. Apparently it is ignored by the CLI and shouldn't be found in an Assembly. 26 | */ 27 | public class CliTableAssemblyOS extends CliAbstractTable { 28 | public class CliAssemblyOSRow extends CliAbstractTableRow { 29 | public int osPlatformID; 30 | public int osMajorVersion; 31 | public int osMinorVersion; 32 | 33 | public CliAssemblyOSRow(int osPlatformID, int osMajorVersion, int osMinorVersion) { 34 | super(); 35 | this.osPlatformID = osPlatformID; 36 | this.osMajorVersion = osMajorVersion; 37 | this.osMinorVersion = osMinorVersion; 38 | } 39 | 40 | @Override 41 | public String getRepresentation() { 42 | return String.format("Platform %d v%d.%d", osPlatformID, osMajorVersion, osMinorVersion); 43 | } 44 | } 45 | 46 | public CliTableAssemblyOS(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 47 | super(reader, stream, tableId); 48 | for (int i = 0; i < this.numRows; i++) { 49 | rows.add(new CliAssemblyOSRow(reader.readNextInt(), reader.readNextInt(), reader.readNextInt())); 50 | } 51 | } 52 | 53 | @Override 54 | public DataType getRowDataType() { 55 | return toDataType(); 56 | } 57 | 58 | @Override 59 | public DataType toDataType() { 60 | Structure rowDt = new StructureDataType(new CategoryPath(PATH), "AssemblyOS Row", 0); 61 | rowDt.add(DWORD, "OSPlatformID", null); 62 | rowDt.add(DWORD, "OSMajorVersion", null); 63 | rowDt.add(DWORD, "OSMinorVersion", null); 64 | return new ArrayDataType(rowDt, this.numRows, rowDt.getLength()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableEventMap.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the EventMap table. Each row is an event list for a class. 27 | */ 28 | public class CliTableEventMap extends CliAbstractTable { 29 | public class CliEventMapRow extends CliAbstractTableRow { 30 | public int parentIndex; 31 | public int eventIndex; 32 | 33 | public CliEventMapRow(int parentIndex, int eventIndex) { 34 | super(); 35 | this.parentIndex = parentIndex; 36 | this.eventIndex = eventIndex; 37 | } 38 | 39 | @Override 40 | public String getRepresentation() { 41 | return String.format("Parent %s EventList %s", getRowRepresentationSafe(CliTypeTable.TypeDef, parentIndex), getRowRepresentationSafe(CliTypeTable.Event, eventIndex)); 42 | } 43 | } 44 | 45 | public CliTableEventMap(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 46 | super(reader, stream, tableId); 47 | for (int i = 0; i < this.numRows; i++) { 48 | rows.add(new CliEventMapRow(readTableIndex(reader, CliTypeTable.TypeDef), readTableIndex(reader, CliTypeTable.Event))); 49 | } 50 | } 51 | 52 | @Override 53 | public StructureDataType getRowDataType() { 54 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "EventMap Row", 0); 55 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.TypeDef), "Parent", null); 56 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.Event), "EventList", "First of a contiguous run in Event table, ending with next EventMap reference or end of table."); 57 | return rowDt; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableClassLayout.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the ClassLayout table. Each row has information that's useful when handing something from managed to unmanaged code. 27 | */ 28 | public class CliTableClassLayout extends CliAbstractTable { 29 | public class CliClassLayoutRow extends CliAbstractTableRow { 30 | public short packingSize; 31 | public int classSize; 32 | public int parentIndex; 33 | 34 | public CliClassLayoutRow(short packingSize, int classSize, int parentIndex) { 35 | super(); 36 | this.packingSize = packingSize; 37 | this.classSize = classSize; 38 | this.parentIndex = parentIndex; 39 | } 40 | 41 | @Override 42 | public String getRepresentation() { 43 | return String.format("Packing %d ClassSize %d Parent %s", packingSize, classSize, 44 | getRowRepresentationSafe(CliTypeTable.TypeDef, parentIndex)); 45 | } 46 | } 47 | 48 | public CliTableClassLayout(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 49 | super(reader, stream, tableId); 50 | for (int i = 0; i < this.numRows; i++) { 51 | rows.add(new CliClassLayoutRow(reader.readNextShort(), reader.readNextInt(), readTableIndex(reader, CliTypeTable.TypeDef))); 52 | } 53 | } 54 | 55 | @Override 56 | public StructureDataType getRowDataType() { 57 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "ClassLayout Row", 0); 58 | rowDt.add( WORD, "PackingSize", null); 59 | rowDt.add(DWORD, "ClassSize", null); 60 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.TypeDef), "Parent", null); 61 | return rowDt; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTypeTable.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | /** 19 | * Possible Metadata table types. 20 | */ 21 | public enum CliTypeTable { 22 | Module(0x00), 23 | TypeRef(0x01), 24 | TypeDef(0x02), 25 | Field(0x04), 26 | MethodDef(0x06), 27 | Param(0x08), 28 | InterfaceImpl(0x09), 29 | MemberRef(0x0a), 30 | Constant(0x0b), 31 | CustomAttribute(0x0c), 32 | FieldMarshal(0x0d), 33 | DeclSecurity(0x0e), 34 | ClassLayout(0x0f), 35 | FieldLayout(0x10), 36 | StandAloneSig(0x11), 37 | EventMap(0x12), 38 | Event(0x14), 39 | PropertyMap(0x15), 40 | Property(0x17), 41 | MethodSemantics(0x18), 42 | MethodImpl(0x19), 43 | ModuleRef(0x1a), 44 | TypeSpec(0x1b), 45 | ImplMap(0x1c), 46 | FieldRVA(0x1d), 47 | Assembly(0x20), 48 | AssemblyProcessor(0x21), 49 | AssemblyOS(0x22), 50 | AssemblyRef(0x23), 51 | AssemblyRefProcessor(0x24), 52 | AssemblyRefOS(0x25), 53 | File(0x26), 54 | ExportedType(0x27), 55 | ManifestResource(0x28), 56 | NestedClass(0x29), 57 | GenericParam(0x2a), 58 | MethodSpec(0x2b), 59 | GenericParamConstraint(0x2c); 60 | 61 | private final int id; 62 | 63 | /** 64 | * Creates a new table type from the given ID. 65 | * 66 | * @param id The ID of the table type to create. 67 | */ 68 | private CliTypeTable(int id) { 69 | this.id = id; 70 | } 71 | 72 | /** 73 | * Gets the ID associated with this table type. 74 | * 75 | * @return The ID associated with this table type. 76 | */ 77 | public int id() { 78 | return id; 79 | } 80 | 81 | /** 82 | * Gets a table type from the given ID. 83 | * 84 | * @param id The ID of the table type to get. 85 | * @return A table type with the given ID, or null if one doesn't exist. 86 | */ 87 | public static CliTypeTable fromId(int id) { 88 | CliTypeTable[] values = CliTypeTable.values(); 89 | for (CliTypeTable value : values) { 90 | if (value.id == id) 91 | return value; 92 | } 93 | return null; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableNestedClass.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the NestedClass table. Each row is a nested class. 27 | */ 28 | public class CliTableNestedClass extends CliAbstractTable { 29 | public class CliNestedClassRow extends CliAbstractTableRow { 30 | public int nestedClassIndex; 31 | public int enclosingClassIndex; 32 | 33 | public CliNestedClassRow(int nestedClassIndex, int enclosingClassIndex) { 34 | super(); 35 | this.nestedClassIndex = nestedClassIndex; 36 | this.enclosingClassIndex = enclosingClassIndex; 37 | } 38 | 39 | @Override 40 | public String getRepresentation() { 41 | return String.format("%s is nested in %s", getRowRepresentationSafe(CliTypeTable.TypeDef, nestedClassIndex), getRowRepresentationSafe(CliTypeTable.TypeDef, enclosingClassIndex)); 42 | } 43 | } 44 | 45 | public CliTableNestedClass(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 46 | super(reader, stream, tableId); 47 | for (int i = 0; i < this.numRows; i++) { 48 | rows.add(new CliNestedClassRow(readTableIndex(reader, CliTypeTable.TypeDef), readTableIndex(reader, CliTypeTable.TypeDef))); 49 | } 50 | reader.setPointerIndex(this.readerOffset); 51 | } 52 | 53 | @Override 54 | public StructureDataType getRowDataType() { 55 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "NestedClass Row", 0); 56 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.TypeDef), "NestedClass", "TypeDef index"); 57 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.TypeDef), "EnclosingClass", "TypeDef index"); 58 | return rowDt; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/new_/AbstractModuleBaseOffsetDataType.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.contrib.new_; 2 | 3 | import ghidra.docking.settings.Settings; 4 | import ghidra.program.model.address.Address; 5 | import ghidra.program.model.address.AddressOutOfBoundsException; 6 | import ghidra.program.model.data.BuiltIn; 7 | import ghidra.program.model.data.CategoryPath; 8 | import ghidra.program.model.data.DataType; 9 | import ghidra.program.model.data.DataTypeManager; 10 | import ghidra.program.model.mem.MemBuffer; 11 | import ghidra.program.model.scalar.Scalar; 12 | 13 | abstract class AbstractModuleBaseOffsetDataType extends BuiltIn { 14 | 15 | public AbstractModuleBaseOffsetDataType(CategoryPath path, String name, DataTypeManager dtm) { 16 | super(path, name, dtm); 17 | } 18 | 19 | abstract DataType getScalarDataType(); 20 | 21 | static String generateName(DataType dt) { 22 | return "ModuleBaseOffset" + dt.getLength() * 8; 23 | } 24 | 25 | static String generateMnemonic(DataType dt) { 26 | return "mbo" + dt.getLength() * 8; 27 | } 28 | 29 | static String generateDescription(DataType dt) { 30 | return (dt.getLength() * 8) + "-bit Module Base Offset"; 31 | } 32 | 33 | @Override 34 | public String getDescription() { 35 | DataType dt = getScalarDataType(); 36 | return generateDescription(dt); 37 | } 38 | 39 | @Override 40 | public String getMnemonic(Settings settings) { 41 | DataType dt = getScalarDataType(); 42 | return generateMnemonic(dt); 43 | } 44 | 45 | @Override 46 | public int getLength() { 47 | return getScalarDataType().getLength(); 48 | } 49 | 50 | @Override 51 | public boolean hasLanguageDependantLength() { 52 | return false; 53 | } 54 | 55 | @Override 56 | public String getRepresentation(MemBuffer buf, Settings settings, int length) { 57 | Address addr = (Address) getValue(buf, settings, length); 58 | if (addr == null) 59 | return "NaP"; 60 | return addr.toString(); 61 | } 62 | 63 | @Override 64 | public Object getValue(MemBuffer buf, Settings settings, int length) { 65 | Address moduleBase = ModuleBaseMap.getModuleBase(buf.getMemory().getProgram(), buf.getAddress()); 66 | if (moduleBase == null) { 67 | return null; 68 | } 69 | 70 | Scalar value = (Scalar) getScalarDataType().getValue(buf, settings, length); 71 | if (value == null || value.getUnsignedValue() == 0) { 72 | return null; 73 | } 74 | 75 | try { 76 | return moduleBase.add(value.getUnsignedValue()); 77 | } catch (AddressOutOfBoundsException e) { 78 | return null; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/S_LDATA32_NEW.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | * 27 | */ 28 | class S_LDATA32_NEW extends DebugSymbol{ 29 | private int reserved; 30 | private byte [] padding; 31 | 32 | static S_LDATA32_NEW createS_LDATA32_NEW(short length, short type, 33 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 34 | S_LDATA32_NEW s_ldata32_new = (S_LDATA32_NEW) reader.getFactory().create(S_LDATA32_NEW.class); 35 | s_ldata32_new.initS_LDATA32_NEW(length, type, reader, ptr); 36 | return s_ldata32_new; 37 | } 38 | 39 | /** 40 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 41 | */ 42 | public S_LDATA32_NEW() {} 43 | 44 | private void initS_LDATA32_NEW(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 45 | processDebugSymbol(length, type); 46 | reserved = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 47 | offset = reader.readInt (ptr); ptr+=BinaryReader.SIZEOF_INT; 48 | section = reader.readShort(ptr); ptr+=BinaryReader.SIZEOF_SHORT; 49 | 50 | byte nameLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 51 | 52 | this.name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 53 | ptr+=nameLen; 54 | 55 | int sizeOfPadding = Conv.shortToInt(length) - 56 | BinaryReader.SIZEOF_SHORT - 57 | BinaryReader.SIZEOF_INT - 58 | BinaryReader.SIZEOF_INT - 59 | BinaryReader.SIZEOF_SHORT - 60 | BinaryReader.SIZEOF_BYTE - 61 | Conv.byteToInt(nameLen); 62 | 63 | padding = reader.readByteArray(ptr, sizeOfPadding); 64 | } 65 | 66 | public int getReserved() { 67 | return reserved; 68 | } 69 | public byte [] getPadding() { 70 | return padding; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/resource/ResourceDirectoryStringU.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.resource; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import ghidra.app.util.bin.StructConverter; 22 | import ghidra.app.util.bin.format.*; 23 | import ghidra.program.model.data.*; 24 | import ghidra.util.exception.DuplicateNameException; 25 | 26 | /** 27 | *
28 |  * typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
29 |  *     WORD    Length;
30 |  *     WCHAR   NameString[ 1 ];
31 |  * };
32 |  * 
33 | */ 34 | public class ResourceDirectoryStringU implements StructConverter { 35 | public final static String NAME = "IMAGE_RESOURCE_DIR_STRING_U"; 36 | 37 | private short length; 38 | private String nameString; 39 | 40 | /** 41 | * Constructor. 42 | * @param reader the binary reader 43 | * @param index the index where this resource string begins 44 | */ 45 | public ResourceDirectoryStringU(FactoryBundledWithBinaryReader reader, int index) throws IOException { 46 | length = reader.readShort(index); 47 | nameString = reader.readUnicodeString(index+BinaryReader.SIZEOF_SHORT, length); 48 | } 49 | 50 | /** 51 | * Returns the length of the string, in bytes. 52 | * @return the length of the string, in bytes 53 | */ 54 | public short getLength() { 55 | return length; 56 | } 57 | 58 | /** 59 | * Returns the resource name string. 60 | * @return the resource name string 61 | */ 62 | public String getNameString() { 63 | return nameString; 64 | } 65 | 66 | public DataType toDataType() throws DuplicateNameException, IOException { 67 | StructureDataType struct = new StructureDataType(NAME+"_"+(length*2), 0); 68 | struct.add(WORD, "Length", null); 69 | struct.add(UTF16, length*2, "NameString", null); 70 | struct.setCategoryPath(new CategoryPath("/PE")); 71 | return struct; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return nameString; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/OMFDirEntry.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.debug; 17 | 18 | import ghidra.app.util.bin.*; 19 | import ghidra.app.util.bin.format.*; 20 | 21 | import java.io.*; 22 | 23 | /** 24 | *
25 |  * typedef struct OMFDirEntry {
26 |  *     unsigned short  SubSection;     // subsection type (sst...)
27 |  *     unsigned short  iMod;           // module index
28 |  *     long            lfo;            // large file offset of subsection
29 |  *     unsigned long   cb;             // number of bytes in subsection
30 |  * };
31 |  * 
32 | */ 33 | class OMFDirEntry { 34 | final static int IMAGE_SIZEOF_OMF_DIR_ENTRY = 12; 35 | 36 | private short subsection; 37 | private short imod; 38 | private int lfo; 39 | private int cb; 40 | 41 | static OMFDirEntry createOMFDirEntry( 42 | FactoryBundledWithBinaryReader reader, int index) 43 | throws IOException { 44 | OMFDirEntry omfDirEntry = (OMFDirEntry) reader.getFactory().create(OMFDirEntry.class); 45 | omfDirEntry.initOMFDirEntry(reader, index); 46 | return omfDirEntry; 47 | } 48 | 49 | /** 50 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 51 | */ 52 | public OMFDirEntry() {} 53 | 54 | private void initOMFDirEntry(FactoryBundledWithBinaryReader reader, int index) throws IOException { 55 | subsection = reader.readShort(index); index+=BinaryReader.SIZEOF_SHORT; 56 | imod = reader.readShort(index); index+=BinaryReader.SIZEOF_SHORT; 57 | lfo = reader.readInt (index); index+=BinaryReader.SIZEOF_INT; 58 | cb = reader.readInt (index); index+=BinaryReader.SIZEOF_INT; 59 | } 60 | 61 | short getSubSectionType() { 62 | return subsection; 63 | } 64 | short getModuleIndex() { 65 | return imod; 66 | } 67 | int getLargeFileOffset() { 68 | return lfo; 69 | } 70 | int getNumberOfBytes() { 71 | return cb; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/DataSym32.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | 22 | import java.io.*; 23 | 24 | /** 25 | *
26 |  * typedef struct DATASYM32 {
27 |  *     unsigned short  reclen;         // Record length
28 |  *     unsigned short  rectyp;         // S_LDATA32, S_GDATA32 or S_PUB32
29 |  *     CV_uoff32_t     off;            // (unsigned long)
30 |  *     unsigned short  seg;
31 |  *     CV_typ_t        typind;         // Type index (unsigned short)
32 |  *     unsigned char   name[1];        // Length-prefixed name
33 |  * } DATASYM32;
34 |  * 
35 | * 36 | * 37 | */ 38 | class DataSym32 extends DebugSymbol { 39 | private short typeIndex; 40 | private byte nameChar; 41 | 42 | static DataSym32 createDataSym32(short length, short type, 43 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 44 | DataSym32 dataSym32 = (DataSym32) reader.getFactory().create(DataSym32.class); 45 | dataSym32.initDataSym32(length, type, reader, ptr); 46 | return dataSym32; 47 | } 48 | 49 | /** 50 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 51 | */ 52 | public DataSym32() {} 53 | 54 | private void initDataSym32(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 55 | processDebugSymbol(length, type); 56 | 57 | this.offset = reader.readInt (ptr); ptr += BinaryReader.SIZEOF_INT; 58 | this.section = reader.readShort(ptr); ptr += BinaryReader.SIZEOF_SHORT; 59 | this.typeIndex = reader.readShort(ptr); ptr += BinaryReader.SIZEOF_SHORT; 60 | this.nameChar = reader.readByte (ptr); ptr += BinaryReader.SIZEOF_BYTE; 61 | this.name = reader.readAsciiString(ptr); ptr += name.length(); 62 | } 63 | 64 | int getTypeIndex() { 65 | return typeIndex; 66 | } 67 | byte getNameChar() { 68 | return nameChar; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/DebugFixupElement.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import java.io.IOException; 20 | 21 | import ghidra.app.util.bin.BinaryReader; 22 | import ghidra.app.util.bin.format.*; 23 | 24 | /** 25 | * A possible implementation of the FIXUP debug directory elements. 26 | * It may be inaccurate and/or incomplete. 27 | * 28 | * 29 | */ 30 | public class DebugFixupElement { 31 | final static int SIZEOF = 12; 32 | 33 | private int type; 34 | private int addr1; 35 | private int addr2; 36 | 37 | static DebugFixupElement createDebugFixupElement( 38 | FactoryBundledWithBinaryReader reader, int index) 39 | throws IOException { 40 | DebugFixupElement debugFixupElement = (DebugFixupElement) reader.getFactory().create(DebugFixupElement.class); 41 | debugFixupElement.initDebugFixupElement(reader, index); 42 | return debugFixupElement; 43 | } 44 | 45 | /** 46 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 47 | */ 48 | public DebugFixupElement() {} 49 | 50 | private void initDebugFixupElement(FactoryBundledWithBinaryReader reader, int index) throws IOException { 51 | type = reader.readInt(index); index += BinaryReader.SIZEOF_INT; 52 | addr1 = reader.readInt(index); index += BinaryReader.SIZEOF_INT; 53 | addr2 = reader.readInt(index); index += BinaryReader.SIZEOF_INT; 54 | } 55 | 56 | /** 57 | * Returns the FIXUP element type. 58 | * @return the FIXUP element type 59 | */ 60 | public int getType() { 61 | return type; 62 | } 63 | /** 64 | * Returns the first address of this FIXUP element. 65 | * @return the first address of this FIXUP element 66 | */ 67 | public int getAddress1() { 68 | return addr1; 69 | } 70 | /** 71 | * Returns the second address of this FIXUP element. 72 | * @return the second address of this FIXUP element 73 | */ 74 | public int getAddress2() { 75 | return addr2; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTablePropertyMap.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.CategoryPath; 23 | import ghidra.program.model.data.StructureDataType; 24 | 25 | /** 26 | * Describes the PropertyMap class. Each row points to a list of properties in the Property table owned by a class. 27 | */ 28 | public class CliTablePropertyMap extends CliAbstractTable { 29 | public class CliPropertyMapRow extends CliAbstractTableRow { 30 | public int parentIndex; 31 | public int propertyListIndex; 32 | 33 | public CliPropertyMapRow(int parentIndex, int propertyListIndex) { 34 | super(); 35 | this.parentIndex = parentIndex; 36 | this.propertyListIndex = propertyListIndex; 37 | } 38 | 39 | @Override 40 | public String getRepresentation() { 41 | // TODO: plist index points to contiguous run of properties 42 | return String.format("Parent %s Properties %x", getRowRepresentationSafe(CliTypeTable.TypeDef, parentIndex), propertyListIndex); 43 | } 44 | } 45 | 46 | public CliTablePropertyMap(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 47 | super(reader, stream, tableId); 48 | for (int i = 0; i < this.numRows; i++) { 49 | rows.add(new CliPropertyMapRow(readTableIndex(reader, CliTypeTable.TypeDef), readTableIndex(reader, CliTypeTable.Property))); 50 | } 51 | reader.setPointerIndex(this.readerOffset); 52 | } 53 | 54 | @Override 55 | public StructureDataType getRowDataType() { 56 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "PropertyMap Row", 0); 57 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.TypeDef), "Parent", null); 58 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.Property), "options", "Index into Property table. Points to contiguous run of Properties until next ref from PropertyMap or end of table."); 59 | return rowDt; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/DataSym32_new.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * REVIEWED: YES 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package net.jubjubnest.minidump.contrib.pe.debug; 18 | 19 | import ghidra.app.util.bin.*; 20 | import ghidra.app.util.bin.format.*; 21 | import ghidra.util.*; 22 | 23 | import java.io.*; 24 | 25 | /** 26 | *
27 |  * typedef struct DATASYM32_NEW {
28 |  *     unsigned short  reclen;         // Record length
29 |  *     unsigned short  rectyp;         // S_LDATA32, S_GDATA32 or S_PUB32
30 |  *     CVTYPEINDEX     typind;
31 |  *     unsigned long   off;
32 |  *     unsigned short  seg;
33 |  *     unsigned char   name[1];        // Length-prefixed name
34 |  * } DATASYM32_NEW;
35 |  * 
36 | * 37 | * 38 | */ 39 | class DataSym32_new extends DebugSymbol { 40 | private int typeIndex; 41 | private byte nameChar; 42 | 43 | static DataSym32_new createDataSym32_new(short length, short type, 44 | FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 45 | DataSym32_new dataSym32_new = (DataSym32_new) reader.getFactory().create(DataSym32_new.class); 46 | dataSym32_new.initDataSym32_new(length, type, reader, ptr); 47 | return dataSym32_new; 48 | } 49 | 50 | /** 51 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 52 | */ 53 | public DataSym32_new() {} 54 | 55 | private void initDataSym32_new(short length, short type, FactoryBundledWithBinaryReader reader, int ptr) throws IOException { 56 | processDebugSymbol(length, type); 57 | 58 | this.typeIndex = reader.readInt (ptr); ptr += BinaryReader.SIZEOF_INT; 59 | this.offset = reader.readInt (ptr); ptr += BinaryReader.SIZEOF_INT; 60 | this.section = reader.readShort(ptr); ptr += BinaryReader.SIZEOF_SHORT; 61 | 62 | byte nameLen = reader.readByte(ptr); ptr += BinaryReader.SIZEOF_BYTE; 63 | 64 | this.name = reader.readAsciiString(ptr, Conv.byteToInt(nameLen)); 65 | } 66 | 67 | int getTypeIndex() { 68 | return typeIndex; 69 | } 70 | byte getNameChar() { 71 | return nameChar; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/DefaultDataDirectory.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; 21 | import ghidra.app.util.importer.MessageLog; 22 | import ghidra.program.model.data.*; 23 | import ghidra.program.model.listing.Program; 24 | import ghidra.util.exception.DuplicateNameException; 25 | import ghidra.util.task.TaskMonitor; 26 | import net.jubjubnest.minidump.contrib.new_.ImageLoadInfo; 27 | 28 | public class DefaultDataDirectory extends DataDirectory { 29 | 30 | static DefaultDataDirectory createDefaultDataDirectory( 31 | NTHeader ntHeader, FactoryBundledWithBinaryReader reader) 32 | throws IOException { 33 | DefaultDataDirectory defaultDataDirectory = (DefaultDataDirectory) reader.getFactory().create(DefaultDataDirectory.class); 34 | defaultDataDirectory.initDefaultDataDirectory(ntHeader, reader); 35 | return defaultDataDirectory; 36 | } 37 | 38 | /** 39 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 40 | */ 41 | public DefaultDataDirectory() {} 42 | 43 | private void initDefaultDataDirectory(NTHeader ntHeader, FactoryBundledWithBinaryReader reader) throws IOException { 44 | processDataDirectory(ntHeader, reader); 45 | } 46 | 47 | @Override 48 | public String getDirectoryName() { 49 | return TITLE; 50 | } 51 | 52 | @Override 53 | public boolean parse() throws IOException { 54 | //do nothing 55 | return true; 56 | } 57 | 58 | @Override 59 | public void markup(Program program, boolean isBinary, TaskMonitor monitor, 60 | MessageLog log, NTHeader ntHeader) { 61 | //do nothing 62 | } 63 | 64 | @Override 65 | public DataType toDataType() throws DuplicateNameException, IOException { 66 | StructureDataType ddstruct = new StructureDataType(DataDirectory.TITLE,0); 67 | ddstruct.add(DWORD, "VirtualAddress", null); 68 | ddstruct.add(DWORD, "Size", null); 69 | ddstruct.setCategoryPath(new CategoryPath("/PE")); 70 | return ddstruct; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableParam.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import net.jubjubnest.minidump.contrib.pe.cli.tables.flags.CliFlags.CliEnumParamAttributes; 23 | import ghidra.program.model.data.CategoryPath; 24 | import ghidra.program.model.data.StructureDataType; 25 | 26 | /** 27 | * Describes the Param table. Each row represents a method's parameter. 28 | */ 29 | public class CliTableParam extends CliAbstractTable { 30 | public class CliParamRow extends CliAbstractTableRow { 31 | public short flags; 32 | public short sequence; 33 | public int nameIndex; 34 | 35 | public CliParamRow(short flags, short sequence, int nameIndex) { 36 | super(); 37 | this.flags = flags; 38 | this.sequence = sequence; 39 | this.nameIndex = nameIndex; 40 | } 41 | 42 | @Override 43 | public String getRepresentation() { 44 | return String.format("%s Flags %s Sequence %x", 45 | metadataStream.getStringsStream().getString(nameIndex), 46 | CliEnumParamAttributes.dataType.getName(flags & 0xffff), sequence); 47 | } 48 | } 49 | 50 | public CliTableParam(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 51 | super(reader, stream, tableId); 52 | for (int i = 0; i < this.numRows; i++) { 53 | CliParamRow row = new CliParamRow(reader.readNextShort(), reader.readNextShort(), readStringIndex(reader)); 54 | rows.add(row); 55 | strings.add(row.nameIndex); 56 | } 57 | reader.setPointerIndex(this.readerOffset); 58 | } 59 | 60 | @Override 61 | public StructureDataType getRowDataType() { 62 | StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "ParamRow",0); 63 | rowDt.add(CliEnumParamAttributes.dataType, "Flags", "bitmask of type ParamAttributes"); 64 | rowDt.add( WORD, "Sequence", "constant"); 65 | rowDt.add(metadataStream.getStringIndexDataType(), "Name", "index into String heap"); 66 | return rowDt; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/resource/ResourceDirectoryString.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.resource; 17 | 18 | import ghidra.app.util.bin.BinaryReader; 19 | import ghidra.app.util.bin.StructConverter; 20 | import ghidra.program.model.data.*; 21 | import ghidra.util.exception.DuplicateNameException; 22 | 23 | import java.io.IOException; 24 | 25 | /** 26 | *
27 |  * typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
28 |  *     WORD    Length;
29 |  *     CHAR    NameString[ 1 ];
30 |  * };
31 |  * 
32 | */ 33 | public class ResourceDirectoryString implements StructConverter { 34 | public final static String NAME = "IMAGE_RESOURCE_DIRECTORY_STRING"; 35 | 36 | private short length; 37 | private String nameString; 38 | 39 | /** 40 | * Constructor. 41 | * @param reader the binary reader 42 | * @param index the index where this resource string begins 43 | */ 44 | public ResourceDirectoryString(BinaryReader reader, int index) throws IOException { 45 | length = reader.readShort(index); 46 | nameString = reader.readAsciiString(index+BinaryReader.SIZEOF_SHORT); 47 | if (nameString.length() != length) { 48 | //todo: 49 | throw new IllegalArgumentException("name string length != length"); 50 | } 51 | } 52 | 53 | /** 54 | * Returns the length of the string, in bytes. 55 | * @return the length of the string, in bytes 56 | */ 57 | public short getLength() { 58 | return length; 59 | } 60 | 61 | /** 62 | * Returns the resource name string. 63 | * @return the resource name string 64 | */ 65 | public String getNameString() { 66 | return nameString; 67 | } 68 | 69 | public DataType toDataType() throws DuplicateNameException, IOException { 70 | StructureDataType struct = new StructureDataType(NAME+"_"+length, 0); 71 | struct.add(WORD, "Length", null); 72 | struct.add(STRING, length, "NameString", null); 73 | struct.setCategoryPath(new CategoryPath("/PE")); 74 | return struct; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return nameString; 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/ExportInfo.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe; 17 | 18 | /** 19 | * A class to hold the information extracted from a 20 | * export data directory. 21 | * 22 | * NOTE: 23 | * This class is simply a storage class created for 24 | * parsing the PE header data structures. 25 | * It does not map back to a PE data data structure. 26 | * 27 | * 28 | */ 29 | public class ExportInfo { 30 | private long address; 31 | private int ordinal; 32 | private String name; 33 | private String comment; 34 | private boolean forwarded; 35 | 36 | ExportInfo(long address, int ordinal, String name, String cmt, boolean forwarded) { 37 | this.address = address; 38 | this.ordinal = ordinal; 39 | this.name = name; 40 | this.comment = cmt; 41 | this.forwarded = forwarded; 42 | } 43 | 44 | /** 45 | * Returns the adjusted address where the export occurs. 46 | * @return the adjusted address where the export occurs 47 | */ 48 | public long getAddress() { 49 | return address; 50 | } 51 | 52 | /** 53 | * Returns the ordinal value of the export. 54 | * @return the ordinal value of the export 55 | */ 56 | public int getOrdinal() { 57 | return ordinal; 58 | } 59 | 60 | /** 61 | * Returns the name of the export. 62 | * @return the name of the export 63 | */ 64 | public String getName() { 65 | return name; 66 | } 67 | 68 | /** 69 | * Returns a comment string containing extra information about the export. 70 | * @return a comment string containing extra information about the export 71 | */ 72 | public String getComment() { 73 | return comment; 74 | } 75 | 76 | /** 77 | * Returns true of this export is going to be forwarded. 78 | * Generally, a forwarded export just through another export. 79 | * @return true of this export is going to be forwarded 80 | */ 81 | public boolean isForwarded() { 82 | return forwarded; 83 | } 84 | 85 | /** 86 | * @see java.lang.Object#toString() 87 | */ 88 | @Override 89 | public String toString() { 90 | return ordinal+" "+name+" at "+Long.toHexString(address); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/tables/CliTableAssemblyRefOS.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.tables; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.*; 23 | 24 | /** 25 | * Describes the AssemblyRefOS table. Apparently it is ignored by the CLI and shouldn't be found in an assembly. 26 | */ 27 | public class CliTableAssemblyRefOS extends CliAbstractTable { 28 | public class CliAssemblyRefOSRow extends CliAbstractTableRow { 29 | public int osPlatformID; 30 | public int osMajorVersion; 31 | public int osMinorVersion; 32 | public int assemblyRefIndex; 33 | 34 | public CliAssemblyRefOSRow(int osPlatformID, int osMajorVersion, int osMinorVersion, int assemblyRefIndex) { 35 | super(); 36 | this.osPlatformID = osPlatformID; 37 | this.osMajorVersion = osMajorVersion; 38 | this.osMinorVersion = osMinorVersion; 39 | this.assemblyRefIndex = assemblyRefIndex; 40 | } 41 | 42 | @Override 43 | public String getRepresentation() { 44 | return String.format("%d v%d.%d", osPlatformID, osMajorVersion, osMinorVersion); 45 | } 46 | } 47 | 48 | public CliTableAssemblyRefOS(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException { 49 | super(reader, stream, tableId); 50 | for (int i = 0; i < this.numRows; i++) { 51 | rows.add(new CliAssemblyRefOSRow(reader.readNextInt(), reader.readNextInt(), reader.readNextInt(), readTableIndex(reader, CliTypeTable.AssemblyRef))); 52 | } 53 | } 54 | 55 | @Override 56 | public DataType getRowDataType() { 57 | return toDataType(); 58 | } 59 | 60 | @Override 61 | public DataType toDataType() { 62 | Structure rowDt = new StructureDataType(new CategoryPath(PATH), "AssemblyRefOS Row", 0); 63 | rowDt.add(DWORD, "OSPlatformID", null); 64 | rowDt.add(DWORD, "OSMajorVersion", null); 65 | rowDt.add(DWORD, "OSMinorVersion", null); 66 | rowDt.add(metadataStream.getTableIndexDataType(CliTypeTable.AssemblyRef), "AssemblyRef", "index into AssemblyRef table"); 67 | return new ArrayDataType(rowDt, this.numRows, rowDt.getLength()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/cli/blobs/CliSigField.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.cli.blobs; 17 | 18 | import java.io.IOException; 19 | 20 | import ghidra.app.util.bin.BinaryReader; 21 | import net.jubjubnest.minidump.contrib.pe.cli.streams.CliStreamMetadata; 22 | import ghidra.program.model.data.*; 23 | import ghidra.util.Msg; 24 | import ghidra.util.exception.InvalidInputException; 25 | 26 | public class CliSigField extends CliAbstractSig { 27 | private CliParam type; 28 | 29 | private static final byte CLISIGFIELD_PROLOG = 0x06; 30 | 31 | public CliSigField(CliBlob blob) throws IOException { 32 | super(blob); 33 | 34 | BinaryReader reader = getContentsReader(); 35 | 36 | byte prolog = reader.readNextByte(); 37 | if (prolog != CLISIGFIELD_PROLOG) { 38 | Msg.warn(this, 39 | "CliSigField had unexpected prolog (0x" + Integer.toHexString(prolog) + ")."); 40 | return; 41 | } 42 | 43 | try { 44 | type = new CliParam(reader); 45 | } 46 | catch (InvalidInputException e) { 47 | type = null; 48 | } 49 | } 50 | 51 | /** 52 | * Checks whether this could *possibly* be a FieldSig. Only looks at the identifier byte. Useful for signature index 53 | * that could be to different kinds of signatures. 54 | * @param blob 55 | * @return 56 | * @throws IOException 57 | */ 58 | public static boolean isFieldSig(CliBlob blob) throws IOException { 59 | return blob.getContentsReader().readNextByte() == CLISIGFIELD_PROLOG; 60 | } 61 | 62 | public CliParam getType() { 63 | return type; 64 | } 65 | 66 | @Override 67 | public DataType getContentsDataType() { 68 | StructureDataType struct = new StructureDataType(new CategoryPath(PATH), getName(), 0); 69 | struct.add(BYTE, "FIELD", "Magic (0x06)"); 70 | struct.add(type.getDefinitionDataType(), "Type", null); 71 | return struct; 72 | } 73 | 74 | @Override 75 | public String getContentsName() { 76 | return "FieldSig"; 77 | } 78 | 79 | @Override 80 | public String getContentsComment() { 81 | return "Type information for Field"; 82 | } 83 | 84 | @Override 85 | public String getRepresentationCommon(CliStreamMetadata stream, boolean isShort) { 86 | return getRepresentationOf(type, stream, isShort); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/analyzer/ModuleParser.java: -------------------------------------------------------------------------------- 1 | package net.jubjubnest.minidump.analyzer; 2 | 3 | import java.io.IOException; 4 | 5 | import ghidra.app.util.bin.BinaryReader; 6 | import ghidra.app.util.bin.ByteProvider; 7 | import ghidra.app.util.bin.MemoryByteProvider; 8 | import ghidra.app.util.datatype.microsoft.GuidUtil; 9 | import ghidra.program.model.address.Address; 10 | import ghidra.program.model.listing.Program; 11 | 12 | class ModuleParser { 13 | public static class PdbInfo { 14 | String guid; 15 | int age; 16 | String pdbName; 17 | } 18 | 19 | public static PdbInfo getPdbInfo(Program program, Address moduleBase) throws IOException { 20 | Address codeviewAddress = optionalHeader(program, moduleBase); 21 | if (codeviewAddress == null) { 22 | return null; 23 | } 24 | 25 | String guid = GuidUtil.getGuidString(program, codeviewAddress.add(4), false); 26 | 27 | ByteProvider provider = new MemoryByteProvider(program.getMemory(), moduleBase); 28 | BinaryReader reader = new BinaryReader(provider, true); 29 | 30 | long offset = codeviewAddress.subtract(moduleBase); 31 | int age = reader.readInt(offset + 0x14); 32 | String pdbName = reader.readAsciiString(offset + 0x18); 33 | 34 | PdbInfo info = new PdbInfo(); 35 | info.guid = guid; 36 | info.age = age; 37 | info.pdbName = pdbName; 38 | return info; 39 | } 40 | 41 | private static Address optionalHeader(Program program, Address moduleBase) throws IOException { 42 | ByteProvider provider = new MemoryByteProvider(program.getMemory(), moduleBase); 43 | BinaryReader reader = new BinaryReader(provider, true); 44 | 45 | // Validate magic bytes at the start of the PE image. 46 | if (!reader.readAsciiString(0, 2).equals("MZ")) { 47 | return null; 48 | } 49 | 50 | // Validate magic bytes at the start of the PE portion of the image. 51 | int peOffset = reader.readInt(0x3C); 52 | if (!reader.readAsciiString(peOffset, 4).equals("PE")) { 53 | return null; 54 | } 55 | 56 | int optOffset = peOffset + 0x18; 57 | if (reader.readShort(optOffset) != 0x020b) { 58 | return null; 59 | } 60 | 61 | int directoryCount = reader.readInt(optOffset + 0x6c); 62 | if (directoryCount < 7) { 63 | return null; 64 | } 65 | 66 | int debugStart = optOffset + 0x70 + 8 * 6; 67 | reader.setPointerIndex(debugStart); 68 | int debugRva = reader.readNextInt(); 69 | int debugSize = reader.readNextInt(); 70 | 71 | int codeviewAddress = 0; 72 | for (int debugCursor = debugRva; debugCursor < debugRva + debugSize; debugCursor += 0x1C) { 73 | int type = reader.readInt(debugCursor + 0xC); 74 | if (type != 2) { 75 | continue; 76 | } 77 | 78 | codeviewAddress = reader.readInt(debugCursor + 0x14); 79 | break; 80 | } 81 | 82 | if (codeviewAddress == 0) { 83 | return null; 84 | } 85 | 86 | return moduleBase.add(codeviewAddress); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /MinidumpLoader/src/main/java/net/jubjubnest/minidump/contrib/pe/debug/DebugFixup.java: -------------------------------------------------------------------------------- 1 | /* ### 2 | * IP: GHIDRA 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.jubjubnest.minidump.contrib.pe.debug; 17 | 18 | import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; 19 | import net.jubjubnest.minidump.contrib.pe.OffsetValidator; 20 | import ghidra.util.Msg; 21 | 22 | import java.io.IOException; 23 | import java.util.ArrayList; 24 | 25 | /** 26 | * A possible implementation of the FIXUP debug directory. 27 | * It may be inaccurate and/or incomplete. 28 | */ 29 | public class DebugFixup { 30 | private DebugFixupElement[] elements; 31 | 32 | /** 33 | * Constructor 34 | * @param reader the binary reader 35 | * @param debugDir the debug directory associated to this FIXUP 36 | * @param ntHeader 37 | */ 38 | static DebugFixup createDebugFixup(FactoryBundledWithBinaryReader reader, 39 | DebugDirectory debugDir, OffsetValidator validator) throws IOException { 40 | DebugFixup debugFixup = (DebugFixup) reader.getFactory().create(DebugFixup.class); 41 | debugFixup.initDebugFixup(reader, debugDir, validator); 42 | return debugFixup; 43 | } 44 | 45 | /** 46 | * DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD. 47 | */ 48 | public DebugFixup() { 49 | } 50 | 51 | private void initDebugFixup(FactoryBundledWithBinaryReader reader, DebugDirectory debugDir, 52 | OffsetValidator validator) throws IOException { 53 | int ptr = debugDir.getPointerToRawData(); 54 | if (!validator.checkPointer(ptr)) { 55 | Msg.error(this, "Invalid pointer " + Long.toHexString(ptr)); 56 | return; 57 | } 58 | int size = debugDir.getSizeOfData(); 59 | 60 | ArrayList list = new ArrayList(); 61 | 62 | while (size > 0) { 63 | list.add(DebugFixupElement.createDebugFixupElement(reader, ptr)); 64 | ptr += DebugFixupElement.SIZEOF; 65 | size -= DebugFixupElement.SIZEOF; 66 | } 67 | 68 | elements = new DebugFixupElement[list.size()]; 69 | list.toArray(elements); 70 | } 71 | 72 | /** 73 | * Returns the array of FIXUP elements associated with this fixup debug directory. 74 | * @return the array of FIXUP elements associated with this fixup debug directory 75 | */ 76 | public DebugFixupElement[] getDebugFixupElements() { 77 | return elements; 78 | } 79 | } 80 | --------------------------------------------------------------------------------