├── 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 ListThis 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 MapIMAGE_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
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