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 long entry = elf.e_entry(); // already adjusted for pre-link
if (entry != 0 && (elf.isExecutable() || elf.isSharedObject())) { if (entry != 0 && (elf.isExecutable() || elf.isSharedObject())) {
Address entryAddr = Address entryAddr = createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry);
createEntryFunction(ElfLoader.ELF_ENTRY_FUNCTION_NAME, entry);
if (entryAddr != null) { if (entryAddr != null) {
addElfHeaderReferenceMarkup(elf.getEntryComponentOrdinal(), entryAddr); addElfHeaderReferenceMarkup(elf.getEntryComponentOrdinal(), entryAddr);
Function entryFunc = program.getFunctionManager().getFunctionAt(entryAddr); Function entryFunc = program.getFunctionManager().getFunctionAt(entryAddr);
@ -996,6 +995,9 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
int symbolIndex = reloc.getSymbolIndex(); int symbolIndex = reloc.getSymbolIndex();
String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : ""; String symbolName = symbolTable != null ? symbolTable.getSymbolName(symbolIndex) : "";
if (symbolName != null && isUnsupportedASCIISymbolName(symbolName)) {
symbolName = getEscapedSymbolName(symbolName);
}
Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true); Address baseAddress = relocationSpace.getTruncatedAddress(baseWordOffset, true);
@ -1116,9 +1118,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
hasConflict = nextRelocAddr != null && nextRelocAddr.compareTo(maxAddr) <= 0; hasConflict = nextRelocAddr != null && nextRelocAddr.compareTo(maxAddr) <= 0;
} }
if (hasConflict) { if (hasConflict) {
Msg.warn(this, Msg.warn(this, "Artificial relocation for " + address +
"Artificial relocation for " + address + " conflicts with a previous relocation");
" conflicts with a previous relocation");
} }
relocationTable.add(address, Status.APPLIED_OTHER, 0, null, length, null); relocationTable.add(address, Status.APPLIED_OTHER, 0, null, length, null);
return true; return true;
@ -2093,6 +2094,12 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
isPrimary = (existingSym == null); 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); createSymbol(address, name, isPrimary, elfSymbol.isAbsolute(), null);
// NOTE: treat weak symbols as global so that other programs may link to them. // 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 @Override
public void setElfSymbolAddress(ElfSymbol elfSymbol, Address address) { public void setElfSymbolAddress(ElfSymbol elfSymbol, Address address) {
symbolMap.put(elfSymbol, address); symbolMap.put(elfSymbol, address);
@ -3627,14 +3667,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
// Msg.debug(this, // Msg.debug(this,
// "Loading block " + name + " at " + start + " from file offset " + fileOffset); // "Loading block " + name + " at " + start + " from file offset " + fileOffset);
long compSectOrigSize = loadable instanceof ElfSectionHeader header && header.isCompressed() long compSectOrigSize =
? header.getSize() loadable instanceof ElfSectionHeader header && header.isCompressed() ? header.getSize()
: -1; : -1;
String blockComment = comment; String blockComment = comment;
if (compSectOrigSize >= 0) { if (compSectOrigSize >= 0) {
blockComment += blockComment += " (decompressed, original length: 0x%x)".formatted(compSectOrigSize);
" (decompressed, original length: 0x%x)".formatted(compSectOrigSize);
} }
else if ((fileOffset + revisedLength - 1) >= fileBytes.getSize()) { else if ((fileOffset + revisedLength - 1) >= fileBytes.getSize()) {
// ensure valid length for non-compressed items // ensure valid length for non-compressed items
@ -3650,15 +3689,13 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
try { try {
if (loadable != null && loadable.hasFilteredLoadInputStream(this, start)) { if (loadable != null && loadable.hasFilteredLoadInputStream(this, start)) {
// block is unable to map directly to file bytes - load from input stream // block is unable to map directly to file bytes - load from input stream
try (InputStream is = try (InputStream is = loadable.getFilteredLoadInputStream(this, start,
loadable.getFilteredLoadInputStream(this, start, revisedLength, revisedLength, (errorMsg, th) -> {
(errorMsg, th) -> { String loadableTypeStr = compSectOrigSize >= 0 ? "compressed section " : "";
String loadableTypeStr = log.appendMsg("Error when reading %s[%s]: %s".formatted(loadableTypeStr,
compSectOrigSize >= 0 ? "compressed section " : ""; name, errorMsg));
log.appendMsg("Error when reading %s[%s]: %s".formatted(loadableTypeStr, Msg.error(this, errorMsg, th);
name, errorMsg)); })) {
Msg.error(this, errorMsg, th);
})) {
block = MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start, block = MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start,
is, revisedLength, blockComment, BLOCK_SOURCE_NAME, r, w, x, log, monitor); is, revisedLength, blockComment, BLOCK_SOURCE_NAME, r, w, x, log, monitor);
} }
@ -3673,8 +3710,8 @@ class ElfProgramBuilder extends MemorySectionResolver implements ElfLoadHelper {
finally { finally {
if (block == null) { if (block == null) {
Address end = start.addNoWrap(revisedLength - 1); Address end = start.addNoWrap(revisedLength - 1);
log("Unexpected ELF memory block load conflict when creating '" + name + log("Unexpected ELF memory block load conflict when creating '" + name + "' at " +
"' at " + start.toString(true) + "-" + end.toString(true)); start.toString(true) + "-" + end.toString(true));
} }
} }
return block; return block;