mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 13:16:48 +08:00
GP-6502: A few more PE Dynamic Value Relocation Table (DVRT)
improvements
This commit is contained in:
+1
-1
@@ -160,7 +160,7 @@ public class LoadConfigDirectory implements StructConverter {
|
||||
if (section != null) {
|
||||
long fileOffset = section.getPointerToRawData() + dynamicValueRelocTableOffset;
|
||||
long rva = section.getVirtualAddress() + dynamicValueRelocTableOffset;
|
||||
dvrt = new ImageDynamicRelocationTable(reader.clone(fileOffset), rva);
|
||||
dvrt = new ImageDynamicRelocationTable(reader.clone(fileOffset), rva, is64bit);
|
||||
}
|
||||
else {
|
||||
Msg.error(this,
|
||||
|
||||
+39
-9
@@ -35,17 +35,20 @@ public enum DvrtType implements StructConverter {
|
||||
IMAGE_DYNAMIC_RELOCATION_SWITCHABLE_BRANCH(0x5),
|
||||
IMAGE_DYNAMIC_RELOCATION_ARM64X(0x6),
|
||||
IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE(0x7),
|
||||
IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER(0x8);
|
||||
IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER(0x8),
|
||||
IMAGE_DYNAMIC_RELOCATION_UNKNOWN(0x100); // made up to handle unknown types
|
||||
|
||||
private long value;
|
||||
private int size;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DvrtType}
|
||||
* Creates a new 8-byte {@link DvrtType}
|
||||
*
|
||||
* @param value The defined value of the type
|
||||
*/
|
||||
private DvrtType(int value) {
|
||||
private DvrtType(long value) {
|
||||
this.value = value;
|
||||
this.size = 8;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,24 +59,51 @@ public enum DvrtType implements StructConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a {@link DvrtType}
|
||||
* Changes the size of this {@link DvrtType} to the given number of bytes
|
||||
*
|
||||
* @param n The new size in bytes
|
||||
* @return This {@link DvrtType}, with the new size applied
|
||||
*/
|
||||
public DvrtType changeSize(int n) {
|
||||
this.size = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an 8-byte {@link DvrtType}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} that points to the start of the type value
|
||||
* @return The type that was read, or {@code null} if the value read does not correspond to a
|
||||
* valid type
|
||||
* @return The type that was read, or {@link #IMAGE_DYNAMIC_RELOCATION_UNKNOWN} if the value
|
||||
* read does not correspond to a known type
|
||||
* @throws IOException if there was an IO-related error
|
||||
*/
|
||||
public static DvrtType type(BinaryReader reader) throws IOException {
|
||||
public static DvrtType type8(BinaryReader reader) throws IOException {
|
||||
long value = reader.readNextLong();
|
||||
return Arrays.stream(DvrtType.values())
|
||||
.filter(e -> value == e.getValue())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.orElse(IMAGE_DYNAMIC_RELOCATION_UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a 4-byte {@link DvrtType}
|
||||
*
|
||||
* @param reader A {@link BinaryReader} that points to the start of the type value
|
||||
* @return The type that was read, or {@link #IMAGE_DYNAMIC_RELOCATION_UNKNOWN} if the value
|
||||
* read does not correspond to a known type
|
||||
* @throws IOException if there was an IO-related error
|
||||
*/
|
||||
public static DvrtType type4(BinaryReader reader) throws IOException {
|
||||
int value = reader.readNextInt();
|
||||
return Arrays.stream(DvrtType.values())
|
||||
.filter(e -> value == e.getValue())
|
||||
.findFirst()
|
||||
.orElse(IMAGE_DYNAMIC_RELOCATION_UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
EnumDataType enumDt = new EnumDataType("DvrtType", 8);
|
||||
EnumDataType enumDt = new EnumDataType("DvrtType", size);
|
||||
Arrays.stream(values()).forEach(e -> enumDt.add(e.name(), e.getValue()));
|
||||
enumDt.setCategoryPath(new CategoryPath("/PE"));
|
||||
return enumDt;
|
||||
|
||||
+18
-7
@@ -40,6 +40,7 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
||||
private int baseRelocSize;
|
||||
|
||||
private long rva;
|
||||
private boolean is64bit;
|
||||
private List<AbstractImageDynamicRelocationHeader> headers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@@ -47,13 +48,17 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
||||
*
|
||||
* @param reader A {@link BinaryReader} that points to the start of the structure
|
||||
* @param rva The relative virtual address of the structure
|
||||
* @param is64bit True if 64-bit; otherwise, false
|
||||
* @throws IOException if there was an IO-related error
|
||||
*/
|
||||
public ImageDynamicRelocation(BinaryReader reader, long rva) throws IOException {
|
||||
public ImageDynamicRelocation(BinaryReader reader, long rva, boolean is64bit)
|
||||
throws IOException {
|
||||
this.rva = rva;
|
||||
this.is64bit = is64bit;
|
||||
long origIndex = reader.getPointerIndex();
|
||||
|
||||
symbol = reader.readNext(DvrtType::type);
|
||||
symbol = is64bit ? reader.readNext(DvrtType::type8)
|
||||
: reader.readNext(DvrtType::type4).changeSize(4);
|
||||
baseRelocSize = reader.readNextInt();
|
||||
|
||||
long startIndex = reader.getPointerIndex();
|
||||
@@ -69,7 +74,8 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
||||
case IMAGE_DYNAMIC_RELOCATION_ARM64X -> new ImageArm64X(reader, newRva);
|
||||
case IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE -> new ImageFunctionOverrideHeader(
|
||||
reader, newRva, baseRelocSize);
|
||||
case null -> new ImageUnsupportedRelocationHeader(reader, newRva, baseRelocSize);
|
||||
case IMAGE_DYNAMIC_RELOCATION_UNKNOWN -> new ImageUnsupportedRelocationHeader(
|
||||
reader, newRva, baseRelocSize);
|
||||
default -> new ImageUnsupportedRelocationHeader(reader, newRva, baseRelocSize);
|
||||
});
|
||||
}
|
||||
@@ -100,14 +106,19 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
||||
for (AbstractImageDynamicRelocationHeader header : headers) {
|
||||
header.markup(program, isBinary, monitor, log, ntHeader);
|
||||
}
|
||||
listing.setComment(start, CommentType.PLATE,
|
||||
symbol != null ? symbol.name() : "IMAGE_DYNAMIC_RELOCATION_<UNKNOWN>");
|
||||
listing.setComment(start, CommentType.PLATE, symbol.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||
StructureDataType struct = new StructureDataType("IMAGE_DYNAMIC_RELOCATION", 0);
|
||||
struct.add(symbol != null ? symbol.toDataType() : QWORD, "Symbol", null);
|
||||
String name ="IMAGE_DYNAMIC_RELOCATION";
|
||||
DataType symbolType = symbol.toDataType();
|
||||
if (symbol == DvrtType.IMAGE_DYNAMIC_RELOCATION_UNKNOWN) {
|
||||
name += "_UNKNOWN";
|
||||
symbolType = is64bit ? QWORD : DWORD;
|
||||
}
|
||||
StructureDataType struct = new StructureDataType(name, 0);
|
||||
struct.add(symbolType, "Symbol", null);
|
||||
struct.add(DWORD, "BaseRelocSize", null);
|
||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
||||
return struct;
|
||||
|
||||
+9
-2
@@ -47,18 +47,25 @@ public class ImageDynamicRelocationTable implements StructConverter, PeMarkupabl
|
||||
*
|
||||
* @param reader A {@link BinaryReader} that points to the start of the structure
|
||||
* @param rva The relative virtual address of the structure
|
||||
* @param is64bit True if 64-bit; otherwise, false
|
||||
* @throws IOException if there was an IO-related error
|
||||
*/
|
||||
public ImageDynamicRelocationTable(BinaryReader reader, long rva) throws IOException {
|
||||
public ImageDynamicRelocationTable(BinaryReader reader, long rva, boolean is64bit)
|
||||
throws IOException {
|
||||
this.rva = rva;
|
||||
long origIndex = reader.getPointerIndex();
|
||||
|
||||
version = reader.readNextInt();
|
||||
size = reader.readNextInt();
|
||||
|
||||
if (version != 1) {
|
||||
// TODO: support version 2
|
||||
return;
|
||||
}
|
||||
|
||||
long startIndex = reader.getPointerIndex();
|
||||
for (long i = startIndex; i < startIndex + size; i = reader.getPointerIndex()) {
|
||||
relocations.add(new ImageDynamicRelocation(reader, rva + (i - origIndex)));
|
||||
relocations.add(new ImageDynamicRelocation(reader, rva + (i - origIndex), is64bit));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user