diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/AndroidElfRelocationGroup.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/AndroidElfRelocationGroup.java index ed06f1eb01..295b881ebb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/AndroidElfRelocationGroup.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/AndroidElfRelocationGroup.java @@ -15,9 +15,8 @@ */ package ghidra.app.util.bin.format.elf; -import java.util.ArrayList; - import java.io.IOException; +import java.util.ArrayList; import javax.help.UnsupportedOperationException; @@ -177,7 +176,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(); - return baseRelocOffset + ((groupSize - 1) * groupOffsetDelta); + return baseRelocOffset + (groupSize * groupOffsetDelta); } if (lastDtc.getFieldName().startsWith("group_")) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocationTable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocationTable.java index 97e8e42e76..f534b2e6c4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocationTable.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfRelocationTable.java @@ -229,6 +229,11 @@ public class ElfRelocationTable implements ElfFileSection { long groupRInfo = groupedByInfo ? reader.readNext(LEB128::signed) : 0; if (groupHasAddend && groupedByAddend) { + if (!addendTypeReloc) { + elfHeader.logError( + "ELF Android Relocation processing failed. Unexpected r_addend in android.rel section"); + return List.of(); + } // group_addend (optional) addend += reader.readNext(LEB128::signed); } @@ -236,16 +241,16 @@ public class ElfRelocationTable implements ElfFileSection { addend = 0; } + // Process all group entries for (int i = 0; i < groupSize; i++) { // reloc_offset (optional) - offset += - groupedByDelta ? groupOffsetDelta : reader.readNext(LEB128::signed); + offset += groupedByDelta ? groupOffsetDelta : reader.readNext(LEB128::signed); // reloc_info (optional) long info = groupedByInfo ? groupRInfo : reader.readNext(LEB128::signed); long rAddend = 0; - if (groupHasAddend) { + if (addendTypeReloc && groupHasAddend) { if (!groupedByAddend) { // reloc_addend (optional) addend += reader.readNext(LEB128::signed); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractLeb128DataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractLeb128DataType.java index cfc671ed88..0f6ca81994 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractLeb128DataType.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractLeb128DataType.java @@ -95,7 +95,7 @@ public abstract class AbstractLeb128DataType extends BuiltIn implements Dynamic } // approximate bitLength from storage byte length - int bitLength = Math.max(64, len * 7); + int bitLength = Math.min(64, len * 7); int mod = bitLength % 8; if (mod != 0) { bitLength += (8 - mod);