GP-2827: No longer rebasing PE files with large imagebases to 0x10000.

This commit is contained in:
Ryan Kurtz 2022-12-07 04:08:03 -05:00
parent 40ab399387
commit 4413dab21d
3 changed files with 8 additions and 94 deletions

View file

@ -267,10 +267,6 @@ public interface OptionalHeader extends StructConverter {
*/
public long getImageBase();
public long getOriginalImageBase();
public boolean wasRebased();
/**
* @return the RVA that would be assigned to the next section following the last section
*/

View file

@ -143,9 +143,6 @@ public class OptionalHeaderImpl implements OptionalHeader {
protected int startIndex;
private long startOfDataDirs;
protected long originalImageBase;
protected boolean wasRebased;
OptionalHeaderImpl(NTHeader ntHeader, BinaryReader reader, int startIndex) throws IOException {
this.ntHeader = ntHeader;
this.reader = reader;
@ -182,11 +179,6 @@ public class OptionalHeaderImpl implements OptionalHeader {
return imageBase;
}
@Override
public long getOriginalImageBase() {
return originalImageBase;
}
@Override
public long getAddressOfEntryPoint() {
return Conv.intToLong(addressOfEntryPoint);
@ -515,23 +507,10 @@ public class OptionalHeaderImpl implements OptionalHeader {
if (is64bit()) {
baseOfData = -1;//not used
imageBase = reader.readNextLong();
if (imageBase <= 0 && !is64bit()) {
Msg.warn(this, "Non-standard image base: 0x" + Long.toHexString(imageBase));
originalImageBase = imageBase;
imageBase = 0x10000;
wasRebased = true;
}
}
else {
baseOfData = reader.readNextInt();
int imgBase = reader.readNextInt();
imageBase = imgBase & Conv.INT_MASK;
if (imgBase <= 0) {
Msg.warn(this, "Non-standard image base " + Integer.toHexString(imgBase));
originalImageBase = imageBase;
imageBase = 0x10000;
wasRebased = true;
}
imageBase = Integer.toUnsignedLong(reader.readNextInt());
}
sectionAlignment = reader.readNextInt();
@ -744,11 +723,6 @@ public class OptionalHeaderImpl implements OptionalHeader {
}
}
@Override
public boolean wasRebased() {
return wasRebased;
}
@Override
public boolean isCLI() throws IOException {
long origPointerIndex = reader.getPointerIndex();

View file

@ -36,13 +36,12 @@ import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.RelocationTable;
import ghidra.program.model.symbol.*;
import ghidra.program.model.util.AddressSetPropertyMap;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.*;
import ghidra.util.Msg;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;
@ -281,10 +280,9 @@ public class PeLoader extends AbstractPeDebugLoader {
private void processRelocations(OptionalHeader optionalHeader, Program prog,
TaskMonitor monitor, MessageLog log) {
// We don't currently support relocations in PE's because we always load at the preferred
// image base, but we'll go though them anyway and add them to the relocation table
if (monitor.isCancelled()) {
return;
}
monitor.setMessage("[" + prog.getName() + "]: processing relocation tables...");
DataDirectory[] dataDirectories = optionalHeader.getDataDirectories();
@ -300,68 +298,14 @@ public class PeLoader extends AbstractPeDebugLoader {
AddressSpace space = prog.getAddressFactory().getDefaultAddressSpace();
RelocationTable relocTable = prog.getRelocationTable();
Memory memory = prog.getMemory();
BaseRelocation[] relocs = brdd.getBaseRelocations();
long originalImageBase = optionalHeader.getOriginalImageBase();
AddressRange brddRange =
new AddressRangeImpl(space.getAddress(originalImageBase + brdd.getVirtualAddress()),
space.getAddress(originalImageBase + brdd.getVirtualAddress() + brdd.getSize()));
AddressRange headerRange = new AddressRangeImpl(space.getAddress(originalImageBase),
space.getAddress(originalImageBase + optionalHeader.getSizeOfHeaders()));
DataConverter conv = LittleEndianDataConverter.INSTANCE;
for (BaseRelocation reloc : relocs) {
for (BaseRelocation reloc : brdd.getBaseRelocations()) {
if (monitor.isCancelled()) {
return;
}
int baseAddr = reloc.getVirtualAddress();
int count = reloc.getCount();
for (int j = 0; j < count; ++j) {
int type = reloc.getType(j);
if (type == BaseRelocation.IMAGE_REL_BASED_ABSOLUTE) {
continue;
}
int offset = reloc.getOffset(j);
long addr =
Integer.toUnsignedLong(baseAddr + offset) + optionalHeader.getImageBase();
Address relocAddr = space.getAddress(addr);
try {
byte[] bytes = optionalHeader.is64bit() ? new byte[8] : new byte[4];
memory.getBytes(relocAddr, bytes);
if (optionalHeader.wasRebased()) {
long val = optionalHeader.is64bit() ? conv.getLong(bytes)
: conv.getInt(bytes) & 0xFFFFFFFFL;
val =
val - (originalImageBase & 0xFFFFFFFFL) + optionalHeader.getImageBase();
byte[] newbytes = optionalHeader.is64bit() ? conv.getBytes(val)
: conv.getBytes((int) val);
if (type == BaseRelocation.IMAGE_REL_BASED_HIGHLOW) {
memory.setBytes(relocAddr, newbytes);
}
else if (type == BaseRelocation.IMAGE_REL_BASED_DIR64) {
memory.setBytes(relocAddr, newbytes);
}
else {
Msg.error(this, "Non-standard relocation type " + type);
}
}
relocTable.add(relocAddr, type, null, null, null);
}
catch (MemoryAccessException e) {
log.appendMsg("Relocation does not exist in memory: " + relocAddr);
}
if (brddRange.contains(relocAddr)) {
Msg.error(this, "Self-modifying relocation table at " + relocAddr);
return;
}
if (headerRange.contains(relocAddr)) {
Msg.error(this, "Header modified at " + relocAddr);
return;
}
for (int i = 0; i < reloc.getCount(); ++i) {
long addr = optionalHeader.getImageBase() + baseAddr + reloc.getOffset(i);
relocTable.add(space.getAddress(addr), reloc.getType(i), null, null, null);
}
}
}