mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 01:39:21 +02:00
Merge branch 'GP-5969_VxWorksTableIDFix'
This commit is contained in:
commit
4f164e68a6
3 changed files with 66 additions and 576 deletions
|
@ -1,246 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// VxWorksSymTab_5_4 is a copy of VxWorksSymTab_6_1 with a different value for SYM_ENTRY_SIZE
|
||||
// It was replaced at the request of a customer who tested that it worked with the slight modification
|
||||
// VxWorksSymTab_6_1 is an adaptation of the vxWorksSymTab script. It was modified by a customer
|
||||
// to use a single loop, instead of two. It also added demangling of C++ symbol names - at least
|
||||
// those that Ghidra knows how to demangle.
|
||||
//
|
||||
// Extracts all symbols in a VxWorks symbol table and disassembles
|
||||
// the global functions. Any existing symbols in the Ghidra symbol table
|
||||
// that collide with symbols defined in the VxWorks symbol table are deleted.
|
||||
//
|
||||
// The VxWorks symbol table is an array of symbol table entries [0..n-1]
|
||||
// followed by a 32-bit value that is equal to n (number of sym tbl entries).
|
||||
// Each entry in the array has the following structure:
|
||||
//
|
||||
// // Total size: 0x18 (24) bytes
|
||||
// 0x00 int NULL
|
||||
// 0x04 char *symNameAddr // symbol name
|
||||
// 0x08 void *symLocAddr // location of object named by symbol
|
||||
// 0x0c int NULL
|
||||
// 0x10 int NULL
|
||||
// 0x14 uchar symType // see switch statement below
|
||||
// 0x15 uchar fill[3]
|
||||
//
|
||||
// The script requests:
|
||||
// - Output file name: Each symbol name and address is recorded here.
|
||||
// (Errors are also logged to this file.)
|
||||
// - Address of "number of symbols" value: At the end of the symbol table,
|
||||
// its length is recorded as a 32-bit integer. The
|
||||
// script needs the address of that value to calculate
|
||||
// the symbol table's start address.
|
||||
//
|
||||
// @category Customer Submission.vxWorks
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.cmd.label.DemanglerCmd;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.demangler.DemangledException;
|
||||
import ghidra.app.util.demangler.MangledContext;
|
||||
import ghidra.app.util.demangler.gnu.GnuDemangler;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
||||
public class VxWorksSymTab_5_4 extends GhidraScript {
|
||||
|
||||
static final int SYM_ENTRY_SIZE = 16;
|
||||
static final int SYM_NAME_OFF = 4;
|
||||
static final int SYM_LOC_OFF = 8;
|
||||
static final int SYM_TYPE_OFF = 0x14;
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
|
||||
// Get Memory and SymbolTable objects (used later)
|
||||
Memory mem = currentProgram.getMemory();
|
||||
SymbolTable ghidraSymTbl = currentProgram.getSymbolTable();
|
||||
|
||||
// Open output file
|
||||
// All symbols found (address and name) will be logged to this file
|
||||
try (PrintWriter output =
|
||||
new PrintWriter(new FileOutputStream(askFile("vxWorks Symbol Table Parser",
|
||||
"Output file name?")))) {
|
||||
|
||||
// Get address of "total number of sym tbl entries" value
|
||||
Address vxNumSymEntriesAddr =
|
||||
askAddress("vxWorks Symbol Table Parser",
|
||||
"Address of \"total number of symbol table entries\" value?");
|
||||
int vxNumSymEntries = mem.getInt(vxNumSymEntriesAddr);
|
||||
println("VxWorks symbol table has " + vxNumSymEntries + " entries");
|
||||
|
||||
// Create a GNU demangler instance
|
||||
GnuDemangler demangler = new GnuDemangler();
|
||||
if (!demangler.canDemangle(currentProgram)) {
|
||||
println("Unable to create demangler.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Process entries in VxWorks symbol table
|
||||
Address vxSymTbl = vxNumSymEntriesAddr.subtract(vxNumSymEntries * SYM_ENTRY_SIZE);
|
||||
for (int i = 0; i < vxNumSymEntries; i++) {
|
||||
|
||||
if (monitor.isCancelled()) {
|
||||
return; // check for cancel button
|
||||
}
|
||||
println("i=" + i); // visual counter
|
||||
|
||||
// Extract symbol table entry values
|
||||
Address symEntry = vxSymTbl.add(i * SYM_ENTRY_SIZE);
|
||||
Address symNameAddr = toAddr(mem.getInt(symEntry.add(SYM_NAME_OFF)));
|
||||
Address symLocAddr = toAddr(mem.getInt(symEntry.add(SYM_LOC_OFF)));
|
||||
byte symType = mem.getByte(symEntry.add(SYM_TYPE_OFF));
|
||||
println("symNameAddr: 0x" + symNameAddr.toString() + ", symLocAddr: 0x" +
|
||||
symLocAddr.toString() + ", symType: " + symType);
|
||||
|
||||
// Remove any data or instructions that overlap this symName
|
||||
// (May happen if disassembly creates invalid references)
|
||||
Address a;
|
||||
String symName;
|
||||
for (a = symNameAddr; mem.getByte(a) != 0; a = a.add(1)) {
|
||||
if (getDataAt(a) != null) {
|
||||
removeDataAt(a);
|
||||
}
|
||||
if (getInstructionAt(a) != null) {
|
||||
removeInstructionAt(a);
|
||||
}
|
||||
}
|
||||
if (getDataAt(a) != null) {
|
||||
removeDataAt(a);
|
||||
}
|
||||
if (getInstructionAt(a) != null) {
|
||||
removeInstructionAt(a);
|
||||
}
|
||||
|
||||
// Turn *symNameAddr into a string and store it in symName
|
||||
try {
|
||||
symName = (String) createAsciiString(symNameAddr).getValue();
|
||||
}
|
||||
catch (Exception e) {
|
||||
println("createAsciiString: caught exception...");
|
||||
println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
println("symName: " + symName);
|
||||
|
||||
// Demangle symName
|
||||
String symDemangledName = null;
|
||||
try {
|
||||
// if successful, symDemangledName will be non-NULL
|
||||
MangledContext mangledContext = demangler.createMangledContext(symDemangledName,
|
||||
null, currentProgram, symNameAddr);
|
||||
symDemangledName = demangler.demangle(mangledContext).getSignature(false);
|
||||
}
|
||||
catch (DemangledException e) {
|
||||
// if symName wasn't a mangled name, silently continue
|
||||
if (!e.isInvalidMangledName()) {
|
||||
println("demangle: Demangling error");
|
||||
output.println("demangle: Demangling error");
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
println("demangle: Caught runtime exception");
|
||||
output.println("demangle: Caught runtime exception");
|
||||
}
|
||||
if (symDemangledName != null) {
|
||||
println("symDemangledName: " + symDemangledName);
|
||||
}
|
||||
|
||||
// Delete any symbol in the Ghidra symbol table with the same name
|
||||
SymbolIterator syms = ghidraSymTbl.getSymbols(symName);
|
||||
Symbol sym;
|
||||
while (syms.hasNext()) {
|
||||
sym = syms.next();
|
||||
println("Deleting matching Ghidra symbol: " + sym.getName());
|
||||
ghidraSymTbl.removeSymbolSpecial(sym);
|
||||
}
|
||||
|
||||
// Delete any symbol in the Ghidra symbol table at the same address
|
||||
if ((sym = getSymbolAt(symLocAddr)) != null) {
|
||||
println("Deleting symbol at target address: " + sym.getName());
|
||||
ghidraSymTbl.removeSymbolSpecial(sym);
|
||||
}
|
||||
|
||||
switch (symType) {
|
||||
case 0: // Undefined Symbol
|
||||
println("NULL symType!");
|
||||
break;
|
||||
case 2: // Local Absolute
|
||||
case 3: // Global Absolute
|
||||
case 6: // Local Data
|
||||
case 7: // Global Data
|
||||
case 8: // Local BSS
|
||||
case 9: // Global BSS
|
||||
// Data: log the symbol & create a Ghidra symbol at symLocAddr
|
||||
output.println(symLocAddr.toString() + "\t" + symName);
|
||||
createLabel(symLocAddr, symName, true);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram, monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: // Local .text
|
||||
case 5: // Global .text
|
||||
// Code: log the symbol, disassemble, & create/name function
|
||||
output.println(symLocAddr.toString() + "\t" + symName);
|
||||
goTo(symLocAddr);
|
||||
disassemble(symLocAddr);
|
||||
createFunction(symLocAddr, symName);
|
||||
if (getFunctionAt(symLocAddr) != null) {
|
||||
getFunctionAt(symLocAddr).setName(symName, SourceType.USER_DEFINED);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram,
|
||||
monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
println("createFunction: Failed to create function");
|
||||
output.println("createFunction: Failed to create function");
|
||||
createLabel(symLocAddr, symName, true);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram,
|
||||
monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
println("Invalid symType!");
|
||||
break;
|
||||
}
|
||||
|
||||
symEntry = symEntry.add(SYM_ENTRY_SIZE); // goto next entry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// VxWorksSymTab_6_1 is an adaptation of the vxWorksSymTab script. It was modified by a customer
|
||||
// to use a single loop, instead of two. It also added demangling of C++ symbol names - at least
|
||||
// those that Ghidra knows how to demangle.
|
||||
//
|
||||
// Extracts all symbols in a VxWorks symbol table and disassembles
|
||||
// the global functions. Any existing symbols in the Ghidra symbol table
|
||||
// that collide with symbols defined in the VxWorks symbol table are deleted.
|
||||
//
|
||||
// The VxWorks symbol table is an array of symbol table entries [0..n-1]
|
||||
// followed by a 32-bit value that is equal to n (number of sym tbl entries).
|
||||
// Each entry in the array has the following structure:
|
||||
//
|
||||
// // Total size: 0x18 (24) bytes
|
||||
// 0x00 int NULL
|
||||
// 0x04 char *symNameAddr // symbol name
|
||||
// 0x08 void *symLocAddr // location of object named by symbol
|
||||
// 0x0c int NULL
|
||||
// 0x10 int NULL
|
||||
// 0x14 uchar symType // see switch statement below
|
||||
// 0x15 uchar fill[3]
|
||||
//
|
||||
// The script requests:
|
||||
// - Output file name: Each symbol name and address is recorded here.
|
||||
// (Errors are also logged to this file.)
|
||||
// - Address of "number of symbols" value: At the end of the symbol table,
|
||||
// its length is recorded as a 32-bit integer. The
|
||||
// script needs the address of that value to calculate
|
||||
// the symbol table's start address.
|
||||
//
|
||||
// @category Customer Submission.vxWorks
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.cmd.label.DemanglerCmd;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.demangler.DemangledException;
|
||||
import ghidra.app.util.demangler.MangledContext;
|
||||
import ghidra.app.util.demangler.gnu.GnuDemangler;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
||||
public class VxWorksSymTab_6_1 extends GhidraScript {
|
||||
|
||||
static final int SYM_ENTRY_SIZE = 24;
|
||||
static final int SYM_NAME_OFF = 4;
|
||||
static final int SYM_LOC_OFF = 8;
|
||||
static final int SYM_TYPE_OFF = 0x14;
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
|
||||
// Get Memory and SymbolTable objects (used later)
|
||||
Memory mem = currentProgram.getMemory();
|
||||
SymbolTable ghidraSymTbl = currentProgram.getSymbolTable();
|
||||
|
||||
// Open output file
|
||||
// All symbols found (address and name) will be logged to this file
|
||||
try (PrintWriter output = new PrintWriter(
|
||||
new FileOutputStream(askFile("vxWorks Symbol Table Parser", "Output file name?")))) {
|
||||
|
||||
// Get address of "total number of sym tbl entries" value
|
||||
Address vxNumSymEntriesAddr = askAddress("vxWorks Symbol Table Parser",
|
||||
"Address of \"total number of symbol table entries\" value?");
|
||||
int vxNumSymEntries = mem.getInt(vxNumSymEntriesAddr);
|
||||
println("VxWorks symbol table has " + vxNumSymEntries + " entries");
|
||||
|
||||
// Create a GNU demangler instance
|
||||
GnuDemangler demangler = new GnuDemangler();
|
||||
if (!demangler.canDemangle(currentProgram)) {
|
||||
println("Unable to create demangler.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Process entries in VxWorks symbol table
|
||||
Address vxSymTbl = vxNumSymEntriesAddr.subtract(vxNumSymEntries * SYM_ENTRY_SIZE);
|
||||
for (int i = 0; i < vxNumSymEntries; i++) {
|
||||
|
||||
if (monitor.isCancelled()) {
|
||||
return; // check for cancel button
|
||||
}
|
||||
println("i=" + i); // visual counter
|
||||
|
||||
// Extract symbol table entry values
|
||||
Address symEntry = vxSymTbl.add(i * SYM_ENTRY_SIZE);
|
||||
Address symNameAddr = toAddr(mem.getInt(symEntry.add(SYM_NAME_OFF)));
|
||||
Address symLocAddr = toAddr(mem.getInt(symEntry.add(SYM_LOC_OFF)));
|
||||
byte symType = mem.getByte(symEntry.add(SYM_TYPE_OFF));
|
||||
println("symNameAddr: 0x" + symNameAddr.toString() + ", symLocAddr: 0x" +
|
||||
symLocAddr.toString() + ", symType: " + symType);
|
||||
|
||||
// Remove any data or instructions that overlap this symName
|
||||
// (May happen if disassembly creates invalid references)
|
||||
Address a;
|
||||
String symName;
|
||||
for (a = symNameAddr; mem.getByte(a) != 0; a = a.add(1)) {
|
||||
if (getDataAt(a) != null) {
|
||||
removeDataAt(a);
|
||||
}
|
||||
if (getInstructionAt(a) != null) {
|
||||
removeInstructionAt(a);
|
||||
}
|
||||
}
|
||||
if (getDataAt(a) != null) {
|
||||
removeDataAt(a);
|
||||
}
|
||||
if (getInstructionAt(a) != null) {
|
||||
removeInstructionAt(a);
|
||||
}
|
||||
|
||||
// Turn *symNameAddr into a string and store it in symName
|
||||
try {
|
||||
symName = (String) createAsciiString(symNameAddr).getValue();
|
||||
}
|
||||
catch (Exception e) {
|
||||
println("createAsciiString: caught exception...");
|
||||
println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
println("symName: " + symName);
|
||||
|
||||
// Demangle symName
|
||||
String symDemangledName = null;
|
||||
try {
|
||||
// if successful, symDemangledName will be non-NULL
|
||||
MangledContext mangledContext = demangler.createMangledContext(symDemangledName,
|
||||
null, currentProgram, symNameAddr);
|
||||
symDemangledName = demangler.demangle(mangledContext).getSignature(false);
|
||||
}
|
||||
catch (DemangledException e) {
|
||||
// if symName wasn't a mangled name, silently continue
|
||||
if (!e.isInvalidMangledName()) {
|
||||
println("demangle: Demangling error");
|
||||
output.println("demangle: Demangling error");
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
println("demangle: Caught runtime exception");
|
||||
output.println("demangle: Caught runtime exception");
|
||||
}
|
||||
if (symDemangledName != null) {
|
||||
println("symDemangledName: " + symDemangledName);
|
||||
}
|
||||
|
||||
// Delete any symbol in the Ghidra symbol table with the same name
|
||||
SymbolIterator syms = ghidraSymTbl.getSymbols(symName);
|
||||
Symbol sym;
|
||||
while (syms.hasNext()) {
|
||||
sym = syms.next();
|
||||
println("Deleting matching Ghidra symbol: " + sym.getName());
|
||||
ghidraSymTbl.removeSymbolSpecial(sym);
|
||||
}
|
||||
|
||||
// Delete any symbol in the Ghidra symbol table at the same address
|
||||
if ((sym = getSymbolAt(symLocAddr)) != null) {
|
||||
println("Deleting symbol at target address: " + sym.getName());
|
||||
ghidraSymTbl.removeSymbolSpecial(sym);
|
||||
}
|
||||
|
||||
switch (symType) {
|
||||
case 0: // Undefined Symbol
|
||||
println("NULL symType!");
|
||||
break;
|
||||
case 2: // Local Absolute
|
||||
case 3: // Global Absolute
|
||||
case 6: // Local Data
|
||||
case 7: // Global Data
|
||||
case 8: // Local BSS
|
||||
case 9: // Global BSS
|
||||
// Data: log the symbol & create a Ghidra symbol at symLocAddr
|
||||
output.println(symLocAddr.toString() + "\t" + symName);
|
||||
createLabel(symLocAddr, symName, true);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram, monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: // Local .text
|
||||
case 5: // Global .text
|
||||
// Code: log the symbol, disassemble, & create/name function
|
||||
output.println(symLocAddr.toString() + "\t" + symName);
|
||||
goTo(symLocAddr);
|
||||
disassemble(symLocAddr);
|
||||
createFunction(symLocAddr, symName);
|
||||
if (getFunctionAt(symLocAddr) != null) {
|
||||
getFunctionAt(symLocAddr).setName(symName, SourceType.USER_DEFINED);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram,
|
||||
monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
println("createFunction: Failed to create function");
|
||||
output.println("createFunction: Failed to create function");
|
||||
createLabel(symLocAddr, symName, true);
|
||||
if (symDemangledName != null) {
|
||||
new DemanglerCmd(symLocAddr, symName).applyTo(currentProgram,
|
||||
monitor);
|
||||
List<Symbol> symbols =
|
||||
getSymbols(symName, currentProgram.getGlobalNamespace());
|
||||
if (!symbols.isEmpty()) {
|
||||
ghidraSymTbl.removeSymbolSpecial(symbols.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
println("Invalid symType!");
|
||||
break;
|
||||
}
|
||||
|
||||
symEntry = symEntry.add(SYM_ENTRY_SIZE); // goto next entry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue