GP-3793 escape non-ASCII symbols during ELF Import

This commit is contained in:
ghidra1 2023-08-28 13:19:40 -04:00
parent 92280f8bc3
commit 9a23f2f788

View file

@ -649,8 +649,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
long entry = elf.e_entry(); // already adjusted for pre-link
if (entry != 0 && (elf.isExecutable() || elf.isSharedObject())) {
Address entryAddr =
createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry);
Address entryAddr = createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry);
if (entryAddr != null) {
addElfHeaderReferenceMarkup(elf.getEntryComponentOrdinal(), entryAddr);
Function entryFunc = program.getFunctionManager().getFunctionAt(entryAddr);
@ -765,7 +764,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
createEntryFunction(name, entryAddress);
return entryAddress;
}
/**
* Attempt to create an entry point function.
* Note: entries in the dynamic table appear to have any pre-link adjustment already applied.
@ -778,7 +777,7 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
MemoryBlock block = memory.getBlock(entryAddress);
if (block == null || !block.isExecute()) {
return;
return;
}
entryAddress = elf.getLoadAdapter().creatingFunction(this, entryAddress);
@ -996,6 +995,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
int symbolIndex = reloc.getSymbolIndex();
String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : "";
if (symbolName != null && isUnsupportedASCIISymbolName(symbolName)) {
symbolName = getEscapedSymbolName(symbolName);
}
Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true);
@ -1116,9 +1118,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
hasConflict = nextRelocAddr != null && nextRelocAddr.compareTo(maxAddr) <= 0;
}
if (hasConflict) {
Msg.warn(this,
"Artificial relocation for " + address +
" conflicts with a previous relocation");
Msg.warn(this, "Artificial relocation for " + address +
" conflicts with a previous relocation");
}
relocationTable.add(address, Status.APPLIED_OTHER, 0, null, length, null);
return true;
@ -2093,6 +2094,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
isPrimary = (existingSym == null);
}
if (name != null && isUnsupportedASCIISymbolName(name)) {
String escapedName = getEscapedSymbolName(name);
log("Unsupported ASCII symbol name has been escaped: \"" + escapedName + "\"");
name = escapedName;
}
createSymbol(address, name, isPrimary, elfSymbol.isAbsolute(), null);
// NOTE: treat weak symbols as global so that other programs may link to them.
@ -2127,6 +2134,39 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
}
}
private boolean isUnsupportedASCIISymbolName(String name) {
for (char c : name.toCharArray()) {
if (!StringUtilities.isAsciiChar(c) || c == ' ') {
return true;
}
}
return false;
}
private String getEscapedSymbolName(String name) {
StringBuilder escapedBuf = new StringBuilder();
for (char c : name.toCharArray()) {
if (c < 0 || c > 0x7f) {
// format non-ASCII as escaped numeric hex value \xNN
escapedBuf.append("\\x%02x".formatted((int) c));
}
else if (c < ' ') {
// format as ^Control character for consistency with readelf
c += 64; // get ASCII control character, starts with ^@
escapedBuf.append('^');
escapedBuf.append(c);
}
else if (c == 0x7f) {
// format as ^? character for consistency with readelf
escapedBuf.append("^?");
}
else {
escapedBuf.append(c);
}
}
return escapedBuf.toString();
}
@Override
public void setElfSymbolAddress(ElfSymbol elfSymbol, Address address) {
symbolMap.put(elfSymbol, address);
@ -3627,14 +3667,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
// Msg.debug(this,
// "Loading block " + name + " at " + start + " from file offset " + fileOffset);
long compSectOrigSize = loadable instanceof ElfSectionHeader header && header.isCompressed()
? header.getSize()
: -1;
long compSectOrigSize =
loadable instanceof ElfSectionHeader header && header.isCompressed() ? header.getSize()
: -1;
String blockComment = comment;
if (compSectOrigSize >= 0) {
blockComment +=
" (decompressed, original length: 0x%x)".formatted(compSectOrigSize);
blockComment += " (decompressed, original length: 0x%x)".formatted(compSectOrigSize);
}
else if ((fileOffset + revisedLength - 1) >= fileBytes.getSize()) {
// ensure valid length for non-compressed items
@ -3650,15 +3689,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
try {
if (loadable != null && loadable.hasFilteredLoadInputStream(this, start)) {
// block is unable to map directly to file bytes - load from input stream
try (InputStream is =
loadable.getFilteredLoadInputStream(this, start, revisedLength,
(errorMsg, th) -> {
String loadableTypeStr =
compSectOrigSize >= 0 ? "compressed section " : "";
log.appendMsg("Error when reading %s[%s]: %s".formatted(loadableTypeStr,
name, errorMsg));
Msg.error(this, errorMsg, th);
})) {
try (InputStream is = loadable.getFilteredLoadInputStream(this, start,
revisedLength, (errorMsg, th) -> {
String loadableTypeStr = compSectOrigSize >= 0 ? "compressed section " : "";
log.appendMsg("Error when reading %s[%s]: %s".formatted(loadableTypeStr,
name, errorMsg));
Msg.error(this, errorMsg, th);
})) {
block = MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start,
is, revisedLength, blockComment, BLOCK_SOURCE_NAME, r, w, x, log, monitor);
}
@ -3673,8 +3710,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
finally {
if (block == null) {
Address end = start.addNoWrap(revisedLength - 1);
log("Unexpected ELF memory block load conflict when creating '" + name +
"' at " + start.toString(true) + "-" + end.toString(true));
log("Unexpected ELF memory block load conflict when creating '" + name + "' at " +
start.toString(true) + "-" + end.toString(true));
}
}
return block;