GP-5969: Updated vxWorks symbol table finding script to better filter

out runs of pointers to locate the table, deleted old scripts, and fixed
de-mangling and labeling issues.
This commit is contained in:
emteere
2025-09-05 18:21:47 +00:00
committed by Ryan Kurtz
parent 58ca21b8db
commit 6d588dab00
3 changed files with 66 additions and 576 deletions

View File

@@ -39,24 +39,25 @@
// - Modify getVxSymbolClass() to recognize your program's VxWorks
// symbol table entry structure, if necessary
//
// @category Customer Submission.vxWorks
// @category VxWorks
import java.util.List;
import ghidra.app.cmd.data.CreateDataCmd;
import ghidra.app.cmd.disassemble.DisassembleCommand;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.demangler.DemangledException;
import ghidra.app.util.demangler.MangledContext;
import ghidra.app.util.PseudoDisassembler;
import ghidra.app.util.demangler.*;
import ghidra.app.util.demangler.gnu.GnuDemangler;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.*;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.*;
import ghidra.program.model.util.CodeUnitInsertionException;
public class VxWorksSymTab_Finder extends GhidraScript {
@@ -86,7 +87,8 @@ public class VxWorksSymTab_Finder extends GhidraScript {
private int getFieldOffset(StructureDataType dataType, String name) {
for (DataTypeComponent comp : dataType.getComponents()) {
if (comp.getFieldName().equals(name)) {
String fieldName = comp.getFieldName();
if (name.equals(fieldName)) {
return comp.getOffset();
}
}
@@ -430,9 +432,14 @@ public class VxWorksSymTab_Finder extends GhidraScript {
// return false;
//}
// symType field must be recognized type code (this test is weak)
// symType field must be recognized type code
byte symType = getByte(entry.add(vxSymbol.typeOffset()));
if (!isValidSymType(symType)) {
byte zeroByte = 0;
if (vxSymbol.typeOffset+1 <= vxSymbol.length()) {
// type is always at end of symbol entry, if padded make sure is zero
zeroByte = getByte(entry.add(vxSymbol.typeOffset()+1));
}
if (!isValidSymType(symType) || zeroByte != 0) {
if (debug) {
println("5: " + entry + " --> " + symType);
}
@@ -454,50 +461,20 @@ public class VxWorksSymTab_Finder extends GhidraScript {
case 9: // Global BSS
case 4: // Local .text
case 5: // Global .text
case 0x11: // External ref
case 0x10: // Local BSS 6.8
case 0x11: // Global BSS 6.8
case 0x12: // Local Common
case 0x13: // Global Common
case 0x20: // Local Common 6.8
case 0x21: // Global Common 6.8
case 0x40: // Local Symbols 6.8
case 0x41: // Global Symbols 6.8
return true;
default:
return false;
}
}
//------------------------------------------------------------------------
// isStringPointerTable
//
// Check to see if the candidate symbol table is just a string pointer
// table.
//------------------------------------------------------------------------
private boolean isStringPointerTable(Address offset, int table_size) throws Exception {
if (debug) {
printf("Checking for string pointer table at 0x%x\n", offset.getOffset());
}
// Skip the first offset in the table because it can be null as a symbol table
Address cursor = offset.add(4);
long end = offset.add(table_size).getOffset();
while (cursor.getOffset() < end) {
long value = getInt(cursor) & 0xffffffffL;
if (isAddress(value)) {
if (!isValidSymbolString(toAddr(value))) {
if (debug) {
printf("Found non-string pointer in table at 0x%x (0x%x)\n",
cursor.getOffset(), value);
}
return false;
}
cursor = cursor.add(4);
}
else {
if (debug) {
printf("Found non-address in table at 0x%x", cursor.getOffset());
}
return false;
}
}
return true;
}
//------------------------------------------------------------------------
// findSymTbl
//
@@ -556,25 +533,13 @@ public class VxWorksSymTab_Finder extends GhidraScript {
}
if (i == testLen) {
// May have symbol table -- verify length
int table_size = vxSymbol.length() * i;
if (!isStringPointerTable(cursor, table_size)) {
if (getSymTblLen(cursor, vxSymbol) != 0) {
printf("\n");
System.out.flush();
return cursor; // found table -- stop searching
}
if (debug) {
printf("Possible symbol table at " + cursor + " has length error\n");
}
if (getSymTblLen(cursor, vxSymbol) != 0) {
printf("\n");
System.out.flush();
return cursor; // found table -- stop searching
}
else {
if (debug) {
printf("False-positive: String pointer table at %s, skipping\n",
cursor.toString());
}
cursor = cursor.add(table_size);
continue;
if (debug) {
printf("Possible symbol table at " + cursor + " has length error\n");
}
}
@@ -659,7 +624,12 @@ public class VxWorksSymTab_Finder extends GhidraScript {
if (symTblLenPtr != null) {
removeConflictingSymbols("vxSymTblLen", symTblLenPtr);
createLabel(symTblLenPtr, "vxSymTblLen", true);
createDWord(symTblLenPtr);
CreateDataCmd dtCmd = new CreateDataCmd(symTblLenPtr, false, DWordDataType.dataType);
boolean created = dtCmd.applyTo(currentProgram);
if (!created) {
println("Warning: Symbol Table size could not be created");
}
}
else {
println("Warning: Symbol Table Size not found before of after table");
@@ -695,12 +665,11 @@ public class VxWorksSymTab_Finder extends GhidraScript {
private void applyDemangled(Address addr, String mangled, String demangled) {
if (demangled != null) {
new DemanglerCmd(addr, mangled).applyTo(currentProgram, monitor);
List<Symbol> symbols =
getSymbols(mangled, currentProgram.getGlobalNamespace());
if (!symbols.isEmpty()) {
currentProgram.getSymbolTable().removeSymbolSpecial(symbols.get(0));
}
DemanglerOptions options = new DemanglerOptions();
options.setApplySignature(true);
options.setApplyCallingConvention(true);
options.setDemangleOnlyKnownPatterns(false);
new DemanglerCmd(addr, mangled, options).applyTo(currentProgram, monitor);
}
return;
@@ -714,11 +683,22 @@ public class VxWorksSymTab_Finder extends GhidraScript {
// allows auto-analysis to operate with more information (and code/data
// that isn't rapidly changing).
//------------------------------------------------------------------------
private void doLocalDisassemble(Address addr) {
private boolean doLocalDisassemble(Address addr) {
// Only disassemble in memory blocks marked executable
if (!isExecute(addr)) {
return;
return false;
}
PseudoDisassembler pdis = new PseudoDisassembler(currentProgram);
pdis.setMaxInstructions(20);
if (!pdis.checkValidSubroutine(addr, true, false, true)) {
return false;
}
// must be at least 2 contiguous instructions
if (pdis.getLastCheckValidInstructionCount()<2) {
return false;
}
DisassembleCommand cmd = new DisassembleCommand(addr, null, true);
@@ -728,7 +708,7 @@ public class VxWorksSymTab_Finder extends GhidraScript {
AddressSet set = cmd.getDisassembledAddressSet();
AutoAnalysisManager.getAnalysisManager(currentProgram).codeDefined(set);
return;
return true;
}
//------------------------------------------------------------------------
@@ -764,6 +744,8 @@ public class VxWorksSymTab_Finder extends GhidraScript {
int symTblLen = getSymTblLen(symTbl, vxSymbol);
println("Symbol table at " + symTbl + " (" + symTblLen + " entries)");
currentProgram.getOptions(Program.PROGRAM_INFO).setString("Framework", "vxWorks");
// Name the VxWorks symbol table
removeConflictingSymbols("vxSymTbl", symTbl);
createLabel(symTbl, "vxSymTbl", true);
@@ -836,9 +818,6 @@ public class VxWorksSymTab_Finder extends GhidraScript {
symType + ", name: " + symName);
}
// Clear any conflicting symbols from the Ghidra symbol table
removeConflictingSymbols(symName, symLoc);
// If entry type is data, simply create a Ghidra symbol for it.
// If entry type is code, disassemble it and create function.
switch (symType) {
@@ -855,27 +834,26 @@ public class VxWorksSymTab_Finder extends GhidraScript {
case 9: // Global BSS
case 0x11: // External ref
createLabel(symLoc, symName, true);
createLabel(symLoc, symName, true, SourceType.IMPORTED);
applyDemangled(symLoc, symName, symDemangledName);
break;
case 4: // Local .text
case 5: // Global .text
doLocalDisassemble(symLoc);
createFunction(symLoc, symName);
if (getFunctionAt(symLoc) != null) {
getFunctionAt(symLoc).setName(symName, SourceType.USER_DEFINED);
applyDemangled(symLoc, symName, symDemangledName);
}
else {
println("createFunction: Failed to create function");
createLabel(symLoc, symName, true);
applyDemangled(symLoc, symName, symDemangledName);
createLabel(symLoc, symName, true, SourceType.IMPORTED);
boolean isCode = doLocalDisassemble(symLoc);
if (isCode) {
Function function = createFunction(symLoc, symName);
if (function == null) {
println("createFunction: Failed to create function " + symLoc);
}
}
applyDemangled(symLoc, symName, symDemangledName);
break;
default:
createLabel(symLoc, symName, true, SourceType.IMPORTED);
println("Invalid symType " + symType + " !");
break;
}