mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Merge remote-tracking branch 'origin/GP-4669_ryanmkurtz_pe'
(Closes #6571)
This commit is contained in:
commit
df4f05bcf9
37 changed files with 291 additions and 460 deletions
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,10 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.bin;
|
package ghidra.app.util.bin;
|
||||||
|
|
||||||
import ghidra.util.DataConverter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import ghidra.util.DataConverter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface to convert from a object to a
|
* An interface to convert from a object to a
|
||||||
* byte array.
|
* byte array.
|
||||||
|
@ -31,6 +30,7 @@ public interface ByteArrayConverter {
|
||||||
* of this interface.
|
* of this interface.
|
||||||
* @param dc the data converter to use
|
* @param dc the data converter to use
|
||||||
* @return a byte array representing this object
|
* @return a byte array representing this object
|
||||||
|
* @throws IOException if an IO-related error occurs
|
||||||
*/
|
*/
|
||||||
public byte [] toBytes(DataConverter dc) throws IOException;
|
public byte [] toBytes(DataConverter dc) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.bin;
|
package ghidra.app.util.bin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Byte Provider implementation based on Memory.
|
* A Byte Provider implementation based on Memory.
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,7 @@ public class MemoryMutableByteProvider extends MemoryByteProvider implements Mut
|
||||||
/**
|
/**
|
||||||
* Constructs a new provider for a specific address space.
|
* Constructs a new provider for a specific address space.
|
||||||
* @param memory the memory
|
* @param memory the memory
|
||||||
|
* @param space the address space
|
||||||
*/
|
*/
|
||||||
public MemoryMutableByteProvider(Memory memory, AddressSpace space) {
|
public MemoryMutableByteProvider(Memory memory, AddressSpace space) {
|
||||||
super(memory, space);
|
super(memory, space);
|
||||||
|
|
|
@ -107,6 +107,7 @@ public interface StructConverter {
|
||||||
* the implementor of this interface
|
* the implementor of this interface
|
||||||
*
|
*
|
||||||
* @throws DuplicateNameException when a datatype of the same name already exists
|
* @throws DuplicateNameException when a datatype of the same name already exists
|
||||||
|
* @throws IOException if an IO-related error occurs
|
||||||
*
|
*
|
||||||
* @see ghidra.program.model.data.StructureDataType
|
* @see ghidra.program.model.data.StructureDataType
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.app.util.bin.format.pe;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
@ -27,7 +28,7 @@ import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class ArchitectureDataDirectory extends DataDirectory {
|
public class ArchitectureDataDirectory extends DataDirectory implements StructConverter {
|
||||||
private final static String NAME = "IMAGE_DIRECTORY_ENTRY_ARCHITECTURE";
|
private final static String NAME = "IMAGE_DIRECTORY_ENTRY_ARCHITECTURE";
|
||||||
|
|
||||||
private String copyright;
|
private String copyright;
|
||||||
|
@ -43,9 +44,9 @@ public class ArchitectureDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException {
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException {
|
||||||
monitor.setMessage(program.getName()+": architecture...");
|
monitor.setMessage(program.getName()+": architecture...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -75,9 +76,6 @@ public class ArchitectureDataDirectory extends DataDirectory {
|
||||||
return copyright;
|
return copyright;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
StructureDataType struct = new StructureDataType(NAME, 0);
|
||||||
|
|
|
@ -159,9 +159,7 @@ public class BaseRelocation implements StructConverter, ByteArrayConverter {
|
||||||
return typeOffsetList.get(index).type;
|
return typeOffsetList.get(index).type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
StructureDataType struct = new StructureDataType(NAME, 0);
|
||||||
|
|
||||||
|
@ -174,9 +172,7 @@ public class BaseRelocation implements StructConverter, ByteArrayConverter {
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte[] toBytes(DataConverter dc) {
|
public byte[] toBytes(DataConverter dc) {
|
||||||
byte [] bytes = new byte[sizeOfBlock];
|
byte [] bytes = new byte[sizeOfBlock];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
|
@ -23,11 +23,11 @@ import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.ByteArrayConverter;
|
import ghidra.app.util.bin.ByteArrayConverter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.DWordDataType;
|
||||||
|
import ghidra.program.model.data.WordDataType;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,10 +51,10 @@ public class BaseRelocationDataDirectory extends DataDirectory implements ByteAr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws CodeUnitInsertionException {
|
NTHeader nt) throws CodeUnitInsertionException {
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": base relocation(s)...");
|
monitor.setMessage(program.getName()+": base relocation(s)...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,19 +65,19 @@ public class BaseRelocationDataDirectory extends DataDirectory implements ByteAr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeUtils.createData(program, addr, DWORD, log);
|
PeUtils.createData(program, addr, DWordDataType.dataType, log);
|
||||||
addr = addr.add(DWORD.getLength());
|
addr = addr.add(DWordDataType.dataType.getLength());
|
||||||
|
|
||||||
PeUtils.createData(program, addr, DWORD, log);
|
PeUtils.createData(program, addr, DWordDataType.dataType, log);
|
||||||
addr = addr.add(DWORD.getLength());
|
addr = addr.add(DWordDataType.dataType.getLength());
|
||||||
|
|
||||||
int count = reloc.getCount();
|
int count = reloc.getCount();
|
||||||
for (int j = 0 ; j < count ; ++j) {
|
for (int j = 0 ; j < count ; ++j) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PeUtils.createData(program, addr, WORD, log);
|
PeUtils.createData(program, addr, WordDataType.dataType, log);
|
||||||
addr = addr.add(WORD.getLength());
|
addr = addr.add(WordDataType.dataType.getLength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,19 +122,6 @@ public class BaseRelocationDataDirectory extends DataDirectory implements ByteAr
|
||||||
return relocs;
|
return relocs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
for (BaseRelocation reloc : relocs) {
|
|
||||||
struct.add(reloc.toDataType());
|
|
||||||
}
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all base relocations from this base relocation
|
* Removes all base relocations from this base relocation
|
||||||
* directory.
|
* directory.
|
||||||
|
@ -167,9 +154,7 @@ public class BaseRelocationDataDirectory extends DataDirectory implements ByteAr
|
||||||
relocs = tmp;
|
relocs = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte[] toBytes(DataConverter dc) {
|
public byte[] toBytes(DataConverter dc) {
|
||||||
int lsize = 0;
|
int lsize = 0;
|
||||||
for (BaseRelocation reloc : relocs) {
|
for (BaseRelocation reloc : relocs) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
|
@ -46,19 +46,6 @@ public class BoundImportDataDirectory extends DataDirectory {
|
||||||
if (descriptors == null) descriptors = new BoundImportDescriptor[0];
|
if (descriptors == null) descriptors = new BoundImportDescriptor[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
for (BoundImportDescriptor descriptor : descriptors) {
|
|
||||||
struct.add(descriptor.toDataType());
|
|
||||||
}
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the array of bound import descriptors defined in this bound import data directory.
|
* Returns the array of bound import descriptors defined in this bound import data directory.
|
||||||
* @return the array of bound import descriptors defined in this bound import data directory
|
* @return the array of bound import descriptors defined in this bound import data directory
|
||||||
|
@ -69,10 +56,10 @@ public class BoundImportDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException {
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException {
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": bound import(s)...");
|
monitor.setMessage(program.getName()+": bound import(s)...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.bin.*;
|
import ghidra.app.util.bin.*;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.util.*;
|
import ghidra.util.DataConverter;
|
||||||
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,22 +141,26 @@ public class BoundImportDescriptor implements StructConverter, ByteArrayConverte
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append("TimeStamp:"+Integer.toHexString(timeDateStamp)+",");
|
buffer.append("TimeStamp:"+Integer.toHexString(timeDateStamp)+",");
|
||||||
buffer.append("OffsetModuleName:"+Integer.toHexString(Conv.shortToInt(offsetModuleName))+"["+moduleName+"]"+",");
|
buffer.append(
|
||||||
buffer.append("NumberOfModuleForwarderRefs:"+Integer.toHexString(Conv.shortToInt(numberOfModuleForwarderRefs)));
|
"OffsetModuleName:" + Integer.toHexString(Short.toUnsignedInt(offsetModuleName)) + "[" +
|
||||||
|
moduleName + "]" + ",");
|
||||||
|
buffer.append("NumberOfModuleForwarderRefs:" +
|
||||||
|
Integer.toHexString(Short.toUnsignedInt(numberOfModuleForwarderRefs)));
|
||||||
buffer.append("\n");
|
buffer.append("\n");
|
||||||
for(int i=0;i<forwarders.size();i++) {
|
for(int i=0;i<forwarders.size();i++) {
|
||||||
BoundImportForwarderRef ref = forwarders.get(i);
|
BoundImportForwarderRef ref = forwarders.get(i);
|
||||||
buffer.append("\t"+"TimeStamp:"+Integer.toHexString(ref.getTimeDateStamp())+",");
|
buffer.append("\t"+"TimeStamp:"+Integer.toHexString(ref.getTimeDateStamp())+",");
|
||||||
buffer.append("\t"+"OffsetModuleName:"+Integer.toHexString(Conv.shortToInt(ref.getOffsetModuleName()))+"["+ref.getModuleName()+"]"+",");
|
buffer.append("\t" + "OffsetModuleName:" +
|
||||||
buffer.append("\t"+"Reserved:"+Integer.toHexString(Conv.shortToInt(ref.getReserved())));
|
Integer.toHexString(Short.toUnsignedInt(ref.getOffsetModuleName())) + "[" +
|
||||||
|
ref.getModuleName() + "]" + ",");
|
||||||
|
buffer.append(
|
||||||
|
"\t" + "Reserved:" + Integer.toHexString(Short.toUnsignedInt(ref.getReserved())));
|
||||||
buffer.append("\n");
|
buffer.append("\n");
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(NAME+"_"+forwarders.size(), 0);
|
StructureDataType struct = new StructureDataType(NAME+"_"+forwarders.size(), 0);
|
||||||
|
|
||||||
|
@ -173,9 +178,7 @@ public class BoundImportDescriptor implements StructConverter, ByteArrayConverte
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte [] toBytes(DataConverter dc) {
|
public byte [] toBytes(DataConverter dc) {
|
||||||
byte [] bytes = new byte[IMAGE_SIZEOF_BOUND_IMPORT_DESCRIPTOR +
|
byte [] bytes = new byte[IMAGE_SIZEOF_BOUND_IMPORT_DESCRIPTOR +
|
||||||
(numberOfModuleForwarderRefs*BoundImportForwarderRef.IMAGE_SIZEOF_BOUND_IMPORT_FORWARDER_REF)];
|
(numberOfModuleForwarderRefs*BoundImportForwarderRef.IMAGE_SIZEOF_BOUND_IMPORT_FORWARDER_REF)];
|
||||||
|
|
|
@ -56,6 +56,7 @@ public class BoundImportForwarderRef implements StructConverter, ByteArrayConver
|
||||||
* @param reader the binary reader
|
* @param reader the binary reader
|
||||||
* @param readerIndex the index into the binary reader
|
* @param readerIndex the index into the binary reader
|
||||||
* @param biddIndex the index where the bound import data directory begins
|
* @param biddIndex the index where the bound import data directory begins
|
||||||
|
* @throws IOException if there was an IO-related error
|
||||||
*/
|
*/
|
||||||
BoundImportForwarderRef(BinaryReader reader, int readerIndex, int biddIndex)
|
BoundImportForwarderRef(BinaryReader reader, int readerIndex, int biddIndex)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -70,9 +71,7 @@ public class BoundImportForwarderRef implements StructConverter, ByteArrayConver
|
||||||
moduleName = reader.readAsciiString(biddIndex + offsetModuleName);
|
moduleName = reader.readAsciiString(biddIndex + offsetModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte [] toBytes(DataConverter dc) {
|
public byte [] toBytes(DataConverter dc) {
|
||||||
byte [] bytes = new byte[IMAGE_SIZEOF_BOUND_IMPORT_FORWARDER_REF];
|
byte [] bytes = new byte[IMAGE_SIZEOF_BOUND_IMPORT_FORWARDER_REF];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
@ -122,9 +121,7 @@ public class BoundImportForwarderRef implements StructConverter, ByteArrayConver
|
||||||
return moduleName;
|
return moduleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
StructureDataType struct = new StructureDataType(NAME, 0);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
|
@ -67,11 +67,11 @@ public class COMDescriptorDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException,
|
||||||
IOException, MemoryAccessException {
|
IOException, MemoryAccessException {
|
||||||
|
|
||||||
monitor.setMessage("[" + program.getName() + "]: com descriptor(s)...");
|
monitor.setMessage("[" + program.getName() + "]: com descriptor(s)...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -80,18 +80,7 @@ public class COMDescriptorDataDirectory extends DataDirectory {
|
||||||
PeUtils.createData(program, addr, dt, log);
|
PeUtils.createData(program, addr, dt, log);
|
||||||
|
|
||||||
if (hasParsed) {
|
if (hasParsed) {
|
||||||
header.markup(program, isBinary, monitor, log, ntHeader);
|
header.markup(program, isBinary, monitor, log, nt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
struct.add(new ArrayDataType(BYTE, size, 1), "COM", null);
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,12 @@ import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.StructConverter;
|
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.DataType;
|
|
||||||
import ghidra.program.model.data.TerminatedStringDataType;
|
import ghidra.program.model.data.TerminatedStringDataType;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract base class to represent the
|
* An abstract base class to represent the
|
||||||
|
@ -42,7 +39,7 @@ import ghidra.util.exception.DuplicateNameException;
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
public abstract class DataDirectory implements PeMarkupable {
|
||||||
/**
|
/**
|
||||||
* The name to use when converting into a structure data type.
|
* The name to use when converting into a structure data type.
|
||||||
*/
|
*/
|
||||||
|
@ -59,27 +56,37 @@ public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
||||||
protected int size;
|
protected int size;
|
||||||
protected boolean hasParsed = false;
|
protected boolean hasParsed = false;
|
||||||
|
|
||||||
protected void processDataDirectory(NTHeader ntHeader, BinaryReader reader)
|
protected void processDataDirectory(NTHeader nt, BinaryReader rdr) throws IOException {
|
||||||
throws IOException {
|
this.ntHeader = nt;
|
||||||
this.ntHeader = ntHeader;
|
this.reader = rdr;
|
||||||
this.reader = reader;
|
|
||||||
|
|
||||||
virtualAddress = reader.readNextInt();
|
virtualAddress = rdr.readNextInt();
|
||||||
size = reader.readNextInt();
|
size = rdr.readNextInt();
|
||||||
|
|
||||||
if (size < 0 || !ntHeader.checkRVA(virtualAddress)) {
|
if (virtualAddress == 0) {
|
||||||
if (size != 0) {
|
|
||||||
Msg.warn(this,
|
|
||||||
"DataDirectory RVA outside of image (RVA: 0x" +
|
|
||||||
Integer.toHexString(virtualAddress) + ", Size: 0x" +
|
|
||||||
Integer.toHexString(size) + "). Could be a file-only data directory.");
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nt.checkRVA(virtualAddress)) {
|
||||||
|
Msg.warn(this,
|
||||||
|
"Skipping DataDirectory '%s'. RVA outside of image (RVA: 0x%x, Size: 0x%x). Could be a file-only data directory."
|
||||||
|
.formatted(getDirectoryName(), virtualAddress, size));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size < 0 && validateSize()) {
|
||||||
|
Msg.warn(this, "Skipping DataDirectory '%s'. Invalid size (Size: 0x%x)."
|
||||||
|
.formatted(getDirectoryName(), size));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hasParsed = parse();
|
hasParsed = parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean validateSize() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String getDirectoryName();
|
public abstract String getDirectoryName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,9 +141,15 @@ public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a fragment with the given name (if it does not already exist).
|
* Creates a fragment with the given name (if it does not already exist) and moves the address
|
||||||
* Move the address range into the fragment.
|
* range into the fragment.
|
||||||
|
* <p>
|
||||||
* Note: the end address is not inclusive!
|
* Note: the end address is not inclusive!
|
||||||
|
* @param program The program
|
||||||
|
* @param fragmentName The fragment name
|
||||||
|
* @param start The start address
|
||||||
|
* @param end The end address
|
||||||
|
* @return True on success; otherwise, false
|
||||||
*/
|
*/
|
||||||
protected boolean createFragment(Program program, String fragmentName, Address start,
|
protected boolean createFragment(Program program, String fragmentName, Address start,
|
||||||
Address end) {
|
Address end) {
|
||||||
|
@ -150,9 +163,9 @@ public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ProgramFragment findFragment(ProgramModule module, String fragmentName) {
|
private ProgramFragment findFragment(ProgramModule module, String fragmentName) {
|
||||||
Group[] groups = module.getChildren();
|
Group[] groups = module.getChildren();
|
||||||
|
@ -224,13 +237,6 @@ public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
||||||
return rvaToPointer() != getVirtualAddress();
|
return rvaToPointer() != getVirtualAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should return a datatype representing the data stored
|
|
||||||
* in this directory.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public abstract DataType toDataType() throws DuplicateNameException, IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directories that are not contained inside of sections
|
* Directories that are not contained inside of sections
|
||||||
* should override this method to write their bytes into the
|
* should override this method to write their bytes into the
|
||||||
|
@ -242,6 +248,7 @@ public abstract class DataDirectory implements StructConverter, PeMarkupable {
|
||||||
*/
|
*/
|
||||||
public void writeBytes(RandomAccessFile raf, DataConverter dc, PortableExecutable template)
|
public void writeBytes(RandomAccessFile raf, DataConverter dc, PortableExecutable template)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasParsedCorrectly() {
|
public boolean hasParsedCorrectly() {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import ghidra.app.util.bin.format.pe.debug.*;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
import ghidra.program.model.data.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
|
@ -64,11 +63,11 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt)
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": debug...");
|
monitor.setMessage(program.getName()+": debug...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +80,7 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
PeUtils.createData(program, addr, dd.toDataType(), log);
|
PeUtils.createData(program, addr, dd.toDataType(), log);
|
||||||
addr = addr.add(DebugDirectory.IMAGE_SIZEOF_DEBUG_DIRECTORY);
|
addr = addr.add(DebugDirectory.IMAGE_SIZEOF_DEBUG_DIRECTORY);
|
||||||
|
|
||||||
Address dataAddr = getDataAddress(dd, isBinary, space, ntHeader);
|
Address dataAddr = getDataAddress(dd, isBinary, space, nt);
|
||||||
if (dataAddr != null) {
|
if (dataAddr != null) {
|
||||||
boolean success = createFragment(program, "Debug Data", dataAddr, dataAddr.add(dd.getSizeOfData()));
|
boolean success = createFragment(program, "Debug Data", dataAddr, dataAddr.add(dd.getSizeOfData()));
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -94,8 +93,8 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
markupDebugCodeView(program, isBinary, log, space);
|
markupDebugCodeView(program, isBinary, log, space);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupDebugCodeView(Program program, boolean isBinary,
|
private void markupDebugCodeView(Program program, boolean isBinary, MessageLog log,
|
||||||
MessageLog log, AddressSpace space) throws DuplicateNameException, IOException {
|
AddressSpace space) {
|
||||||
DebugCodeView dcv = parser.getDebugCodeView();
|
DebugCodeView dcv = parser.getDebugCodeView();
|
||||||
if (dcv != null) {
|
if (dcv != null) {
|
||||||
Address dataAddr = getDataAddress(dcv.getDebugDirectory(), isBinary, space, ntHeader);
|
Address dataAddr = getDataAddress(dcv.getDebugDirectory(), isBinary, space, ntHeader);
|
||||||
|
@ -126,13 +125,13 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Address getDataAddress(DebugDirectory dd, boolean isBinary,
|
private Address getDataAddress(DebugDirectory dd, boolean isBinary, AddressSpace space,
|
||||||
AddressSpace space, NTHeader ntHeader) {
|
NTHeader nt) {
|
||||||
|
|
||||||
long ptr = 0;
|
long ptr = 0;
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
ptr = dd.getPointerToRawData();
|
ptr = dd.getPointerToRawData();
|
||||||
if (ptr != 0 && !ntHeader.checkPointer(ptr)) {
|
if (ptr != 0 && !nt.checkPointer(ptr)) {
|
||||||
Msg.error(this, "Invalid pointer "+Long.toHexString(ptr));
|
Msg.error(this, "Invalid pointer "+Long.toHexString(ptr));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +143,7 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
return space.getAddress(ptr);
|
return space.getAddress(ptr);
|
||||||
}
|
}
|
||||||
return space.getAddress(ptr + ntHeader.getOptionalHeader().getImageBase());
|
return space.getAddress(ptr + nt.getOptionalHeader().getImageBase());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -157,20 +156,6 @@ public class DebugDataDirectory extends DataDirectory {
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
DebugDirectory [] ddArr = parser.getDebugDirectories();
|
|
||||||
for (DebugDirectory sc : ddArr) {
|
|
||||||
struct.add(sc.toDataType(),sc.getDescription(),null );
|
|
||||||
}
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ghidra.app.util.bin.format.pe.DataDirectory#writeBytes(java.io.RandomAccessFile, ghidra.util.DataConverter, ghidra.app.util.bin.format.pe.PortableExecutable)
|
* @see ghidra.app.util.bin.format.pe.DataDirectory#writeBytes(java.io.RandomAccessFile, ghidra.util.DataConverter, ghidra.app.util.bin.format.pe.PortableExecutable)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,13 +18,14 @@ package ghidra.app.util.bin.format.pe;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class DefaultDataDirectory extends DataDirectory {
|
public class DefaultDataDirectory extends DataDirectory implements StructConverter {
|
||||||
|
|
||||||
DefaultDataDirectory(NTHeader ntHeader, BinaryReader reader) throws IOException {
|
DefaultDataDirectory(NTHeader ntHeader, BinaryReader reader) throws IOException {
|
||||||
processDataDirectory(ntHeader, reader);
|
processDataDirectory(ntHeader, reader);
|
||||||
|
@ -43,7 +44,7 @@ public class DefaultDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) {
|
NTHeader nt) {
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,11 +86,11 @@ public class DelayImportDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt)
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": delay import(s)...");
|
monitor.setMessage(program.getName()+": delay import(s)...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,9 @@ public class DelayImportDataDirectory extends DataDirectory {
|
||||||
try {
|
try {
|
||||||
program.getSymbolTable().createLabel(addr, name, SourceType.IMPORTED);
|
program.getSymbolTable().createLabel(addr, name, SourceType.IMPORTED);
|
||||||
}
|
}
|
||||||
catch (Exception e) {}
|
catch (Exception e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Address addr(AddressSpace space, boolean isBinary,
|
private Address addr(AddressSpace space, boolean isBinary,
|
||||||
|
@ -228,13 +230,13 @@ public class DelayImportDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
DataType dt;
|
DataType dt;
|
||||||
if (thunk.isOrdinal() || thunk.getAddressOfData() == 0) {
|
if (thunk.isOrdinal() || thunk.getAddressOfData() == 0) {
|
||||||
dt = is64bit ? QWORD : DWORD;
|
dt = is64bit ? QWordDataType.dataType : DWordDataType.dataType;
|
||||||
}
|
}
|
||||||
else if (isIAT) {
|
else if (isIAT) {
|
||||||
dt = is64bit ? Pointer64DataType.dataType : Pointer32DataType.dataType;
|
dt = is64bit ? Pointer64DataType.dataType : Pointer32DataType.dataType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dt = is64bit ? IBO64 : IBO32;
|
dt = is64bit ? IBO64DataType.dataType : IBO32DataType.dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
Address thunkAddress = space.getAddress(thunkPtr);
|
Address thunkAddress = space.getAddress(thunkPtr);
|
||||||
|
@ -243,17 +245,4 @@ public class DelayImportDataDirectory extends DataDirectory {
|
||||||
thunkPtr += thunk.getStructSize();
|
thunkPtr += thunk.getStructSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
for (DelayImportDescriptor descriptor : descriptors) {
|
|
||||||
struct.add(descriptor.toDataType(), DelayImportDescriptor.NAME, null);
|
|
||||||
}
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.StructConverter;
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.symbol.SymbolUtilities;
|
import ghidra.program.model.symbol.SymbolUtilities;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
@ -176,17 +175,17 @@ public class DelayImportDescriptor implements StructConverter {
|
||||||
private void readFields(BinaryReader reader, int index) throws IOException {
|
private void readFields(BinaryReader reader, int index) throws IOException {
|
||||||
grAttrs = reader.readInt(index);
|
grAttrs = reader.readInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
szName = reader.readInt(index) & Conv.INT_MASK;
|
szName = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
phmod = reader.readInt(index) & Conv.INT_MASK;
|
phmod = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
pIAT = reader.readInt(index) & Conv.INT_MASK;
|
pIAT = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
pINT = reader.readInt(index) & Conv.INT_MASK;
|
pINT = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
pBoundIAT = reader.readInt(index) & Conv.INT_MASK;
|
pBoundIAT = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
pUnloadIAT = reader.readInt(index) & Conv.INT_MASK;
|
pUnloadIAT = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
dwTimeStamp = reader.readInt(index);
|
dwTimeStamp = reader.readInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
@ -84,10 +83,10 @@ public class ExceptionDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt)
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
|
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,11 +95,4 @@ public class ExceptionDataDirectory extends DataDirectory {
|
||||||
functionEntries.markup(program, addr);
|
functionEntries.markup(program, addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, size);
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
|
@ -28,7 +29,6 @@ import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -52,7 +52,7 @@ import ghidra.util.task.TaskMonitor;
|
||||||
* };
|
* };
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class ExportDataDirectory extends DataDirectory {
|
public class ExportDataDirectory extends DataDirectory implements StructConverter {
|
||||||
private final static String NAME = "IMAGE_DIRECTORY_ENTRY_EXPORT";
|
private final static String NAME = "IMAGE_DIRECTORY_ENTRY_EXPORT";
|
||||||
/**
|
/**
|
||||||
* The size of the <code>IMAGE_EXPORT_DIRECTORY</code> in bytes.
|
* The size of the <code>IMAGE_EXPORT_DIRECTORY</code> in bytes.
|
||||||
|
@ -144,12 +144,12 @@ public class ExportDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt)
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
|
|
||||||
monitor.setMessage("[" + program.getName() + "]: exports...");
|
monitor.setMessage("[" + program.getName() + "]: exports...");
|
||||||
|
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -303,8 +303,8 @@ public class ExportDataDirectory extends DataDirectory {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
long addr =
|
long addr = Integer.toUnsignedLong(entryPointRVA) +
|
||||||
Conv.intToLong(entryPointRVA) + ntHeader.getOptionalHeader().getImageBase();
|
ntHeader.getOptionalHeader().getImageBase();
|
||||||
|
|
||||||
if (!ntHeader.getOptionalHeader().is64bit()) {
|
if (!ntHeader.getOptionalHeader().is64bit()) {
|
||||||
addr &= 0xffffffffL;
|
addr &= 0xffffffffL;
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
@ -41,10 +40,9 @@ public class GlobalPointerDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
|
||||||
monitor.setMessage(program.getName()+": global pointers...");
|
monitor.setMessage(program.getName()+": global pointers...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -59,15 +57,4 @@ public class GlobalPointerDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
struct.add(new ArrayDataType(BYTE,size,1), "GLOBAL_PTR", null);
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,10 @@ import java.util.List;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class ImportAddressTableDataDirectory extends DataDirectory {
|
public class ImportAddressTableDataDirectory extends DataDirectory {
|
||||||
|
@ -56,10 +54,10 @@ public class ImportAddressTableDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws CodeUnitInsertionException, MemoryAccessException {
|
NTHeader nt) throws CodeUnitInsertionException, MemoryAccessException {
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": IAT...");
|
monitor.setMessage(program.getName()+": IAT...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -101,15 +99,4 @@ public class ImportAddressTableDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
struct.add(new ArrayDataType(BYTE, size, 1), "IAT", null);
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,7 @@ public class ImportByName implements StructConverter, ByteArrayConverter {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
int len = name.length()+1;
|
int len = name.length()+1;
|
||||||
StructureDataType struct = new StructureDataType(NAME+"_"+len, 0);
|
StructureDataType struct = new StructureDataType(NAME+"_"+len, 0);
|
||||||
|
@ -82,9 +80,7 @@ public class ImportByName implements StructConverter, ByteArrayConverter {
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte [] toBytes(DataConverter dc) {
|
public byte [] toBytes(DataConverter dc) {
|
||||||
byte [] bytes = new byte[getSizeOf()];
|
byte [] bytes = new byte[getSizeOf()];
|
||||||
dc.getBytes(hint, bytes, 0);
|
dc.getBytes(hint, bytes, 0);
|
||||||
|
|
|
@ -74,9 +74,15 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean validateSize() {
|
||||||
|
// The Windows loader is known to not check the size of this DataDirectory
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt)
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException,
|
throws DuplicateNameException, CodeUnitInsertionException, IOException,
|
||||||
MemoryAccessException {
|
MemoryAccessException {
|
||||||
|
|
||||||
|
@ -84,7 +90,7 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
monitor.setMessage("[" + program.getName() + "]: import(s)...");
|
monitor.setMessage("[" + program.getName() + "]: import(s)...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -100,8 +106,8 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
setPlateComment(program, addr, ImportDescriptor.NAME);
|
setPlateComment(program, addr, ImportDescriptor.NAME);
|
||||||
for (int j = 0; j < 5; ++j) {
|
for (int j = 0; j < 5; ++j) {
|
||||||
PeUtils.createData(program, addr, DWORD, log);
|
PeUtils.createData(program, addr, DWordDataType.dataType, log);
|
||||||
addr = addr.add(DWORD.getLength());
|
addr = addr.add(DWordDataType.dataType.getLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor.getName() == 0 && descriptor.getTimeDateStamp() == 0) {
|
if (descriptor.getName() == 0 && descriptor.getTimeDateStamp() == 0) {
|
||||||
|
@ -112,7 +118,7 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
if (dll != null && dll.startsWith(program.getName())) {
|
if (dll != null && dll.startsWith(program.getName())) {
|
||||||
Msg.warn(this,
|
Msg.warn(this,
|
||||||
program.getName() + " potentially modified via import of local exports");
|
program.getName() + " potentially modified via import of local exports");
|
||||||
DataDirectory[] dataDirectories = ntHeader.getOptionalHeader().getDataDirectories();
|
DataDirectory[] dataDirectories = nt.getOptionalHeader().getDataDirectories();
|
||||||
exportDirectory =
|
exportDirectory =
|
||||||
(ExportDataDirectory) dataDirectories[OptionalHeader.IMAGE_DIRECTORY_ENTRY_EXPORT];
|
(ExportDataDirectory) dataDirectories[OptionalHeader.IMAGE_DIRECTORY_ENTRY_EXPORT];
|
||||||
}
|
}
|
||||||
|
@ -150,7 +156,7 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
ExportInfo exportInfo = exportDirectory.getExports()[j];
|
ExportInfo exportInfo = exportDirectory.getExports()[j];
|
||||||
long address = exportInfo.getAddress();
|
long address = exportInfo.getAddress();
|
||||||
long thunkAddr = va(intptr, isBinary);
|
long thunkAddr = va(intptr, isBinary);
|
||||||
byte[] bytes = ntHeader.getOptionalHeader().is64bit() ? conv.getBytes(address)
|
byte[] bytes = nt.getOptionalHeader().is64bit() ? conv.getBytes(address)
|
||||||
: conv.getBytes((int) address);
|
: conv.getBytes((int) address);
|
||||||
try {
|
try {
|
||||||
program.getMemory().setBytes(
|
program.getMemory().setBytes(
|
||||||
|
@ -169,8 +175,8 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
long ibnAddr = va(thunks[j].getAddressOfData(), isBinary);
|
long ibnAddr = va(thunks[j].getAddressOfData(), isBinary);
|
||||||
Address ibnAddress = space.getAddress(ibnAddr);
|
Address ibnAddress = space.getAddress(ibnAddr);
|
||||||
setPlateComment(program, ibnAddress, ImportByName.NAME);
|
setPlateComment(program, ibnAddress, ImportByName.NAME);
|
||||||
PeUtils.createData(program, ibnAddress, WORD, log);
|
PeUtils.createData(program, ibnAddress, WordDataType.dataType, log);
|
||||||
Address ibnNameAddress = ibnAddress.add(WORD.getLength());
|
Address ibnNameAddress = ibnAddress.add(WordDataType.dataType.getLength());
|
||||||
PeUtils.createData(program, ibnNameAddress, tsdt, log);
|
PeUtils.createData(program, ibnNameAddress, tsdt, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +188,8 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
throws MemoryAccessException {
|
throws MemoryAccessException {
|
||||||
DataType dt = null;
|
DataType dt = null;
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
dt = ntHeader.getOptionalHeader().is64bit() ? (DataType) QWORD : (DataType) DWORD;
|
dt = ntHeader.getOptionalHeader().is64bit() ? (DataType) QWordDataType.dataType
|
||||||
|
: (DataType) DWordDataType.dataType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dt = new PointerDataType(null, -1, program.getDataTypeManager());
|
dt = new PointerDataType(null, -1, program.getDataTypeManager());
|
||||||
|
@ -208,7 +215,8 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
dt = new PointerDataType(null, -1, program.getDataTypeManager());
|
dt = new PointerDataType(null, -1, program.getDataTypeManager());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dt = ntHeader.getOptionalHeader().is64bit() ? (DataType) QWORD : (DataType) DWORD;
|
dt = ntHeader.getOptionalHeader().is64bit() ? (DataType) QWordDataType.dataType
|
||||||
|
: (DataType) DWordDataType.dataType;
|
||||||
}
|
}
|
||||||
PeUtils.createData(program, thunkAddress, dt, log);
|
PeUtils.createData(program, thunkAddress, dt, log);
|
||||||
}
|
}
|
||||||
|
@ -368,16 +376,4 @@ public class ImportDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
return buff.toString();
|
return buff.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
DataType array = new ArrayDataType(BYTE, size, 1);
|
|
||||||
struct.add(array, array.getLength(), "IMPORT", null);
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,7 @@ public class ImportDescriptor implements StructConverter, ByteArrayConverter {
|
||||||
return timeDateStamp != NOT_BOUND;
|
return timeDateStamp != NOT_BOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
UnionDataType union = new UnionDataType("union");
|
UnionDataType union = new UnionDataType("union");
|
||||||
union.add(DWORD, "Characteristics", null);
|
union.add(DWORD, "Characteristics", null);
|
||||||
|
@ -230,9 +228,7 @@ public class ImportDescriptor implements StructConverter, ByteArrayConverter {
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte [] toBytes(DataConverter dc) {
|
public byte [] toBytes(DataConverter dc) {
|
||||||
byte [] bytes = new byte[SIZEOF];
|
byte [] bytes = new byte[SIZEOF];
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -25,4 +24,5 @@ package ghidra.app.util.bin.format.pe;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvalidNTHeaderException extends Exception {
|
public class InvalidNTHeaderException extends Exception {
|
||||||
|
// No special implementation
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,12 +50,11 @@ public class LoadConfigDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
|
||||||
|
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": load config directory...");
|
monitor.setMessage(program.getName()+": load config directory...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -63,14 +62,14 @@ public class LoadConfigDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
PeUtils.createData(program, addr, lcd.toDataType(), log);
|
PeUtils.createData(program, addr, lcd.toDataType(), log);
|
||||||
|
|
||||||
markupSeHandler(program, isBinary, monitor, log, ntHeader);
|
markupSeHandler(program, isBinary, monitor, log, nt);
|
||||||
ControlFlowGuard.markup(lcd, program, log, ntHeader);
|
ControlFlowGuard.markup(lcd, program, log, nt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupSeHandler(Program program, boolean isBinary, TaskMonitor monitor,
|
private void markupSeHandler(Program program, boolean isBinary, TaskMonitor monitor,
|
||||||
MessageLog log, NTHeader ntHeader) {
|
MessageLog log, NTHeader nt) {
|
||||||
long exceptionCount = lcd.getSeHandlerCount();
|
long exceptionCount = lcd.getSeHandlerCount();
|
||||||
long exceptionTable = lcd.getSeHandlerTable() - ntHeader.getOptionalHeader().getImageBase();
|
long exceptionTable = lcd.getSeHandlerTable() - nt.getOptionalHeader().getImageBase();
|
||||||
if (exceptionCount > NTHeader.MAX_SANE_COUNT) {
|
if (exceptionCount > NTHeader.MAX_SANE_COUNT) {
|
||||||
// a heuristic but...
|
// a heuristic but...
|
||||||
return;
|
return;
|
||||||
|
@ -85,8 +84,8 @@ public class LoadConfigDataDirectory extends DataDirectory {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DataType dt = ntHeader.getOptionalHeader().is64bit() ? IBO64DataType.dataType
|
DataType dt =
|
||||||
: IBO32DataType.dataType;
|
nt.getOptionalHeader().is64bit() ? IBO64DataType.dataType : IBO32DataType.dataType;
|
||||||
|
|
||||||
PeUtils.createData(program, addr, dt, log);
|
PeUtils.createData(program, addr, dt, log);
|
||||||
|
|
||||||
|
@ -104,14 +103,6 @@ public class LoadConfigDataDirectory extends DataDirectory {
|
||||||
lcd = new LoadConfigDirectory(reader, ptr, ntHeader.getOptionalHeader());
|
lcd = new LoadConfigDirectory(reader, ptr, ntHeader.getOptionalHeader());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
return lcd.toDataType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,13 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.StructConverter;
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to represent the <code>IMAGE_LOAD_CONFIG_DIRECTORY</code>
|
* A class to represent the <code>IMAGE_LOAD_CONFIG_DIRECTORY</code>
|
||||||
* data structure which is defined in <b><code>winnt.h</code></b>.
|
* data structure which is defined in <b><code>winnt.h</code></b>.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class LoadConfigDirectory implements StructConverter {
|
public class LoadConfigDirectory implements StructConverter {
|
||||||
public final static String NAME32 = "IMAGE_LOAD_CONFIG_DIRECTORY32";
|
public final static String NAME32 = "IMAGE_LOAD_CONFIG_DIRECTORY32";
|
||||||
public final static String NAME64 = "IMAGE_LOAD_CONFIG_DIRECTORY64";
|
public final static String NAME64 = "IMAGE_LOAD_CONFIG_DIRECTORY64";
|
||||||
|
@ -370,7 +370,7 @@ public class LoadConfigDirectory implements StructConverter {
|
||||||
if (is64bit) {
|
if (is64bit) {
|
||||||
return reader.readNextLong();
|
return reader.readNextLong();
|
||||||
}
|
}
|
||||||
return reader.readNextInt() & Conv.INT_MASK;
|
return reader.readNextUnsignedInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -437,8 +437,8 @@ public class LoadConfigDirectory implements StructConverter {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("flags=0x" + Integer.toHexString(Conv.shortToInt(flags)));
|
sb.append("flags=0x" + Integer.toHexString(Short.toUnsignedInt(flags)));
|
||||||
sb.append(", catalog=0x" + Integer.toHexString(Conv.shortToInt(catalog)));
|
sb.append(", catalog=0x" + Integer.toHexString(Short.toUnsignedInt(catalog)));
|
||||||
sb.append(", catalogOffset=0x" + Integer.toHexString(catalogOffset));
|
sb.append(", catalogOffset=0x" + Integer.toHexString(catalogOffset));
|
||||||
sb.append(", reserved=0x" + Integer.toHexString(reserved));
|
sb.append(", reserved=0x" + Integer.toHexString(reserved));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,15 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.bin.format.pe;
|
package ghidra.app.util.bin.format.pe;
|
||||||
|
|
||||||
import ghidra.util.Conv;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class MachineName {
|
class MachineName {
|
||||||
|
|
||||||
static String getName(short machine) {
|
static String getName(short machine) {
|
||||||
return getName(machine & Conv.SHORT_MASK);
|
return getName(Short.toUnsignedInt(machine));
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getName(int machine) {
|
static String getName(int machine) {
|
||||||
|
|
|
@ -26,7 +26,8 @@ import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.util.*;
|
import ghidra.util.DataConverter;
|
||||||
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -166,7 +167,7 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getAddressOfEntryPoint() {
|
public long getAddressOfEntryPoint() {
|
||||||
return Conv.intToLong(addressOfEntryPoint);
|
return Integer.toUnsignedLong(addressOfEntryPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -181,7 +182,7 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSizeOfInitializedData() {
|
public long getSizeOfInitializedData() {
|
||||||
return Conv.intToLong(sizeOfInitializedData);
|
return Integer.toUnsignedLong(sizeOfInitializedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -191,7 +192,7 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSizeOfUninitializedData() {
|
public long getSizeOfUninitializedData() {
|
||||||
return Conv.intToLong(sizeOfUninitializedData);
|
return Integer.toUnsignedLong(sizeOfUninitializedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -201,17 +202,17 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBaseOfCode() {
|
public long getBaseOfCode() {
|
||||||
return Conv.intToLong(baseOfCode);
|
return Integer.toUnsignedLong(baseOfCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBaseOfData() {
|
public long getBaseOfData() {
|
||||||
return Conv.intToLong(baseOfData);
|
return Integer.toUnsignedLong(baseOfData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSizeOfImage() {
|
public long getSizeOfImage() {
|
||||||
return Conv.intToLong(sizeOfImage);
|
return Integer.toUnsignedLong(sizeOfImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,7 +222,7 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getSizeOfHeaders() {
|
public long getSizeOfHeaders() {
|
||||||
return Conv.intToLong(sizeOfHeaders);
|
return Integer.toUnsignedLong(sizeOfHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -231,7 +232,7 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNumberOfRvaAndSizes() {
|
public long getNumberOfRvaAndSizes() {
|
||||||
return Conv.intToLong(numberOfRvaAndSizes);
|
return Integer.toUnsignedLong(numberOfRvaAndSizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -531,10 +532,10 @@ public class OptionalHeaderImpl implements OptionalHeader {
|
||||||
sizeOfHeapCommit = reader.readNextLong();
|
sizeOfHeapCommit = reader.readNextLong();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sizeOfStackReserve = reader.readNextInt() & Conv.INT_MASK;
|
sizeOfStackReserve = reader.readNextUnsignedInt();
|
||||||
sizeOfStackCommit = reader.readNextInt() & Conv.INT_MASK;
|
sizeOfStackCommit = reader.readNextUnsignedInt();
|
||||||
sizeOfHeapReserve = reader.readNextInt() & Conv.INT_MASK;
|
sizeOfHeapReserve = reader.readNextUnsignedInt();
|
||||||
sizeOfHeapCommit = reader.readNextInt() & Conv.INT_MASK;
|
sizeOfHeapCommit = reader.readNextUnsignedInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
loaderFlags = reader.readNextInt();
|
loaderFlags = reader.readNextInt();
|
||||||
|
|
|
@ -187,14 +187,13 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
|
||||||
|
|
||||||
if (rootDirectory == null) {
|
if (rootDirectory == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
monitor.setMessage("[" + program.getName() + "]: resources...");
|
monitor.setMessage("[" + program.getName() + "]: resources...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -402,8 +401,7 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
Msg.error(this, "Invalid resource data: " + e.getMessage(), e);
|
Msg.error(this, "Invalid resource data: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address resourceBase =
|
Address resourceBase = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
|
||||||
markupDirectory(rootDirectory, resourceBase, resourceBase, program, isBinary, monitor, log);
|
markupDirectory(rootDirectory, resourceBase, resourceBase, program, isBinary, monitor, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,7 +548,7 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
//get first structure
|
//get first structure
|
||||||
Data componentAt = data.getComponentAt(offset);
|
Data componentAt = data.getComponentContaining(offset);
|
||||||
if (componentAt.isStructure() &&
|
if (componentAt.isStructure() &&
|
||||||
componentAt.getBaseDataType().getName().equals("DLGTEMPLATE")) {
|
componentAt.getBaseDataType().getName().equals("DLGTEMPLATE")) {
|
||||||
|
|
||||||
|
@ -567,7 +565,7 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
//get three or five components after initial structure
|
//get three or five components after initial structure
|
||||||
for (int i = 0; i < numAfter; i++) {
|
for (int i = 0; i < numAfter; i++) {
|
||||||
offset += componentAt.getLength();
|
offset += componentAt.getLength();
|
||||||
componentAt = data.getComponentAt(offset);
|
componentAt = data.getComponentContaining(offset);
|
||||||
comment.append("\n" + afterTemplate[i] + ": ");
|
comment.append("\n" + afterTemplate[i] + ": ");
|
||||||
if (componentAt.getBaseDataType().getName().equals("short")) {
|
if (componentAt.getBaseDataType().getName().equals("short")) {
|
||||||
comment.append(componentAt.getDefaultValueRepresentation());
|
comment.append(componentAt.getDefaultValueRepresentation());
|
||||||
|
@ -593,14 +591,14 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
comment.append("\n");
|
comment.append("\n");
|
||||||
while (currentItem < numItems) {
|
while (currentItem < numItems) {
|
||||||
offset += componentAt.getLength();
|
offset += componentAt.getLength();
|
||||||
componentAt = data.getComponentAt(offset);
|
componentAt = data.getComponentContaining(offset);
|
||||||
if (componentAt.getBaseDataType().getName().equals("DLGITEMTEMPLATE")) {
|
if (componentAt.getBaseDataType().getName().equals("DLGITEMTEMPLATE")) {
|
||||||
currentItem++;
|
currentItem++;
|
||||||
comment.append("\nItem " + currentItem + ": ");
|
comment.append("\nItem " + currentItem + ": ");
|
||||||
//loop over three items after each item structure
|
//loop over three items after each item structure
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
offset += componentAt.getLength();
|
offset += componentAt.getLength();
|
||||||
componentAt = data.getComponentAt(offset);
|
componentAt = data.getComponentContaining(offset);
|
||||||
comment.append("\n " + afterItem[i] + ": ");
|
comment.append("\n " + afterItem[i] + ": ");
|
||||||
if (componentAt.getBaseDataType().getName().startsWith("short[")) {
|
if (componentAt.getBaseDataType().getName().startsWith("short[")) {
|
||||||
//no other info
|
//no other info
|
||||||
|
@ -754,12 +752,4 @@ public class ResourceDataDirectory extends DataDirectory {
|
||||||
}
|
}
|
||||||
return buff.toString();
|
return buff.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
|
||||||
return rootDirectory.toDataType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import ghidra.app.util.bin.ByteArrayConverter;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.AddressSpace;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
|
@ -63,8 +63,7 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
|
||||||
|
|
||||||
if (!isBinary) {//certificates are never mapped into running program...
|
if (!isBinary) {//certificates are never mapped into running program...
|
||||||
return;
|
return;
|
||||||
|
@ -125,35 +124,16 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
|
||||||
for (SecurityCertificate certificate : certificates) {
|
|
||||||
struct.add(certificate.toDataType());
|
|
||||||
}
|
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
|
||||||
return struct;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public byte [] toBytes(DataConverter dc) {
|
public byte [] toBytes(DataConverter dc) {
|
||||||
try {
|
try {
|
||||||
return reader.readByteArray( virtualAddress, size );
|
return reader.readByteArray( virtualAddress, size );
|
||||||
}
|
}
|
||||||
catch ( IOException e) {
|
catch ( IOException e) {
|
||||||
}
|
|
||||||
return new byte[size];//TODO: need to implement!
|
return new byte[size];//TODO: need to implement!
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.format.pe.DataDirectory#writeBytes(java.io.RandomAccessFile, ghidra.util.DataConverter, ghidra.app.util.bin.format.pe.PortableExecutable)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBytes(RandomAccessFile raf, DataConverter dc, PortableExecutable template)
|
public void writeBytes(RandomAccessFile raf, DataConverter dc, PortableExecutable template)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -186,9 +166,6 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||||
virtualAddress += offset;
|
virtualAddress += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* virtualAddress is always a binary offset
|
|
||||||
*/
|
|
||||||
public Address getMarkupAddress(Program program, boolean isBinary) {
|
public Address getMarkupAddress(Program program, boolean isBinary) {
|
||||||
AddressSpace space = program.getAddressFactory().getDefaultAddressSpace();
|
AddressSpace space = program.getAddressFactory().getDefaultAddressSpace();
|
||||||
return space.getAddress( virtualAddress);
|
return space.getAddress( virtualAddress);
|
||||||
|
|
|
@ -15,15 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.util.bin.format.pe;
|
package ghidra.app.util.bin.format.pe;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.bin.format.pe.debug.DebugDirectoryParser;
|
import ghidra.app.util.bin.format.pe.debug.DebugDirectoryParser;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +70,6 @@ public class SeparateDebugHeader implements OffsetValidator {
|
||||||
private int[] reserved = new int[2];
|
private int[] reserved = new int[2];
|
||||||
|
|
||||||
private SectionHeader[] sections;
|
private SectionHeader[] sections;
|
||||||
private String[] exportedNames;
|
|
||||||
private DebugDirectoryParser parser;
|
private DebugDirectoryParser parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +123,6 @@ public class SeparateDebugHeader implements OffsetValidator {
|
||||||
}
|
}
|
||||||
exportedNameslist.add(str);
|
exportedNameslist.add(str);
|
||||||
}
|
}
|
||||||
exportedNames = exportedNameslist.toArray(String[]::new);
|
|
||||||
|
|
||||||
ptr += exportedNamesSize;
|
ptr += exportedNamesSize;
|
||||||
|
|
||||||
|
@ -256,8 +252,8 @@ public class SeparateDebugHeader implements OffsetValidator {
|
||||||
@Override
|
@Override
|
||||||
public boolean checkPointer(long ptr) {
|
public boolean checkPointer(long ptr) {
|
||||||
for (int i = 0; i < sections.length; ++i) {
|
for (int i = 0; i < sections.length; ++i) {
|
||||||
long rawSize = sections[i].getSizeOfRawData() & Conv.INT_MASK;
|
long rawSize = Integer.toUnsignedLong(sections[i].getSizeOfRawData());
|
||||||
long rawPtr = sections[i].getPointerToRawData() & Conv.INT_MASK;
|
long rawPtr = Integer.toUnsignedLong(sections[i].getPointerToRawData());
|
||||||
|
|
||||||
if (ptr >= rawPtr && ptr <= rawPtr + rawSize) { // <= allows data after the last section, which is OK
|
if (ptr >= rawPtr && ptr <= rawPtr + rawSize) { // <= allows data after the last section, which is OK
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -58,11 +58,10 @@ public class TLSDataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader)
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
||||||
throws DuplicateNameException, CodeUnitInsertionException, IOException {
|
|
||||||
|
|
||||||
monitor.setMessage(program.getName()+": TLS...");
|
monitor.setMessage(program.getName()+": TLS...");
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -115,12 +114,4 @@ public class TLSDataDirectory extends DataDirectory {
|
||||||
tls = new TLSDirectory(reader, ptr, ntHeader.getOptionalHeader().is64bit());
|
tls = new TLSDirectory(reader, ptr, ntHeader.getOptionalHeader().is64bit());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
|
||||||
return tls.toDataType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.io.IOException;
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.StructConverter;
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
@ -76,13 +75,13 @@ public class TLSDirectory implements StructConverter {
|
||||||
index += BinaryReader.SIZEOF_LONG;
|
index += BinaryReader.SIZEOF_LONG;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
startAddressOfRawData = reader.readInt(index) & Conv.INT_MASK;
|
startAddressOfRawData = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
endAddressOfRawData = reader.readInt(index) & Conv.INT_MASK;
|
endAddressOfRawData = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
addressOfIndex = reader.readInt(index) & Conv.INT_MASK;
|
addressOfIndex = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
addressOfCallBacks = reader.readInt(index) & Conv.INT_MASK;
|
addressOfCallBacks = reader.readUnsignedInt(index);
|
||||||
index += BinaryReader.SIZEOF_INT;
|
index += BinaryReader.SIZEOF_INT;
|
||||||
}
|
}
|
||||||
Msg.info(this, "TLS callbacks at " + Long.toHexString(addressOfCallBacks));
|
Msg.info(this, "TLS callbacks at " + Long.toHexString(addressOfCallBacks));
|
||||||
|
@ -137,9 +136,7 @@ public class TLSDirectory implements StructConverter {
|
||||||
return characteristics;
|
return characteristics;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(getName(), 0);
|
StructureDataType struct = new StructureDataType(getName(), 0);
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.*;
|
import ghidra.app.util.bin.*;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.util.Conv;
|
|
||||||
import ghidra.util.DataConverter;
|
import ghidra.util.DataConverter;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@ public class ThunkData implements StructConverter, ByteArrayConverter {
|
||||||
value = reader.readLong(index);
|
value = reader.readLong(index);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
value = reader.readInt(index) & Conv.INT_MASK;
|
value = reader.readUnsignedInt(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +99,7 @@ public class ThunkData implements StructConverter, ByteArrayConverter {
|
||||||
* @param value the new thunk value
|
* @param value the new thunk value
|
||||||
*/
|
*/
|
||||||
public void setValue(int value) {
|
public void setValue(int value) {
|
||||||
this.value = value & Conv.INT_MASK;
|
this.value = Integer.toUnsignedLong(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,9 +153,7 @@ public class ThunkData implements StructConverter, ByteArrayConverter {
|
||||||
return ibn;
|
return ibn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
|
||||||
*/
|
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
UnionDataType union = new UnionDataType("u1");
|
UnionDataType union = new UnionDataType("u1");
|
||||||
union.setCategoryPath(new CategoryPath("/PE"));
|
union.setCategoryPath(new CategoryPath("/PE"));
|
||||||
|
@ -174,9 +171,7 @@ public class ThunkData implements StructConverter, ByteArrayConverter {
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
|
||||||
*/
|
|
||||||
public byte[] toBytes(DataConverter dc) {
|
public byte[] toBytes(DataConverter dc) {
|
||||||
if (is64bit) {
|
if (is64bit) {
|
||||||
return dc.getBytes(value);
|
return dc.getBytes(value);
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.app.util.bin.format.pe.cli;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.bin.StructConverter;
|
||||||
import ghidra.app.util.bin.format.pe.*;
|
import ghidra.app.util.bin.format.pe.*;
|
||||||
import ghidra.app.util.importer.MessageLog;
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -31,7 +32,7 @@ import ghidra.util.task.TaskMonitor;
|
||||||
/**
|
/**
|
||||||
* The Metadata directory pointed found in {@link ImageCor20Header}.
|
* The Metadata directory pointed found in {@link ImageCor20Header}.
|
||||||
*/
|
*/
|
||||||
public class CliMetadataDirectory extends DataDirectory {
|
public class CliMetadataDirectory extends DataDirectory implements StructConverter {
|
||||||
|
|
||||||
private final static String NAME = "CLI_METADATA_DIRECTORY";
|
private final static String NAME = "CLI_METADATA_DIRECTORY";
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public class CliMetadataDirectory extends DataDirectory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
|
||||||
NTHeader ntHeader) throws DuplicateNameException, CodeUnitInsertionException,
|
NTHeader nt) throws DuplicateNameException, CodeUnitInsertionException,
|
||||||
IOException, MemoryAccessException {
|
IOException, MemoryAccessException {
|
||||||
|
|
||||||
if (metadataRoot == null) {
|
if (metadataRoot == null) {
|
||||||
|
@ -86,7 +87,7 @@ public class CliMetadataDirectory extends DataDirectory {
|
||||||
monitor.setMessage("[" + program.getName() + "]: CLI metadata...");
|
monitor.setMessage("[" + program.getName() + "]: CLI metadata...");
|
||||||
|
|
||||||
// Get our program address
|
// Get our program address
|
||||||
Address addr = PeUtils.getMarkupAddress(program, isBinary, ntHeader, virtualAddress);
|
Address addr = PeUtils.getMarkupAddress(program, isBinary, nt, virtualAddress);
|
||||||
if (!program.getMemory().contains(addr)) {
|
if (!program.getMemory().contains(addr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,7 @@ public class CliMetadataDirectory extends DataDirectory {
|
||||||
PeUtils.createData(program, addr, dt, log);
|
PeUtils.createData(program, addr, dt, log);
|
||||||
|
|
||||||
// Markup metadata header
|
// Markup metadata header
|
||||||
metadataRoot.markup(program, isBinary, monitor, log, ntHeader);
|
metadataRoot.markup(program, isBinary, monitor, log, nt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class VS_VERSION_INFO implements StructConverter {
|
||||||
reader.setPointerIndex(oldIndex);
|
reader.setPointerIndex(oldIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException {
|
public DataType toDataType() throws DuplicateNameException {
|
||||||
StructureDataType struct = new StructureDataType(NAME, 0);
|
StructureDataType struct = new StructureDataType(NAME, 0);
|
||||||
struct.add(WORD, "StructLength", null);
|
struct.add(WORD, "StructLength", null);
|
||||||
|
|
|
@ -33,6 +33,7 @@ public enum MSProductType {
|
||||||
this.desc = d;
|
this.desc = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ public class RichProduct {
|
||||||
return productType;
|
return productType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getProductVersion() + " -- " + getProductType();
|
return getProductVersion() + " -- " + getProductType();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue