Skip to content

Commit

Permalink
GP-1864 Added loader for dump files. Initial implementation supports MS
Browse files Browse the repository at this point in the history
Minidump, Userdump and Pagedump formats.
  • Loading branch information
d-millar authored and ghidra1 committed Jun 10, 2022
1 parent e55bdc3 commit 9b73a78
Show file tree
Hide file tree
Showing 83 changed files with 13,552 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public boolean parse() throws IOException {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

monitor.setMessage(program.getName()+": debug...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public boolean parse() throws IOException {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

monitor.setMessage(program.getName()+": delay import(s)...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ public boolean parse() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

monitor.setMessage(program.getName()+": exceptions...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
if (!program.getMemory().contains(addr)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,9 @@ public String getExportName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

monitor.setMessage("[" + program.getName() + "]: exports...");

Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {
monitor.setMessage(program.getName()+": global pointers...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
if (!program.getMemory().contains(addr)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException, MemoryAccessException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException,
MemoryAccessException {

if (imports == null || descriptors == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {


monitor.setMessage(program.getName()+": load config directory...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ public short getMinorOperatingSystemVersion() {

@Override
public void processDataDirectories(TaskMonitor monitor) throws IOException {
reader.setPointerIndex(startOfDataDirs);

dataDirectory = new DataDirectory[numberOfRvaAndSizes];
if (numberOfRvaAndSizes == 0) {
return;
Expand Down Expand Up @@ -513,7 +515,7 @@ protected void parse() throws IOException {
if (is64bit()) {
baseOfData = -1;//not used
imageBase = reader.readNextLong();
if (imageBase <= 0) {
if (imageBase <= 0 && !is64bit()) {
Msg.warn(this, "Non-standard image base: 0x" + Long.toHexString(imageBase));
originalImageBase = imageBase;
imageBase = 0x10000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

if (rootDirectory == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

if (!isBinary) {//certificates are never mapped into running program...
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public String getDirectoryName() {

@Override
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
IOException {
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {

monitor.setMessage(program.getName()+": TLS...");
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public Collection<LoadSpec> findSupportedLoadSpecs(ByteProvider provider) throws
return loadSpecs;
}

PortableExecutable pe = new PortableExecutable(provider, SectionLayout.FILE, false, false);
PortableExecutable pe = new PortableExecutable(provider, getSectionLayout(), false, false);
NTHeader ntHeader = pe.getNTHeader();
if (ntHeader != null && ntHeader.getOptionalHeader() != null) {
long imageBase = ntHeader.getOptionalHeader().getImageBase();
Expand All @@ -102,7 +102,7 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
return;
}

PortableExecutable pe = new PortableExecutable(provider, SectionLayout.FILE, false,
PortableExecutable pe = new PortableExecutable(provider, getSectionLayout(), false,
shouldParseCliHeaders(options));

NTHeader ntHeader = pe.getNTHeader();
Expand All @@ -113,7 +113,7 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
FileHeader fileHeader = ntHeader.getFileHeader();

monitor.setMessage("Completing PE header parsing...");
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
FileBytes fileBytes = createFileBytes(provider, program, monitor);
try {
Map<SectionHeader, Address> sectionToAddress =
processMemoryBlocks(pe, program, fileBytes, monitor, log);
Expand Down Expand Up @@ -166,6 +166,16 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
monitor.setMessage("[" + program.getName() + "]: done!");
}

protected SectionLayout getSectionLayout() {
return SectionLayout.FILE;
}

protected FileBytes createFileBytes(ByteProvider provider, Program program, TaskMonitor monitor)
throws IOException, CancelledException {
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);
return fileBytes;
}

@Override
public List<Option> getDefaultOptions(ByteProvider provider, LoadSpec loadSpec,
DomainObject domainObject, boolean loadIntoProgram) {
Expand Down Expand Up @@ -211,7 +221,8 @@ private boolean shouldParseCliHeaders(List<Option> options) {
return PARSE_CLI_HEADERS_OPTION_DEFAULT;
}

private void layoutHeaders(Program program, PortableExecutable pe, NTHeader ntHeader,
private void layoutHeaders(Program program, PortableExecutable pe,
NTHeader ntHeader,
DataDirectory[] datadirs) {
try {
DataType dt = pe.getDOSHeader().toDataType();
Expand Down Expand Up @@ -419,7 +430,6 @@ private void processImports(OptionalHeader optionalHeader, Program program, Task
AddressSpace space = af.getDefaultAddressSpace();

Listing listing = program.getListing();
ReferenceManager refManager = program.getReferenceManager();

ImportInfo[] imports = idd.getImports();
for (ImportInfo importInfo : imports) {
Expand All @@ -441,27 +451,30 @@ private void processImports(OptionalHeader optionalHeader, Program program, Task
setComment(CodeUnit.PRE_COMMENT, address, importInfo.getComment());

Data data = listing.getDefinedDataAt(address);
if (data == null || !(data.getValue() instanceof Address)) {
continue;
if (data != null && data.isPointer()) {
addExternalReference(data, importInfo, log);
}
}
}

Address extAddr = (Address) data.getValue();
if (extAddr != null) {
// remove the existing mem reference that was created
// when making a pointer
data.removeOperandReference(0, extAddr);
protected void addExternalReference(Data pointerData, ImportInfo importInfo, MessageLog log) {
Address extAddr = (Address) pointerData.getValue();
if (extAddr != null) {
// remove the existing mem reference that was created when making a pointer
pointerData.removeOperandReference(0, extAddr);
// symTable.removeSymbol(symTable.getDynamicSymbol(extAddr));

try {
refManager.addExternalReference(address, importInfo.getDLL().toUpperCase(),
importInfo.getName(), extAddr, SourceType.IMPORTED, 0, RefType.DATA);
}
catch (DuplicateNameException e) {
log.appendMsg("External location not created: " + e.getMessage());
}
catch (InvalidInputException e) {
log.appendMsg("External location not created: " + e.getMessage());
}
try {
ReferenceManager refManager = pointerData.getProgram().getReferenceManager();
refManager.addExternalReference(pointerData.getAddress(),
importInfo.getDLL().toUpperCase(),
importInfo.getName(), extAddr, SourceType.IMPORTED, 0, RefType.DATA);
}
catch (DuplicateNameException e) {
log.appendMsg("External location not created: " + e.getMessage());
}
catch (InvalidInputException e) {
log.appendMsg("External location not created: " + e.getMessage());
}
}
}
Expand Down Expand Up @@ -544,11 +557,11 @@ private void processDelayImports(OptionalHeader optionalHeader, Program program,
}

/**
* Mark this location as code in the CodeMap.
* The analyzers will pick this up and disassemble the code.
* Mark this location as code in the CodeMap. The analyzers will pick this up and disassemble
* the code.
*
* TODO: this should be in a common place, so all importers can communicate that something
* is code or data.
* TODO: this should be in a common place, so all importers can communicate that something is
* code or data.
*
* @param program The program to mark up.
* @param address The location.
Expand Down Expand Up @@ -687,7 +700,7 @@ private void processExports(OptionalHeader optionalHeader, Program program, Task
}
}

private Map<SectionHeader, Address> processMemoryBlocks(PortableExecutable pe, Program prog,
protected Map<SectionHeader, Address> processMemoryBlocks(PortableExecutable pe, Program prog,
FileBytes fileBytes, TaskMonitor monitor, MessageLog log)
throws AddressOverflowException {

Expand Down Expand Up @@ -803,7 +816,7 @@ else if (rawDataSize > virtualSize) {
return sectionToAddress;
}

private int getVirtualSize(PortableExecutable pe, SectionHeader[] sections,
protected int getVirtualSize(PortableExecutable pe, SectionHeader[] sections,
AddressSpace space) {
DOSHeader dosHeader = pe.getDOSHeader();
OptionalHeader optionalHeader = pe.getNTHeader().getOptionalHeader();
Expand Down Expand Up @@ -1019,6 +1032,7 @@ private static SectionHeader getSectionHeader(String name, SectionHeader[] list)

/**
* Return true if chararray appears in full, starting at offset bytestart in bytearray
*
* @param bytearray the array of bytes containing the potential match
* @param bytestart the potential start of the match
* @param chararray the array of characters to match
Expand Down
1 change: 1 addition & 0 deletions Ghidra/Features/FileFormats/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies {

api project(':Base')
api project(':Recognizers')
api project(':PDB')

api ':dex-ir:2.0'
api ':dex-reader:2.0'
Expand Down
1 change: 1 addition & 0 deletions Ghidra/Features/FileFormats/certification.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ data/ExtensionPoint.manifest||GHIDRA||||END|
data/android/eclipse-classpath||GHIDRA||reviewed||END|
data/android/eclipse-project||GHIDRA||reviewed||END|
data/crypto/README.txt||GHIDRA||||END|
data/languages/dumpfile.opinion||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/FileFormatsPlugin/FileFormats.html||GHIDRA||||END|
48 changes: 48 additions & 0 deletions Ghidra/Features/FileFormats/data/languages/dumpfile.opinion
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<opinions>
<constraint loader="Dump File Loader">
<constraint compilerSpecID="windows">
<!-- Page/Userdump MachineImageType values -->
<!-- constraint primary="21064" processor="ALPHA" endian="little" size="64" -->
<constraint primary="1824" processor="ARM" endian="little" size="32" variant="v8" />
<constraint primary="2080" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
<constraint primary="2336" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
<constraint primary="2577" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
<constraint primary="70001" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
<!-- constraint primary="2200" processor="IA64" endian="little" size="64" -->
<constraint primary="4000" processor="MIPS" endian="little" size="32" variant="default" /> <!-- R4000 -->
<!-- constraint primary="821" processor="MOTOROLA" endian="little" size="64" -->
<!-- constraint primary="18767" processor="OPTIL" endian="little" size="64" -->
<constraint primary="103" processor="SuperH3" endian="little" size="32" />
<constraint primary="104" processor="SuperH4" endian="little" size="32" />
<constraint primary="10003" processor="SuperH4" endian="little" size="32" />
<constraint primary="10004" processor="SuperH4" endian="little" size="32" />
<constraint primary="10005" processor="SuperH4" endian="little" size="32" />
<constraint primary="386" processor="x86" endian="little" size="32" />
<constraint primary="486" processor="x86" endian="little" size="32" />
<constraint primary="586" processor="x86" endian="little" size="32" />
<constraint primary="8664" processor="x86" endian="little" size="64" />
<!-- MDMP Architecture values -->
<constraint primary="0" processor="x86" endian="little" size="32" />
<constraint primary="1" processor="MIPS" endian="little" size="32" />
<!-- constraint primary="2" processor="ALPHA" endian="little" size="32" -->
<constraint primary="4" processor="SuperH4" endian="little" size="32" />
<constraint primary="5" processor="ARM" endian="little" size="32" />
<!-- constraint primary="6" processor="IA64" endian="little" size="32" -->
<!-- constraint primary="7" processor="ALPHA64" endian="little" size="32" -->
<!-- constraint primary="8" processor="MSIL" endian="little" size="32" -->
<constraint primary="9" processor="x86" endian="little" size="64" />
<!-- constraint primary="10" processor="IA32/64" endian="little" size="32" -->
<!-- constraint primary="11" processor="NEUTRAL" endian="little" size="32" -->
<constraint primary="12" processor="ARM" endian="little" size="64" />
<constraint primary="13" processor="ARM" endian="little" size="32" />
<!-- constraint primary="14" processor="IA32" endian="little" size="32" -->
</constraint>
<constraint compilerSpecID="default">
<constraint primary="601" processor="PowerPC" endian="little" size="32" />
<constraint primary="603" processor="PowerPC" endian="little" size="32" />
<constraint primary="604" processor="PowerPC" endian="little" size="32" />
<constraint primary="620" processor="PowerPC" endian="little" size="32" />
<constraint primary="3" processor="PowerPC" endian="little" size="32" />
</constraint>
</constraint>
</opinions>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//Given a raw binary PE image,
//this script will create data structures
//representing the PE header. Including,
//but not limited to, the PE header,
//section headers, optional header, etc.
//@category Binary

import ghidra.app.script.GhidraScript;
import ghidra.file.formats.dump.cmd.ModuleToPeHelper;

public class ApplyPEToDumpFileScript extends GhidraScript {

@Override
public void run() throws Exception {
if (currentProgram != null) {
ModuleToPeHelper.queryModules(currentProgram, monitor);
}
}

}
Loading

0 comments on commit 9b73a78

Please sign in to comment.