GP-4202 corrected ELF PT_NOTE processing issue

This commit is contained in:
ghidra1 2023-11-14 18:42:03 -05:00
parent 86da74d01a
commit 68dc53768c
2 changed files with 58 additions and 38 deletions

View File

@ -23,6 +23,7 @@ import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.bin.format.elf.info.ElfInfoItem.ReaderFunc;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.data.*;
import ghidra.program.model.data.DataUtilities.ClearDataMode;
import ghidra.program.model.listing.CodeUnit;
@ -52,12 +53,12 @@ public class StandardElfInfoProducer implements ElfInfoProducer {
public static final CategoryPath ELF_CATEGORYPATH = new CategoryPath("/ELF");
private static final Map<String, ReaderFunc<ElfInfoItem>> STANDARD_READERS = Map.of(
GnuDebugLink.SECTION_NAME, GnuDebugLink::read,
NoteAbiTag.SECTION_NAME, (br, prg) -> NoteAbiTag.read(ElfNote.read(br), prg),
NoteGnuBuildId.SECTION_NAME, (br, prg) -> NoteGnuBuildId.read(ElfNote.read(br), prg),
NoteGnuProperty.SECTION_NAME, (br, prg) -> NoteGnuProperty.read(ElfNote.read(br), prg),
ElfComment.SECTION_NAME, ElfComment::read);
private static final Map<String, ReaderFunc<ElfInfoItem>> STANDARD_READERS =
Map.of(GnuDebugLink.SECTION_NAME, GnuDebugLink::read, NoteAbiTag.SECTION_NAME,
(br, prg) -> NoteAbiTag.read(ElfNote.read(br), prg), NoteGnuBuildId.SECTION_NAME,
(br, prg) -> NoteGnuBuildId.read(ElfNote.read(br), prg), NoteGnuProperty.SECTION_NAME,
(br, prg) -> NoteGnuProperty.read(ElfNote.read(br), prg), ElfComment.SECTION_NAME,
ElfComment::read);
private ElfLoadHelper elfLoadHelper;
@ -78,10 +79,10 @@ public class StandardElfInfoProducer implements ElfInfoProducer {
ElfInfoItem.markupElfInfoItemSection(program, sectionName, readFunc);
}
markupPTNOTESections(monitor);
markupPtNoteSegments(monitor);
}
private void markupPTNOTESections(TaskMonitor monitor) throws CancelledException {
private void markupPtNoteSegments(TaskMonitor monitor) throws CancelledException {
Program program = elfLoadHelper.getProgram();
Memory memory = program.getMemory();
for (ElfProgramHeader elfProgramHeader : elfLoadHelper.getElfHeader()
@ -90,43 +91,63 @@ public class StandardElfInfoProducer implements ElfInfoProducer {
Address addr = elfLoadHelper.findLoadAddress(elfProgramHeader, 0);
if (addr == null) {
elfLoadHelper.log("Failed to identify PT_NOTE load address");
continue;
}
MemoryBlock memBlock = memory.getBlock(addr);
if (memBlock == null) {
continue;
}
try (ByteProvider bp =
MemoryByteProvider.createMemoryBlockByteProvider(program.getMemory(), memBlock)) {
BinaryReader br = new BinaryReader(bp, !program.getMemory().isBigEndian());
while (br.hasNext()) {
monitor.checkCancelled();
long start = br.getPointerIndex();
ElfNote note = br.readNext(ElfNote::read);
br.align(4); // fix any notes with non-aligned size payloads
long noteLength = br.getPointerIndex() - start;
try {
StructureDataType struct = note.toStructure(program.getDataTypeManager());
DataUtilities.createData(program, addr, struct, -1, false,
ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA);
String comment =
"ELF Note \"%s\", %xh".formatted(note.getName(), note.getVendorType());
program.getListing().setComment(addr, CodeUnit.EOL_COMMENT, comment);
}
catch (CodeUnitInsertionException e) {
// ignore, continue to next note
try {
Address endAddr = null;
MemoryBlock memBlock = memory.getBlock(addr);
if (memBlock != null) {
long loadSize = elfProgramHeader.getAdjustedLoadSize();
if (loadSize > 0) {
endAddr = addr.add(loadSize - 1);
}
}
addr = addr.addWrap(noteLength);
if (endAddr == null) {
elfLoadHelper.log("Failed to markup non-loaded PT_NOTE at " + addr);
continue;
}
try (ByteProvider bp = new MemoryByteProvider(program.getMemory(), addr, endAddr)) {
BinaryReader br = new BinaryReader(bp, !program.getMemory().isBigEndian());
markupPtNote(br, program, addr, monitor);
}
}
catch (IOException e) {
Msg.warn(this, "Failed to read ELF Note at %s".formatted(addr), e);
catch (Exception e) {
// NOTE: There are some unsupported formats which may throw severe exceptions
elfLoadHelper.log("Failed to parse and markup ELF Note starting at " + addr);
}
}
}
private void markupPtNote(BinaryReader br, Program program, Address noteAddr,
TaskMonitor monitor)
throws CancelledException, AddressOutOfBoundsException, IOException {
while (br.hasNext()) {
monitor.checkCancelled();
long start = br.getPointerIndex();
ElfNote note = br.readNext(ElfNote::read);
br.align(4); // fix any notes with non-aligned size payloads
long noteLength = br.getPointerIndex() - start;
try {
StructureDataType struct = note.toStructure(program.getDataTypeManager());
DataUtilities.createData(program, noteAddr, struct, -1, false,
ClearDataMode.CLEAR_ALL_UNDEFINED_CONFLICT_DATA);
String comment =
"ELF Note \"%s\", %xh".formatted(note.getName(), note.getVendorType());
program.getListing().setComment(noteAddr, CodeUnit.EOL_COMMENT, comment);
}
catch (CodeUnitInsertionException e) {
elfLoadHelper.log("Failed to markup ELF Note at " + noteAddr + ": data conflict");
}
noteAddr = noteAddr.add(noteLength);
}
}
}

View File

@ -38,7 +38,7 @@ public class Relocation {
UNKNOWN(0, true),
/**
* Relocation has be intentionally skipped and should not be treated as a failure.
* Relocation has been intentionally skipped and should not be treated as a failure.
*/
SKIPPED(1, false),
@ -105,8 +105,7 @@ public class Relocation {
return s;
}
}
throw new IllegalArgumentException(
"Undefined Status value: " + value);
throw new IllegalArgumentException("Undefined Status value: " + value);
}
}