mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-23 13:41:04 +00:00
GP-4202 corrected ELF PT_NOTE processing issue
This commit is contained in:
parent
86da74d01a
commit
68dc53768c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user