mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 01:10:26 +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) {
|
if (section != null) {
|
||||||
long fileOffset = section.getPointerToRawData() + dynamicValueRelocTableOffset;
|
long fileOffset = section.getPointerToRawData() + dynamicValueRelocTableOffset;
|
||||||
long rva = section.getVirtualAddress() + dynamicValueRelocTableOffset;
|
long rva = section.getVirtualAddress() + dynamicValueRelocTableOffset;
|
||||||
dvrt = new ImageDynamicRelocationTable(reader.clone(fileOffset), rva);
|
dvrt = new ImageDynamicRelocationTable(reader.clone(fileOffset), rva, is64bit);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Msg.error(this,
|
Msg.error(this,
|
||||||
|
|||||||
+39
-9
@@ -35,17 +35,20 @@ public enum DvrtType implements StructConverter {
|
|||||||
IMAGE_DYNAMIC_RELOCATION_SWITCHABLE_BRANCH(0x5),
|
IMAGE_DYNAMIC_RELOCATION_SWITCHABLE_BRANCH(0x5),
|
||||||
IMAGE_DYNAMIC_RELOCATION_ARM64X(0x6),
|
IMAGE_DYNAMIC_RELOCATION_ARM64X(0x6),
|
||||||
IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE(0x7),
|
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 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
|
* @param value The defined value of the type
|
||||||
*/
|
*/
|
||||||
private DvrtType(int value) {
|
private DvrtType(long value) {
|
||||||
this.value = 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
|
* @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
|
* @return The type that was read, or {@link #IMAGE_DYNAMIC_RELOCATION_UNKNOWN} if the value
|
||||||
* valid type
|
* read does not correspond to a known type
|
||||||
* @throws IOException if there was an IO-related error
|
* @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();
|
long value = reader.readNextLong();
|
||||||
return Arrays.stream(DvrtType.values())
|
return Arrays.stream(DvrtType.values())
|
||||||
.filter(e -> value == e.getValue())
|
.filter(e -> value == e.getValue())
|
||||||
.findFirst()
|
.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
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
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()));
|
Arrays.stream(values()).forEach(e -> enumDt.add(e.name(), e.getValue()));
|
||||||
enumDt.setCategoryPath(new CategoryPath("/PE"));
|
enumDt.setCategoryPath(new CategoryPath("/PE"));
|
||||||
return enumDt;
|
return enumDt;
|
||||||
|
|||||||
+18
-7
@@ -40,6 +40,7 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
|||||||
private int baseRelocSize;
|
private int baseRelocSize;
|
||||||
|
|
||||||
private long rva;
|
private long rva;
|
||||||
|
private boolean is64bit;
|
||||||
private List<AbstractImageDynamicRelocationHeader> headers = new ArrayList<>();
|
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 reader A {@link BinaryReader} that points to the start of the structure
|
||||||
* @param rva The relative virtual address 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
|
* @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.rva = rva;
|
||||||
|
this.is64bit = is64bit;
|
||||||
long origIndex = reader.getPointerIndex();
|
long origIndex = reader.getPointerIndex();
|
||||||
|
|
||||||
symbol = reader.readNext(DvrtType::type);
|
symbol = is64bit ? reader.readNext(DvrtType::type8)
|
||||||
|
: reader.readNext(DvrtType::type4).changeSize(4);
|
||||||
baseRelocSize = reader.readNextInt();
|
baseRelocSize = reader.readNextInt();
|
||||||
|
|
||||||
long startIndex = reader.getPointerIndex();
|
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_ARM64X -> new ImageArm64X(reader, newRva);
|
||||||
case IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE -> new ImageFunctionOverrideHeader(
|
case IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE -> new ImageFunctionOverrideHeader(
|
||||||
reader, newRva, baseRelocSize);
|
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);
|
default -> new ImageUnsupportedRelocationHeader(reader, newRva, baseRelocSize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -100,14 +106,19 @@ public class ImageDynamicRelocation implements StructConverter, PeMarkupable {
|
|||||||
for (AbstractImageDynamicRelocationHeader header : headers) {
|
for (AbstractImageDynamicRelocationHeader header : headers) {
|
||||||
header.markup(program, isBinary, monitor, log, ntHeader);
|
header.markup(program, isBinary, monitor, log, ntHeader);
|
||||||
}
|
}
|
||||||
listing.setComment(start, CommentType.PLATE,
|
listing.setComment(start, CommentType.PLATE, symbol.name());
|
||||||
symbol != null ? symbol.name() : "IMAGE_DYNAMIC_RELOCATION_<UNKNOWN>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
StructureDataType struct = new StructureDataType("IMAGE_DYNAMIC_RELOCATION", 0);
|
String name ="IMAGE_DYNAMIC_RELOCATION";
|
||||||
struct.add(symbol != null ? symbol.toDataType() : QWORD, "Symbol", null);
|
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.add(DWORD, "BaseRelocSize", null);
|
||||||
struct.setCategoryPath(new CategoryPath("/PE"));
|
struct.setCategoryPath(new CategoryPath("/PE"));
|
||||||
return struct;
|
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 reader A {@link BinaryReader} that points to the start of the structure
|
||||||
* @param rva The relative virtual address 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
|
* @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;
|
this.rva = rva;
|
||||||
long origIndex = reader.getPointerIndex();
|
long origIndex = reader.getPointerIndex();
|
||||||
|
|
||||||
version = reader.readNextInt();
|
version = reader.readNextInt();
|
||||||
size = reader.readNextInt();
|
size = reader.readNextInt();
|
||||||
|
|
||||||
|
if (version != 1) {
|
||||||
|
// TODO: support version 2
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
long startIndex = reader.getPointerIndex();
|
long startIndex = reader.getPointerIndex();
|
||||||
for (long i = startIndex; i < startIndex + size; i = 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