mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-1571 ELF: create fake relocation table entry for non-relocation memory modifications (needed for ELF export)
This commit is contained in:
parent
b5927ce849
commit
9076b2429c
5 changed files with 66 additions and 17 deletions
|
@ -378,9 +378,11 @@ public class ElfDefaultGotPltMarkup {
|
|||
// TODO: record artificial relative relocation for reversion/export concerns
|
||||
entry1Value += imageBaseAdj; // adjust first entry value
|
||||
if (elf.is64Bit()) {
|
||||
elfLoadHelper.addFakeRelocTableEntry(gotStart, 8);
|
||||
memory.setLong(gotStart, entry1Value);
|
||||
}
|
||||
else {
|
||||
elfLoadHelper.addFakeRelocTableEntry(gotStart, 4);
|
||||
memory.setInt(gotStart, (int) entry1Value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,7 @@ package ghidra.app.util.bin.format.elf;
|
|||
|
||||
import ghidra.app.util.bin.format.MemoryLoadable;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
|
@ -203,4 +202,18 @@ public interface ElfLoadHelper {
|
|||
public long getOriginalValue(Address addr, boolean signExtend)
|
||||
throws MemoryAccessException;
|
||||
|
||||
/**
|
||||
* Add a fake relocation table entry if none previously existed for the specified address.
|
||||
* This is intended to record original file bytes when forced modifications have been
|
||||
* performed during the ELF import processing. A relocation type of 0 will be specified for
|
||||
* fake entry.
|
||||
* @param address relocation address
|
||||
* @param length number of bytes affected
|
||||
* @return true if recorded successfully, or false if conflict with existing relocation entry occurs
|
||||
* @throws MemoryAccessException if unable to read bytes from memory
|
||||
* @throws AddressOverflowException if range address wrap occurs
|
||||
*/
|
||||
public boolean addFakeRelocTableEntry(Address address, int length)
|
||||
throws MemoryAccessException, AddressOverflowException;
|
||||
|
||||
}
|
||||
|
|
|
@ -846,6 +846,11 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
monitor.checkCanceled();
|
||||
monitor.incrementProgress(1);
|
||||
|
||||
long type = reloc.getType();
|
||||
if (type == 0) {
|
||||
continue; // ignore relocation type 0 (i.e., ..._NONE)
|
||||
}
|
||||
|
||||
int symbolIndex = reloc.getSymbolIndex();
|
||||
String symbolName = null;
|
||||
if (symbolIndex >= 0 && symbolIndex < symbols.length) {
|
||||
|
@ -863,7 +868,6 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
|
||||
byte[] bytes = elf.is64Bit() ? new byte[8] : new byte[4];
|
||||
|
||||
long type = reloc.getType();
|
||||
if (relrRelocationType != 0) {
|
||||
type = relrRelocationType;
|
||||
reloc.setType(relrRelocationType);
|
||||
|
@ -929,6 +933,28 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
|
|||
: dataConverter.getValue(bytes, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addFakeRelocTableEntry(Address address, int length)
|
||||
throws MemoryAccessException, AddressOverflowException {
|
||||
byte[] bytes = new byte[length];
|
||||
Address maxAddr = address.addNoWrap(length - 1);
|
||||
RelocationTable relocationTable = program.getRelocationTable();
|
||||
Relocation relocation = relocationTable.getRelocation(address);
|
||||
if (relocation != null) {
|
||||
return false;
|
||||
}
|
||||
relocation = relocationTable.getRelocationAfter(address);
|
||||
if (relocation != null && relocation.getAddress().compareTo(maxAddr) <= 0) {
|
||||
return false;
|
||||
}
|
||||
int cnt = memory.getBytes(address, bytes);
|
||||
if (cnt != length) {
|
||||
throw new MemoryAccessException();
|
||||
}
|
||||
relocationTable.add(address, 0, new long[0], bytes, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add reference to previously applied header structure (assumes markupElfHeader previously called)
|
||||
* @param componentName
|
||||
|
|
|
@ -454,7 +454,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
|
||||
setTableEntryIfZero(gotBaseAddress, gotIndex, symbolOffset, elfLoadHelper);
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
catch (MemoryAccessException | AddressOverflowException e) {
|
||||
Msg.error(this, "Failed to update .got table entry", e);
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
|
@ -793,7 +793,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
catch (NotFoundException e) {
|
||||
throw new AssertException("unexpected", e);
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
catch (MemoryAccessException | AddressOverflowException e) {
|
||||
elfLoadHelper.log("Failed to adjust GOT: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -846,37 +846,42 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
catch (NotFoundException e) {
|
||||
throw new AssertException("unexpected", e);
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
catch (MemoryAccessException | AddressOverflowException e) {
|
||||
elfLoadHelper.log("Failed to adjust MIPS GOT: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Address adjustTableEntryIfNonZero(Address tableBaseAddr, int entryIndex,
|
||||
long adjustment, ElfLoadHelper elfLoadHelper) throws MemoryAccessException {
|
||||
// TODO: record artificial relative relocation for reversion/export concerns
|
||||
long adjustment, ElfLoadHelper elfLoadHelper)
|
||||
throws MemoryAccessException, AddressOverflowException {
|
||||
boolean is64Bit = elfLoadHelper.getElfHeader().is64Bit();
|
||||
Memory memory = elfLoadHelper.getProgram().getMemory();
|
||||
Address tableEntryAddr;
|
||||
if (is64Bit) {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 8);
|
||||
long offset = memory.getLong(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
memory.setLong(tableEntryAddr, offset + adjustment);
|
||||
if (adjustment != 0) {
|
||||
long offset = memory.getLong(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
elfLoadHelper.addFakeRelocTableEntry(tableEntryAddr, 8);
|
||||
memory.setLong(tableEntryAddr, offset + adjustment);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tableEntryAddr = tableBaseAddr.add(entryIndex * 4);
|
||||
int offset = memory.getInt(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
memory.setInt(tableEntryAddr, (int) (offset + adjustment));
|
||||
if (adjustment != 0) {
|
||||
int offset = memory.getInt(tableEntryAddr);
|
||||
if (offset != 0) {
|
||||
elfLoadHelper.addFakeRelocTableEntry(tableEntryAddr, 4);
|
||||
memory.setInt(tableEntryAddr, (int) (offset + adjustment));
|
||||
}
|
||||
}
|
||||
}
|
||||
return tableEntryAddr;
|
||||
}
|
||||
|
||||
private Address setTableEntryIfZero(Address tableBaseAddr, int entryIndex, long value,
|
||||
ElfLoadHelper elfLoadHelper) throws MemoryAccessException {
|
||||
// TODO: record artificial relative relocation for reversion/export concerns
|
||||
ElfLoadHelper elfLoadHelper) throws MemoryAccessException, AddressOverflowException {
|
||||
boolean is64Bit = elfLoadHelper.getElfHeader().is64Bit();
|
||||
Memory memory = elfLoadHelper.getProgram().getMemory();
|
||||
Address tableEntryAddr;
|
||||
|
@ -884,6 +889,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
tableEntryAddr = tableBaseAddr.add(entryIndex * 8);
|
||||
long offset = memory.getLong(tableEntryAddr);
|
||||
if (offset == 0) {
|
||||
elfLoadHelper.addFakeRelocTableEntry(tableEntryAddr, 8);
|
||||
memory.setLong(tableEntryAddr, value);
|
||||
}
|
||||
}
|
||||
|
@ -891,6 +897,7 @@ public class MIPS_ElfExtension extends ElfExtension {
|
|||
tableEntryAddr = tableBaseAddr.add(entryIndex * 4);
|
||||
int offset = memory.getInt(tableEntryAddr);
|
||||
if (offset == 0) {
|
||||
elfLoadHelper.addFakeRelocTableEntry(tableEntryAddr, 4);
|
||||
memory.setInt(tableEntryAddr, (int) value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,9 +113,10 @@ public class PowerPC_ElfExtension extends ElfExtension {
|
|||
// Update first got entry normally updated by link editor to refer to dynamic table
|
||||
int dynamicOffset =
|
||||
memory.getInt(gotAddr) + (int) elfLoadHelper.getImageBaseWordAdjustmentOffset();
|
||||
elfLoadHelper.addFakeRelocTableEntry(gotAddr, 4);
|
||||
memory.setInt(gotAddr, dynamicOffset);
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
catch (MemoryAccessException | AddressOverflowException e) {
|
||||
elfLoadHelper.log(e);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue