mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-07-05 01:08:38 +00:00
Merge remote-tracking branch
'origin/GP-1352_ghidra1_ElfAndroidRelocMarkup' (Closes #3462)
This commit is contained in:
commit
be13d9047a
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.elf;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import ghidra.app.plugin.exceptionhandlers.gcc.datatype.AbstractLeb128DataType;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.SettingsDefinition;
|
||||
|
@ -48,10 +50,8 @@ class AndroidElfRelocationData extends AbstractLeb128DataType {
|
|||
|
||||
@Override
|
||||
public DataType clone(DataTypeManager dtm) {
|
||||
if (dtm == getDataTypeManager()) {
|
||||
return this;
|
||||
}
|
||||
return new AndroidElfRelocationData(dtm, relocationOffset);
|
||||
// specific instances are used by AndroidElfRelocationTableDataType
|
||||
throw new UnsupportedOperationException("may not be cloned");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,6 +18,8 @@ package ghidra.app.util.bin.format.elf;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import ghidra.app.util.bin.*;
|
||||
import ghidra.app.util.bin.format.elf.AndroidElfRelocationTableDataType.LEB128Info;
|
||||
import ghidra.docking.settings.Settings;
|
||||
|
@ -48,10 +50,8 @@ class AndroidElfRelocationGroup extends DynamicDataType {
|
|||
|
||||
@Override
|
||||
public DataType clone(DataTypeManager dtm) {
|
||||
if (dtm == dataMgr) {
|
||||
return this;
|
||||
}
|
||||
return new AndroidElfRelocationGroup(dtm, baseRelocOffset);
|
||||
// specific instances are used by AndroidElfRelocationTableDatatype
|
||||
throw new UnsupportedOperationException("may not be cloned");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,9 +125,10 @@ class AndroidElfRelocationGroup extends DynamicDataType {
|
|||
}
|
||||
else {
|
||||
sleb128 = LEB128Info.parse(reader, true);
|
||||
long baseOffset = relocOffset;
|
||||
relocOffset += sleb128.value;
|
||||
DataTypeComponent dtc = new ReadOnlyDataTypeComponent(
|
||||
new AndroidElfRelocationOffset(dataMgr, relocOffset), this,
|
||||
new AndroidElfRelocationOffset(dataMgr, baseOffset, relocOffset), this,
|
||||
sleb128.byteLength, list.size(), sleb128.offset, "reloc_offset_" + i,
|
||||
null);
|
||||
list.add(dtc);
|
||||
|
@ -161,6 +162,7 @@ class AndroidElfRelocationGroup extends DynamicDataType {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// group_size component
|
||||
Scalar s = (Scalar) comps[0].getDataType().getValue(buf, null, comps[0].getLength());
|
||||
int groupSize = (int) s.getValue();
|
||||
|
||||
|
@ -170,10 +172,7 @@ class AndroidElfRelocationGroup extends DynamicDataType {
|
|||
WrappedMemBuffer cbuf = new WrappedMemBuffer(buf, comps[2].getOffset());
|
||||
s = (Scalar) comps[2].getDataType().getValue(cbuf, null, comps[2].getLength());
|
||||
long groupOffsetDelta = s.getValue();
|
||||
if (lastDtc.getFieldName().startsWith("group_")) {
|
||||
// must compute final offset for group
|
||||
return baseRelocOffset + (groupSize * groupOffsetDelta);
|
||||
}
|
||||
return baseRelocOffset + ((groupSize - 1) * groupOffsetDelta);
|
||||
}
|
||||
|
||||
if (lastDtc.getFieldName().startsWith("group_")) {
|
||||
|
@ -189,7 +188,6 @@ class AndroidElfRelocationGroup extends DynamicDataType {
|
|||
AndroidElfRelocationData d = (AndroidElfRelocationData) dt;
|
||||
return d.getRelocationOffset(); // return stashed offset
|
||||
}
|
||||
|
||||
return -1; // unexpected
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,19 @@
|
|||
*/
|
||||
package ghidra.app.util.bin.format.elf;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
|
||||
import ghidra.app.plugin.exceptionhandlers.gcc.datatype.AbstractLeb128DataType;
|
||||
import ghidra.app.util.opinion.ElfLoader;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.docking.settings.SettingsDefinition;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
|
||||
/**
|
||||
|
@ -46,18 +51,21 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
|
|||
* value adjusted by baseOffset.
|
||||
* @param dtm the data type manager to associate with this data type.
|
||||
* @param baseOffset base offset to which LEB128 offset data should be added
|
||||
* @param relocationOffset the actual relocation offset value assciated with this
|
||||
* instance (used by {@link #getValue(MemBuffer, Settings, int)} and
|
||||
* returned by {@link #getRelocationOffset()}. This value should equals
|
||||
* <code>baseOffset</code> plus decoded value of sleb128 data.
|
||||
*/
|
||||
AndroidElfRelocationOffset(DataTypeManager dtm, long baseOffset) {
|
||||
AndroidElfRelocationOffset(DataTypeManager dtm, long baseOffset, long relocationOffset) {
|
||||
super("sleb128_offset", true, dtm);
|
||||
this.baseOffset = baseOffset;
|
||||
this.relocationOffset = relocationOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType clone(DataTypeManager dtm) {
|
||||
if (dtm == getDataTypeManager()) {
|
||||
return this;
|
||||
}
|
||||
return new AndroidElfRelocationOffset(dtm, baseOffset);
|
||||
// specific instances are used by AndroidElfRelocationGroup
|
||||
throw new UnsupportedOperationException("may not be cloned");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,15 +93,29 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
|
|||
return Address.class;
|
||||
}
|
||||
|
||||
private long getImageBaseAdjustment(Program program) {
|
||||
Long originalimageBase = ElfLoader.getElfOriginalImageBase(program);
|
||||
if (originalimageBase != null) {
|
||||
return program.getImageBase().getOffset() - originalimageBase;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(MemBuffer buf, Settings settings, int length) {
|
||||
Scalar s = (Scalar) super.getValue(buf, settings, length);
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
long imageBaseAdj = 0;
|
||||
Memory mem = buf.getMemory();
|
||||
if (mem != null) {
|
||||
imageBaseAdj = getImageBaseAdjustment(mem.getProgram());
|
||||
}
|
||||
|
||||
// assume pointer into physical space associated with buf
|
||||
AddressSpace space = buf.getAddress().getAddressSpace().getPhysicalSpace();
|
||||
return space.getAddress(s.getUnsignedValue() + baseOffset);
|
||||
return space.getAddress(s.getSignedValue() + baseOffset + imageBaseAdj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,7 +132,7 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
|
|||
b.append(" + ");
|
||||
}
|
||||
b.append("0x");
|
||||
b.append(Long.toHexString(s.getUnsignedValue()));
|
||||
b.append(Long.toHexString(s.getSignedValue()));
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
@ -122,12 +144,4 @@ class AndroidElfRelocationOffset extends AbstractLeb128DataType {
|
|||
return relocationOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the computed relocation offset location associated with this
|
||||
* component.
|
||||
* @param relocationOffset stashed relocation offset
|
||||
*/
|
||||
void setRelocationOffset(long relocationOffset) {
|
||||
this.relocationOffset = relocationOffset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,12 +205,15 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
|
|||
|
||||
try {
|
||||
int relocationIndex = 0;
|
||||
long remainingRelocations = LEB128.readAsLong(reader, true);
|
||||
long offset = LEB128.readAsLong(reader, true);
|
||||
long addend = 0;
|
||||
long remainingRelocations = LEB128.readAsLong(reader, true); // reloc_count
|
||||
long offset = LEB128.readAsLong(reader, true); // reloc_baseOffset
|
||||
|
||||
while (remainingRelocations > 0) {
|
||||
|
||||
// start new group
|
||||
long addend = 0;
|
||||
|
||||
// group_size
|
||||
long groupSize = LEB128.readAsLong(reader, true);
|
||||
if (groupSize > remainingRelocations) {
|
||||
Msg.warn(this, "Group relocation count " + groupSize +
|
||||
|
@ -218,6 +221,7 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
|
|||
break;
|
||||
}
|
||||
|
||||
// group_flags
|
||||
long groupFlags = LEB128.readAsLong(reader, true);
|
||||
boolean groupedByInfo =
|
||||
(groupFlags & AndroidElfRelocationGroup.RELOCATION_GROUPED_BY_INFO_FLAG) != 0;
|
||||
|
@ -228,34 +232,36 @@ public class ElfRelocationTable implements ElfFileSection, ByteArrayConverter {
|
|||
boolean groupHasAddend =
|
||||
(groupFlags & AndroidElfRelocationGroup.RELOCATION_GROUP_HAS_ADDEND_FLAG) != 0;
|
||||
|
||||
// group_offsetDelta (optional)
|
||||
long groupOffsetDelta = groupedByDelta ? LEB128.readAsLong(reader, true) : 0;
|
||||
|
||||
// group_info (optional)
|
||||
long groupRInfo = groupedByInfo ? LEB128.readAsLong(reader, true) : 0;
|
||||
|
||||
if (groupedByAddend && groupHasAddend) {
|
||||
// group_addend (optional)
|
||||
addend += LEB128.readAsLong(reader, true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < groupSize; i++) {
|
||||
// reloc_offset (optional)
|
||||
offset += groupedByDelta ? groupOffsetDelta : LEB128.readAsLong(reader, true);
|
||||
|
||||
// reloc_info (optional)
|
||||
long info = groupedByInfo ? groupRInfo : LEB128.readAsLong(reader, true);
|
||||
|
||||
long rAddend = 0;
|
||||
if (groupHasAddend) {
|
||||
if (!groupedByAddend) {
|
||||
// reloc_addend (optional)
|
||||
addend += LEB128.readAsLong(reader, true);
|
||||
}
|
||||
rAddend = addend;
|
||||
}
|
||||
|
||||
relocations.add(ElfRelocation.createElfRelocation(reader.getFactory(),
|
||||
elfHeader, relocationIndex++, addendTypeReloc, offset, info, rAddend));
|
||||
}
|
||||
|
||||
if (!groupHasAddend) {
|
||||
addend = 0;
|
||||
}
|
||||
|
||||
remainingRelocations -= groupSize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ public class ARM_ElfRelocationHandler extends ElfRelocationHandler {
|
|||
return elf.e_machine() == ElfConstants.EM_ARM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelrRelocationType() {
|
||||
return ARM_ElfRelocationConstants.R_ARM_RELATIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation,
|
||||
Address relocationAddress) throws MemoryAccessException, NotFoundException {
|
||||
|
|
Loading…
Reference in New Issue
Block a user