Candidate release of source code.

This commit is contained in:
Dan
2019-03-26 13:45:32 -04:00
parent db81e6b3b0
commit 79d8f164f8
12449 changed files with 2800756 additions and 16 deletions

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,7 @@
apply plugin: 'eclipse'
eclipse.project.name = 'Features GnuDemangler'
apply from: "$rootProject.projectDir/gradleScripts/ghidraScripts.gradle"
dependencies {
compile project(":Base")
}

View File

@@ -0,0 +1,9 @@
##VERSION: 2.0
##MODULE IP: BSD
.classpath||GHIDRA||||END|
.project||GHIDRA||||END|
Module.manifest||GHIDRA||||END|
build.gradle||GHIDRA||||END|
src/test/resources/ghidra/app/util/demangler/gnu_mangled_names.txt||GHIDRA||reviewed||END|
src/test/resources/ghidra/app/util/demangler/gnu_mangled_names_macho.txt||GHIDRA||reviewed||END|
src/test/resources/ghidra/app/util/demangler/libMagick.symbols.txt||GHIDRA||reviewed||END|

View File

@@ -0,0 +1,128 @@
/* ###
* 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.
*/
// An exemplar script that allows the user to pass options to the Gnu Demangler. One such
// option is the '-s arm' option which is hard coded into the script to show how it is done.
// See binutils' c++filt for more information on supported options.
//
//@category Examples.Demangler
import java.io.*;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.demangler.DemangledObject;
import ghidra.app.util.demangler.DemanglerOptions;
import ghidra.app.util.demangler.gnu.GnuDemanglerParser;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.app.util.opinion.MachoLoader;
import ghidra.framework.*;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.symbol.Symbol;
public class DemangleElfWithOptionScript extends GhidraScript {
@Override
protected void run() throws Exception {
String executableFormat = currentProgram.getExecutableFormat();
if (!canDemangle(executableFormat)) {
println("Cannot use the elf demangling options for executable format: " +
executableFormat);
return;
}
Symbol symbol = null;
if (currentAddress != null && (currentSelection == null || currentSelection.isEmpty())) {
symbol = getSymbolAt(currentAddress);
}
if (symbol == null) {
println("No symbol at the current address (selections are not supported)");
return;
}
String mangled = symbol.getName();
Process process = createProcess(executableFormat);
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
BufferedReader input = new BufferedReader(new InputStreamReader(in));
PrintWriter output = new PrintWriter(out);
output.println(mangled);
output.flush();
String demangled = input.readLine();
println("demangled: " + demangled);
GnuDemanglerParser parser = new GnuDemanglerParser(null);
DemangledObject demangledObject = parser.parse(mangled, demangled);
if (demangledObject == null) {
println("Could not demangle: " + mangled);
return;
}
DemanglerOptions options = new DemanglerOptions();
options.setDoDisassembly(false);
options.setApplySignature(true);
options.setDemangleOnlyKnownPatterns(true);
if (!demangledObject.applyTo(currentProgram, currentAddress, options, monitor)) {
println("Failed to apply demangled data for " + mangled);
}
println("Succesfully demangled " + mangled + " to " + demangled);
}
private boolean canDemangle(String executableFormat) {
//check if language is GCC - this is not altogether correct !
// Objective-C and other non-GCC based symbols may be handled improperly
if (isELF(executableFormat) || isMacho(executableFormat)) {
return true;
}
CompilerSpec compilerSpec = currentProgram.getCompilerSpec();
if (compilerSpec.getCompilerSpecID().getIdAsString().toLowerCase().indexOf("windows") == -1) {
return true;
}
return false;
}
private boolean isELF(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(ElfLoader.ELF_NAME) != -1;
}
private boolean isMacho(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(MachoLoader.MACH_O_NAME) != -1;
}
private Process createProcess(String executableName) throws Exception {
OperatingSystem OS = Platform.CURRENT_PLATFORM.getOperatingSystem();
String demanglerExe =
(OS == OperatingSystem.WINDOWS) ? "demangler_gnu.exe" : "demangler_gnu";
File commandPath = Application.getOSFile("GnuDemangler", demanglerExe);
//
// This is where special options are to be passed. Put your own here as necessary.
//
String[] command = new String[] { commandPath.getAbsolutePath(), "-s", "arm" };
Process process = Runtime.getRuntime().exec(command);
return process;
}
}

View File

@@ -0,0 +1,228 @@
/* ###
* 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 CustomerSubmission.vxWorks
import java.io.FileOutputStream;
import java.io.PrintWriter;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.demangler.DemangledException;
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
symDemangledName = demangler.demangle(symName, true).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);
ghidraSymTbl.removeSymbolSpecial(getSymbol(symName,
currentProgram.getGlobalNamespace()));
}
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);
ghidraSymTbl.removeSymbolSpecial(getSymbol(symName,
currentProgram.getGlobalNamespace()));
}
}
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);
ghidraSymTbl.removeSymbolSpecial(getSymbol(symName,
currentProgram.getGlobalNamespace()));
}
}
break;
default:
println("Invalid symType!");
break;
}
symEntry = symEntry.add(SYM_ENTRY_SIZE); // goto next entry
}
}
}
}

View File

@@ -0,0 +1,229 @@
/* ###
* 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 CustomerSubmission.vxWorks
import java.io.FileOutputStream;
import java.io.PrintWriter;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.script.GhidraScript;
import ghidra.app.util.demangler.DemangledException;
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
symDemangledName = demangler.demangle(symName, true).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);
ghidraSymTbl.removeSymbolSpecial(
getSymbol(symName, currentProgram.getGlobalNamespace()));
}
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);
ghidraSymTbl.removeSymbolSpecial(
getSymbol(symName, currentProgram.getGlobalNamespace()));
}
}
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);
ghidraSymTbl.removeSymbolSpecial(
getSymbol(symName, currentProgram.getGlobalNamespace()));
}
}
break;
default:
println("Invalid symType!");
break;
}
symEntry = symEntry.add(SYM_ENTRY_SIZE); // goto next entry
}
}
}
}

View File

@@ -0,0 +1,840 @@
/* ###
* 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.
*/
// Locates and parses the VxWorks symbol table. Names the table "vxSymTbl"
// and names the table length variable "vxSymTblLen" (if the length variable
// appears either directly before or after the symbol table). Defines the
// symbol table as SYMBOL[vxSymTblLen].
//
// Extracts symbol name, location, and type from each entry. Disassembles,
// creates, and names functions. Names global variables.
//
// Any existing Ghidra symbol table entries that collide with VxWorks symbol
// table entries are deleted. Mangled C++ symbol names are demangled.
//
// The VxWorks symbol table is an array [0..n-1] of (struct SYMBOL) entries.
// The table may be immediately followed or preceeded by an (int) vxSymTblLen
// value.
//
// Prerequisites:
//
// - Program memory block(s) is(are) aligned with actual load addresses
// (run something like MemAlignARM_LE.java)
//
// - Symbol table cannot be in a memory block with a name that contains
// the string "text" or "bss"
//
// - Modify getVxSymbolClass() to recognize your program's VxWorks
// symbol table entry structure, if necessary
//
// @category VxWorks
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.services.DataTypeManagerService;
import ghidra.app.util.demangler.DemangledException;
import ghidra.app.util.demangler.gnu.GnuDemangler;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.data.ArrayDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.data.DataTypeManager;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
public class VxWorksSymTab_Finder extends GhidraScript {
boolean debug = false;
//------------------------------------------------------------------------
// getDataTypeManagerByName
//
// Retrieves data type manager by name.
//
// Returns:
// Success: DataTypeManager
// Failure: null
//------------------------------------------------------------------------
private DataTypeManager getDataTypeManagerByName(String name) {
DataTypeManagerService service = state.getTool().getService(DataTypeManagerService.class);
// Loop through all managers in the data type manager service
for (DataTypeManager manager : service.getDataTypeManagers()) {
if (manager.getName().equals(name)) {
return manager;
}
}
return null;
}
//------------------------------------------------------------------------
// VxSymbol
//
// Contains a SYMBOL data type representing a VxWorks symbol table entry
// and several associated methods.
//------------------------------------------------------------------------
private class VxSymbol {
StructureDataType dt = null;
int nameOffset = 0;
int locOffset = 0;
int typeOffset = 0;
int length = 0;
public VxSymbol(StructureDataType struct) {
dt = struct;
nameOffset = getFieldOffset(dt, "symNameOff");
locOffset = getFieldOffset(dt, "symLocOff");
typeOffset = getFieldOffset(dt, "symType");
length = dt.getLength();
}
private int getFieldOffset(StructureDataType dataType, String name) {
for (DataTypeComponent comp : dataType.getComponents()) {
if (comp.getFieldName().equals(name)) {
return comp.getOffset();
}
}
return -1;
}
public DataType dataType() {
return dt;
}
public int length() {
return length;
}
public int nameOffset() {
return nameOffset;
}
public int locOffset() {
return locOffset;
}
public int typeOffset() {
return typeOffset;
}
// Add SYMBOL data type to Program DataTypeManager
// (if data type already exists, replace it)
public void createGhidraType() {
currentProgram.getDataTypeManager().addDataType(dt,
DataTypeConflictHandler.REPLACE_HANDLER);
}
}
//------------------------------------------------------------------------
// getVxSymbolClass
//
// Creates a SYMBOL structure data type and uses it to create a new
// VxSymbol class instance.
//
// Returns:
// Success: VxSymbol
// Failure: null
//------------------------------------------------------------------------
private VxSymbol getVxSymbolClass(int type) {
// Pre-define base data types used to define symbol table entry data type
DataTypeManager builtin = getDataTypeManagerByName("BuiltInTypes");
DataType charType = builtin.getDataType("/char");
DataType charPtrType = PointerDataType.getPointer(charType, 4);
DataType byteType = builtin.getDataType("/byte");
DataType ushortType = builtin.getDataType("/ushort");
DataType intType = builtin.getDataType("/int");
DataType uintType = builtin.getDataType("/uint");
DataType voidType = builtin.getDataType("/void");
DataType voidPtrType = PointerDataType.getPointer(voidType, 4);
// Define a SYMBOL data type (try to put most common first).
// Each SYMBOL data type must include at least 3 fields named
// symNameOff, symLocOff, and symType.
StructureDataType dt = null;
switch (type) {
case 0:
// Version 5.4, 6.4 and 6.8
//
// Total length: 0x14 bytes
// 0x00 uint symHashNode // NULL
// 0x04 char *symNameOff
// 0x08 void *symLocOff
// 0x0c int NULL
// 0x10 ushort symGroup
// 0x12 uchar symType
// 0x13 uchar undef
dt = new StructureDataType("SYMBOL", 0x14);
dt.replaceAtOffset(0, uintType, 4, "symHashNode", "");
dt.replaceAtOffset(4, charPtrType, 4, "symNameOff", "");
dt.replaceAtOffset(8, voidPtrType, 4, "symLocOff", "");
dt.replaceAtOffset(0x0c, intType, 4, "", "");
dt.replaceAtOffset(0x10, ushortType, 2, "symGroup", "");
dt.replaceAtOffset(0x12, byteType, 1, "symType", "");
break;
case 1:
// Version 6.1
//
// Total length: 0x18 bytes
// 0x00 uint symHashNode // NULL
// 0x04 char *symNameOff
// 0x08 void *symLocOff
// 0x0c int NULL
// 0x10 int NULL
// 0x14 uchar symType
// 0x15 uchar undef[3]
dt = new StructureDataType("SYMBOL", 0x18);
dt.replaceAtOffset(0, uintType, 4, "symHashNode", "");
dt.replaceAtOffset(4, charPtrType, 4, "symNameOff", "");
dt.replaceAtOffset(8, voidPtrType, 4, "symLocOff", "");
dt.replaceAtOffset(0x0c, intType, 4, "", "");
dt.replaceAtOffset(0x10, intType, 4, "", "");
dt.replaceAtOffset(0x14, byteType, 1, "symType", "");
break;
case 2:
// Unknown VxWorks version(s)
//
// Total length: 0x1c bytes
// 0x00 uint symHashNode // NULL
// 0x04 char *symNameOff
// 0x08 void *symLocOff
// 0x0c int unk; // no clear pattern to values
// 0x10 int NULL
// 0x14 int NULL
// 0x18 uchar symType
// 0x19 uchar undef[3]
dt = new StructureDataType("SYMBOL", 0x1c);
dt.replaceAtOffset(0, uintType, 4, "symHashNode", "");
dt.replaceAtOffset(4, charPtrType, 4, "symNameOff", "");
dt.replaceAtOffset(8, voidPtrType, 4, "symLocOff", "");
dt.replaceAtOffset(0x0c, intType, 4, "", "");
dt.replaceAtOffset(0x10, intType, 4, "", "");
dt.replaceAtOffset(0x14, intType, 4, "", "");
dt.replaceAtOffset(0x18, byteType, 1, "symType", "");
break;
case 3:
// Version 5.5
//
// Total length: 0x10 bytes
// 0x00 uint symHashNode // NULL
// 0x04 char *symNameOff
// 0x08 void *symLocOff
// 0x0c ushort symGroup // NULL
// 0x0e uchar symType
// 0x0f uchar undef
dt = new StructureDataType("SYMBOL", 0x10);
dt.replaceAtOffset(0, uintType, 4, "symHashNode", "");
dt.replaceAtOffset(4, charPtrType, 4, "symNameOff", "");
dt.replaceAtOffset(8, voidPtrType, 4, "symLocOff", "");
dt.replaceAtOffset(0x0c, ushortType, 2, "symGroup", "");
dt.replaceAtOffset(0x0e, byteType, 1, "symType", "");
break;
default:
return null;
}
// Return a VxSymbol class for this SYMBOL data type
return new VxSymbol(dt);
}
//------------------------------------------------------------------------
// isExecute
//
// Is address in an executable memory block?
//------------------------------------------------------------------------
private boolean isExecute(Address addr) {
// Search all program memory blocks
for (MemoryBlock block : getMemoryBlocks()) {
if (block.contains(addr)) {
return block.isExecute();
}
}
return false;
}
//------------------------------------------------------------------------
// isAddress
//
// Is offset in an existing memory block?
//------------------------------------------------------------------------
private boolean isAddress(long offset) {
// Search all program memory blocks
for (MemoryBlock block : getMemoryBlocks()) {
if (block.getStart().getOffset() <= offset && block.getEnd().getOffset() >= offset) {
return true;
}
}
return false; // no match
}
//------------------------------------------------------------------------
// isAddress
//
// Is offset in the specified memory block?
//------------------------------------------------------------------------
private boolean isAddress(long offset, MemoryBlock block) {
if (block.getStart().getOffset() <= offset && block.getEnd().getOffset() >= offset) {
return true;
}
return false;
}
//------------------------------------------------------------------------
// isString
//
// Are the bytes starting at addr a C string?
//
// Algorithm: Scan bytes until finding either an invalid char or null.
// If scan stops at null, return true -- else false.
//------------------------------------------------------------------------
private boolean isString(Address addr) {
byte _byte;
try {
_byte = getByte(addr);
}
catch (Exception except) {
return false;
}
while ( // May need to add valid character examples here.
(_byte == 0x09 || _byte == 0x0a || _byte == 0x0d || (_byte > 0x19 && _byte < 0x80)) &&
_byte != 0x00) {
if (monitor.isCancelled()) {
return false;
}
addr = addr.add(1);
try {
_byte = getByte(addr);
}
catch (Exception except) {
return false;
}
}
if (_byte == 0x00)
{
return true; // Scan stopped at null.
}
return false; // Scan stopped at invalid char.
}
//------------------------------------------------------------------------
// clearString
//
// Remove data or instructions that overlap the null-terminated
// string at addr (may happen if disassembly creates invalid references
// or compiler optimization creates shared strings).
//
// Use get*Containing() in case a string that ends with the string
// at addr has already been defined (e.g., the string at addr is
// "CoolFunc" and the string "g_pfCoolFunc" overlaps it).
//------------------------------------------------------------------------
private void clearString(Address addr) throws Exception {
Data data;
Instruction inst;
// Clear the string, breaking on the terminating null character
while (getByte(addr) != 0) {
data = getDataContaining(addr);
if (data != null) {
removeDataAt(data.getAddress());
}
inst = getInstructionContaining(addr);
if (inst != null) {
removeInstructionAt(inst.getAddress());
}
addr = addr.add(1);
}
// Now clear at string's terminating null character
data = getDataContaining(addr);
if (data != null) {
removeDataAt(data.getAddress());
}
inst = getInstructionContaining(addr);
if (inst != null) {
removeInstructionAt(inst.getAddress());
}
}
//------------------------------------------------------------------------
// isSymTblEntry
//
// Does data pointed to by entry look like a VxWorks symbol table entry?
// Test is weak.
//------------------------------------------------------------------------
private boolean isSymTblEntry(Address entry, VxSymbol vxSymbol) throws Exception {
// First dword must be null or a valid ptr (typically into the sym table)
long value = getInt(entry) & 0xffffffffL;
if ((value != 0) && !isAddress(value)) {
if (debug) {
println("1: " + entry + " --> " + Long.toHexString(value));
}
return false;
}
// symNameOff field must point to a non-null C string
value = getInt(entry.add(vxSymbol.nameOffset())) & 0xffffffffL;
if (!isAddress(value)) {
if (debug) {
println("2: " + entry + " --> " + Long.toHexString(value));
}
return false;
}
Address symNameAddr = toAddr(value);
if (!isString(symNameAddr)) {
if (debug) {
println("3: " + entry + " --> " + Long.toHexString(value));
}
return false;
}
if (getByte(symNameAddr) == 0) {
return false;
}
// symLocOff field can be almost anything (e.g., external mem ref)
//value = (long)getInt(entry.add(vxSymbol.locOffset())) & 0xffffffffL;
//if (value == 0) {
// if (debug) println("4: " + entry);
// return false;
//}
// symType field must be recognized type code (this test is weak)
byte symType = getByte(entry.add(vxSymbol.typeOffset()));
if (!isValidSymType(symType)) {
if (debug) {
println("5: " + entry + " --> " + symType);
}
return false;
}
return true;
}
private boolean isValidSymType(byte symType) {
switch (symType) {
case 0: // Undefined Symbol
return false;
case 2: // Local Absolute
case 3: // Global Absolute
case 6: // Local Data
case 7: // Global Data
case 8: // Local BSS
case 9: // Global BSS
case 4: // Local .text
case 5: // Global .text
case 0x11: // External ref -- ignore
return true;
default:
return false;
}
}
//------------------------------------------------------------------------
// findSymTbl
//
// Searches all memory blocks for data that looks like a run of testLen
// VxWorks symbol table entries.
//
// Returns:
// Success: table address
// Failure: null
//------------------------------------------------------------------------
private Address findSymTbl(VxSymbol vxSymbol) throws Exception {
int testLen = 100; // number of symbol tbl entries to look for
boolean hasNonExecute = checkNonExecute();
// Iterate through all memory blocks
for (MemoryBlock block : currentProgram.getMemory().getBlocks()) {
// Skip code/execute blocks if there are non-execute blocks,
// otherwise search everything.
if (hasNonExecute && block.isExecute()) {
continue;
}
// skip uninit
if (!block.isInitialized()) {
continue;
}
// Search current block for run of testLen symbol table entries
int testBlkSize = vxSymbol.length * testLen;
printf(" block: " + block.getName() + " (" + block.getStart() + ", " +
block.getEnd() + ") ");
printf("testBlkSize = " + Integer.toHexString(testBlkSize) + " ");
System.out.flush();
long prevOffset = 0;
Address cursor = block.getStart();
while ((cursor != null) && isAddress(cursor.getOffset() + testBlkSize, block)) {
// Script cancel check and visual feedback
if (monitor.isCancelled()) {
return null;
}
if ((cursor.getOffset() - prevOffset) >= 0x100000) {
printf(".");
System.out.flush();
prevOffset = cursor.getOffset();
}
// Determine whether cursor now points to a symbol table
int i = 0;
for (Address entry = cursor; isSymTblEntry(entry, vxSymbol) &&
(i < testLen); entry = entry.add(vxSymbol.length()), i++) {
}
if (i == testLen) {
// May have symbol table -- verify length
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");
}
}
cursor = cursor.add(4);
}
printf("\n");
printf(" search terminated at: " + cursor + "\n");
System.out.flush();
}
return null;
}
private boolean checkNonExecute() {
for (MemoryBlock block : currentProgram.getMemory().getBlocks()) {
if (!block.isExecute()) {
return true;
}
}
return false;
}
//------------------------------------------------------------------------
// getSymTblLen
//
// Counts number of entries in VxWorks table at address symTbl.
//
// Returns:
// Success: number of table entries (> 0)
// Failure: 0
//------------------------------------------------------------------------
private int getSymTblLen(Address symTbl, VxSymbol vxSymbol) throws Exception {
Address entry = symTbl;
int j = 0;
while (isSymTblEntry(entry, vxSymbol)) {
entry = entry.add(vxSymbol.length());
j++;
}
return j;
// NOTE: Found an example of a VxWorks symbol table that was not
// directly adjacent to the symbol table length variable...
// so removed the following constraint.
/*
// Symbol table length entry may be at beginning or end of the symbol
// table...so compare computed length with both values. If either
// matches, table length is verified.
if ((j == getInt(entry)) || (j == getInt(symTbl.subtract(4)))) {
return j;
} else {
return 0;
}
*/
}
/**
* Look before/after the table to see if there is a size value there and mark it if it agrees with TableLen
*
* @param symTbl
* @param vxSymbol
* @param tableLen
* @throws Exception
*/
private void markSymbolTableLen(Address symTbl, VxSymbol vxSymbol, int symTblLen)
throws Exception {
// NOTE: Found an example of a VxWorks symbol table that was not
// directly adjacent to the symbol table length variable...
// Name the VxWorks symbol length variable
// (if it appears either directly before or after the symbol table)
Address symTblLenPtr = null;
long foreOff = symTbl.getOffset() - 4;
long aftOff = symTbl.getOffset() + symTblLen * vxSymbol.length();
if (isAddress(foreOff) && getInt(toAddr(foreOff)) == symTblLen) {
symTblLenPtr = toAddr(foreOff);
}
else if (isAddress(aftOff) && getInt(toAddr(aftOff)) == symTblLen) {
symTblLenPtr = toAddr(aftOff);
}
if (symTblLenPtr != null) {
removeConflictingSymbols("vxSymTblLen", symTblLenPtr);
createLabel(symTblLenPtr, "vxSymTblLen", true);
createDWord(symTblLenPtr);
}
else {
println("Warning: Symbol Table Size not found before of after table");
}
}
//------------------------------------------------------------------------
// removeConflictingSymbols
//
// Deletes all symbols with the same name and the primary symbol at addr.
//------------------------------------------------------------------------
private void removeConflictingSymbols(String name, Address addr) {
// Delete any existing symbols with the same name
for (Symbol sym : currentProgram.getSymbolTable().getSymbols(name)) {
sym.delete();
}
// Delete primary Ghidra symbol at the same address
Symbol sym = getSymbolAt(addr);
if (sym != null) {
sym.delete();
}
return;
}
//------------------------------------------------------------------------
// applyDemangled
//
// Apply demangled symbol name to symbol.
//------------------------------------------------------------------------
private void applyDemangled(Address addr, String mangled, String demangled) {
if (demangled != null) {
new DemanglerCmd(addr, mangled).applyTo(currentProgram, monitor);
currentProgram.getSymbolTable().removeSymbolSpecial(
getSymbol(mangled, currentProgram.getGlobalNamespace()));
}
return;
}
//------------------------------------------------------------------------
// doLocalDisassemble
//
// Do our own disassembly, and don't let auto-analysis start until after
// this script finishes. This speeds up the script substantially and
// allows auto-analysis to operate with more information (and code/data
// that isn't rapidly changing).
//------------------------------------------------------------------------
private void doLocalDisassemble(Address addr) {
// Only disassemble in memory blocks marked executable
if (!isExecute(addr)) {
return;
}
DisassembleCommand cmd = new DisassembleCommand(addr, null, true);
cmd.enableCodeAnalysis(false); // Queues changes up for later analysis
cmd.applyTo(currentProgram, monitor);
AddressSet set = cmd.getDisassembledAddressSet();
AutoAnalysisManager.getAnalysisManager(currentProgram).codeDefined(set);
return;
}
//------------------------------------------------------------------------
// getScriptAnalysisMode
//
// Force auto-analysis to wait until script completes.
//------------------------------------------------------------------------
@Override
public AnalysisMode getScriptAnalysisMode() {
return AnalysisMode.SUSPENDED;
}
//========================================================================
// Main
//========================================================================
@Override
public void run() throws Exception {
// Find VxWorks symbol table
Address symTbl = null;
VxSymbol vxSymbol = getVxSymbolClass(0);
for (int i = 0; ((vxSymbol != null) && !monitor.isCancelled()); i++, vxSymbol =
getVxSymbolClass(i)) {
println("Searching for symbol table variant " + i);
if ((symTbl = findSymTbl(vxSymbol)) != null) {
break;
}
}
if (vxSymbol == null) {
return;
}
int symTblLen = getSymTblLen(symTbl, vxSymbol);
println("Symbol table at " + symTbl + " (" + symTblLen + " entries)");
// Name the VxWorks symbol table
removeConflictingSymbols("vxSymTbl", symTbl);
createLabel(symTbl, "vxSymTbl", true);
markSymbolTableLen(symTbl, vxSymbol, symTblLen);
// Create symbol data type and symbol table structure
println("Creating SYMBOL data type and symbol table structure...");
vxSymbol.createGhidraType();
clearListing(symTbl, symTbl.add(symTblLen * vxSymbol.length() - 1));
createData(symTbl, new ArrayDataType(vxSymbol.dataType(), symTblLen, vxSymbol.length()));
// Create a GNU demangler instance
GnuDemangler demangler = new GnuDemangler();
if (!demangler.canDemangle(currentProgram)) {
println("Unable to create demangler.");
return;
}
// Process VxWorks symbol table entries
println("Processing symbol table entries.");
Address symEntry = symTbl;
for (int i = 0; (i < symTblLen) && !monitor.isCancelled(); i++, symEntry =
symEntry.add(vxSymbol.length())) {
// Extract symbol table entry values
Address symNameAddr = toAddr(getInt(symEntry.add(vxSymbol.nameOffset())) & 0xffffffffL);
Address symLoc = toAddr(getInt(symEntry.add(vxSymbol.locOffset())) & 0xffffffffL);
byte symType = getByte(symEntry.add(vxSymbol.typeOffset()));
// Remove any data or instructions that overlap string at *symNameAddr
clearString(symNameAddr);
// Turn *symNameAddr into a string and store it in symName
String symName;
try {
symName = (String) createAsciiString(symNameAddr).getValue();
}
catch (Exception e) {
println("createAsciiString: caught exception...");
println(e.getMessage());
println(e.toString());
return;
}
if (symName.length() > 2000) {
symName = symName.substring(0, 2000);
}
// Demangle symName
String symDemangledName = null;
try {
symDemangledName = demangler.demangle(symName, true).getSignature(false);
}
catch (DemangledException e) { // report demangling error
if (!e.isInvalidMangledName()) {
println("demangle: Demangling error");
}
}
catch (RuntimeException e) { // ignore unmangled symNames
}
// Status update
if (symDemangledName != null) {
println("i=" + i + ", nameAddr: " + symNameAddr + ", loc: " + symLoc + ", type: " +
symType + ", name: " + symName + ", demangled: " + symDemangledName);
}
else {
println("i=" + i + ", nameAddr: " + symNameAddr + ", loc: " + symLoc + ", type: " +
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) {
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
createLabel(symLoc, symName, true);
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);
}
break;
case 0x11: // External ref -- ignore
break;
default:
println("Invalid symType!");
break;
}
}
}
}

View File

@@ -0,0 +1,236 @@
/* ###
* 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.
*/
package ghidra.app.util.demangler.gnu;
import java.io.File;
import java.io.IOException;
import generic.jar.ResourceFile;
import ghidra.app.util.demangler.*;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.app.util.opinion.MachoLoader;
import ghidra.framework.Application;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.listing.Program;
/**
* A class for demangling debug symbols created using GNU GCC.
*/
public class GnuDemangler implements Demangler {
private static final String DWARF_REF = "DW.ref."; //dwarf debug reference
private static final String GLOBAL_PREFIX = "_GLOBAL_";
public GnuDemangler() {
// needed to instantiate dynamically
}
@Override
public boolean canDemangle(Program program) {
String executableFormat = program.getExecutableFormat();
if (isELF(executableFormat) || isMacho(executableFormat)) {
return true;
}
//check if language is GCC
CompilerSpec compilerSpec = program.getCompilerSpec();
if (compilerSpec.getCompilerSpecID().getIdAsString().toLowerCase().indexOf(
"windows") == -1) {
return true;
}
return false;
}
@Override
public DemangledObject demangle(String mangled, boolean demangleOnlyKnownPatterns)
throws DemangledException {
if (skip(mangled, demangleOnlyKnownPatterns)) {
return null;
}
String originalMangled = mangled;
String globalPrefix = null;
if (mangled.startsWith(GLOBAL_PREFIX)) {
int index = mangled.indexOf("_Z");
if (index > 0) {
globalPrefix = mangled.substring(0, index);
mangled = mangled.substring(index);
}
}
else if (mangled.startsWith("__Z")) {
mangled = mangled.substring(1);//removed first underscore....
}
boolean isDwarf = false;
if (mangled.startsWith(DWARF_REF)) {
int len = DWARF_REF.length();
mangled = mangled.substring(len);
isDwarf = true;
}
try {
GnuDemanglerNativeProcess process = GnuDemanglerNativeProcess.getDemanglerNativeProcess();
String demangled = process.demangle(mangled).trim();
if (mangled.equals(demangled) || demangled.length() == 0) {
throw new DemangledException(true);
}
DemangledObject demangledObject =
parse(mangled, process, demangled, demangleOnlyKnownPatterns);
if (demangledObject == null) {
return demangledObject;
}
if (globalPrefix != null) {
// TODO: may need better naming convention for demangled function
DemangledFunction dfunc =
new DemangledFunction(globalPrefix + demangledObject.getName());
dfunc.setNamespace(demangledObject.getNamespace());
demangledObject = dfunc;
}
else {
demangledObject.setSignature(demangled);
}
demangledObject.setOriginalMangled(originalMangled);
if (isDwarf) {
DemangledAddressTable dat = new DemangledAddressTable((String) null, 1);
dat.setSpecialPrefix("DWARF Debug ");
dat.setName(demangledObject.getName());
dat.setNamespace(demangledObject.getNamespace());
dat.setOriginalMangled(originalMangled);
return dat;
}
return demangledObject;
}
catch (IOException e) {
if (e.getMessage().endsWith("14001")) {//missing runtime dlls, prolly
ResourceFile installationDir = Application.getInstallationDirectory();
throw new DemangledException("Missing runtime libraries. " + "Please install " +
installationDir + File.separatorChar + "support" + File.separatorChar +
"install_windows_runtime_libraries.exe.");
}
throw new DemangledException(e);
}
}
private boolean skip(String mangled, boolean demangleOnlyKnownPatterns) {
// Ignore versioned symbols which are generally duplicated at the same address
if (mangled.indexOf("@") > 0) { // do not demangle versioned symbols
return true;
}
if (mangled.startsWith("___")) {
// not a mangled symbol, but the demangler will try anyway, so don't let it
return true;
}
if (!demangleOnlyKnownPatterns) {
return false; // let it go through
}
// add to this list if we find any other known GNU start patterns
if (mangled.startsWith("_Z")) {
return false;
}
else if (mangled.startsWith("__Z")) {
return false;
}
else if (mangled.startsWith("h__")) {
return false; // not sure about this one
}
else if (mangled.startsWith("?")) {
return false; // not sure about this one
}
else if (isGnu2Or3Pattern(mangled)) {
return false;
}
return true;
}
private DemangledObject parse(String mangled, GnuDemanglerNativeProcess process, String demangled,
boolean demangleOnlyKnownPatterns) {
if (demangleOnlyKnownPatterns && !isMangledString(mangled, demangled)) {
return null;
}
try {
GnuDemanglerParser parser = new GnuDemanglerParser(process);
DemangledObject demangledObject = parser.parse(mangled, demangled);
return demangledObject;
}
catch (Exception e) {
throw e;
}
}
private boolean isMangledString(String mangled, String demangled) {
//
// We get requests to demangle strings that are not mangled. For newer mangled strings
// we know how to avoid that. However, older mangled strings can be of many forms. To
// detect whether a string is mangled, we have to resort to examining the output of
// the demangler.
//
// check for the case where good strings have '__' in them (which is valid GNU2 mangling)
if (isInvalidDoubleUnderscoreString(mangled, demangled)) {
return false;
}
return true;
}
private boolean isInvalidDoubleUnderscoreString(String mangled, String demangled) {
int index = mangled.indexOf("__");
if (index == -1) {
return false;
}
//
// Bad string form: text__moretext
//
// The demangler will output something like text(..)(...)(...) or e::text(...)(...)
String leadingText = mangled.substring(0, index);
return demangled.contains(leadingText);
}
private boolean isGnu2Or3Pattern(String mangled) {
//@formatter:off
return // Gnu2/3 constructs--not sure if we still need these
mangled.startsWith("_GLOBAL_.I.") ||
mangled.startsWith("_GLOBAL_.D.") ||
mangled.startsWith("_GLOBAL__I__Z") ||
mangled.startsWith("_GLOBAL__D__Z");
//@formatter:on
}
private boolean isELF(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(ElfLoader.ELF_NAME) != -1;
}
private boolean isMacho(String executableFormat) {
return executableFormat != null && executableFormat.indexOf(MachoLoader.MACH_O_NAME) != -1;
}
}

View File

@@ -0,0 +1,104 @@
/* ###
* 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.
*/
package ghidra.app.util.demangler.gnu;
import java.io.*;
import ghidra.framework.Application;
import ghidra.framework.Platform;
public class GnuDemanglerNativeProcess {
private static final String DEMANGLER_GNU = "demangler_gnu";
private static GnuDemanglerNativeProcess demanglerNativeProcess;
private boolean isDisposed;
private Process process;
private BufferedReader reader;
private PrintWriter writer;
public static synchronized GnuDemanglerNativeProcess getDemanglerNativeProcess()
throws IOException {
if (demanglerNativeProcess == null) {
demanglerNativeProcess = new GnuDemanglerNativeProcess();
}
return demanglerNativeProcess;
}
private GnuDemanglerNativeProcess() throws IOException {
createProcess();
}
public synchronized String demangle(String mangled) throws IOException {
if (isDisposed) {
throw new IOException("Demangled process has been terminated.");
}
return demangle(mangled, true);
}
private String demangle(String mangled, boolean restart) throws IOException {
try {
writer.println(mangled);
writer.flush();
return reader.readLine();
}
catch (IOException e) {
dispose();
if (!restart) {
demanglerNativeProcess = null;
throw new IOException("Demangler process is not running.");
}
createProcess();
return demangle(mangled, false);
}
}
private void dispose() {
try {
if (process != null) {
process.destroy();
}
process = null;
reader = null;
writer = null;
}
catch (Exception e) {
// ignore
}
finally {
isDisposed = true;
}
}
private void createProcess() throws IOException {
String executableName = DEMANGLER_GNU + Platform.CURRENT_PLATFORM.getExecutableExtension();
File commandPath = Application.getOSFile(executableName);
String[] command = new String[] { commandPath.getAbsolutePath() };
process = Runtime.getRuntime().exec(command);
InputStream in = process.getInputStream();
OutputStream out = process.getOutputStream();
reader = new BufferedReader(new InputStreamReader(in));
writer = new PrintWriter(out);
isDisposed = false;
}
}

View File

@@ -0,0 +1,195 @@
/* ###
* 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.
*/
package ghidra.app.util.demangler.gnu;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.util.demangler.*;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.TerminatedStringDataType;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Data;
import ghidra.program.model.symbol.*;
import ghidra.test.ToyProgramBuilder;
import ghidra.util.task.TaskMonitor;
public class GnuDemanglerTest extends AbstractGenericTest {
private ProgramDB program;
@Before
public void setUp() throws Exception {
ToyProgramBuilder builder = new ToyProgramBuilder("test", true);
builder.createMemory(".text", "0x01001000", 0x100);
program = builder.getProgram();
}
@Test
public void testNonMangledSymbol() throws Exception {
String mangled = "Java_org_sqlite_NativeDB__1exec";
GnuDemangler demangler = new GnuDemangler();
demangler.canDemangle(program);// this perform initialization
// this throws an exception with the bug in place
demangler.demangle(mangled, true);
}
@Test
public void testDemangleOnlyKnownPatterns_False() throws Exception {
String mangled = "abracadabra_hocus_pocus";
GnuDemangler demangler = new GnuDemangler();
demangler.canDemangle(program);// this perform initialization
try {
demangler.demangle(mangled, false);
fail("Demangle should have failed attempting to demangle a non-mangled string");
}
catch (DemangledException e) {
// expected
}
}
@Test
public void testDemangleOnlyKnownPatterns_True() throws Exception {
String mangled = "abracadabra_hocus_pocus";
GnuDemangler demangler = new GnuDemangler();
demangler.canDemangle(program);// this perform initialization
DemangledObject result = demangler.demangle(mangled, true);
assertNull("Demangle did not skip a name that does not match a known mangled pattern",
result);
}
@Test
public void testDemangleTypeInfo() throws Exception {
String mangled = "_ZTIN6AP_HAL3HAL9CallbacksE";
program.startTransaction("markup...");
program.getMemory().setInt(addr("01001000"), 0x1001010);
SymbolTable symbolTable = program.getSymbolTable();
symbolTable.createLabel(addr("01001000"), mangled, SourceType.IMPORTED);
GnuDemangler demangler = new GnuDemangler();
DemangledObject obj = demangler.demangle(mangled, true);
assertNotNull(obj);
//assertEquals("typeinfo for AP_HAL::HAL::Callbacks", obj.getSignature(false));
assertTrue(
obj.applyTo(program, addr("01001000"), new DemanglerOptions(), TaskMonitor.DUMMY));
Symbol s = symbolTable.getPrimarySymbol(addr("01001000"));
assertNotNull(s);
assertEquals("typeinfo", s.getName());
assertEquals("AP_HAL::HAL::Callbacks", s.getParentNamespace().getName(true));
assertEquals("typeinfo for AP_HAL::HAL::Callbacks",
program.getListing().getComment(CodeUnit.PLATE_COMMENT, addr("01001000")));
Data d = program.getListing().getDefinedDataAt(addr("01001000"));
assertNotNull(d);
assertTrue(d.isPointer());
}
@Test
public void testDemangleTypeInfoName() throws Exception {
String mangled = "_ZTSN6AP_HAL3HAL9CallbacksE";
program.startTransaction("markup...");
program.getMemory().setBytes(addr("01001000"), "ABC\0".getBytes());
SymbolTable symbolTable = program.getSymbolTable();
symbolTable.createLabel(addr("01001000"), mangled, SourceType.IMPORTED);
GnuDemangler demangler = new GnuDemangler();
DemangledObject obj = demangler.demangle(mangled, true);
assertNotNull(obj);
assertEquals("typeinfo name for AP_HAL::HAL::Callbacks", obj.getSignature(false));
assertTrue(
obj.applyTo(program, addr("01001000"), new DemanglerOptions(), TaskMonitor.DUMMY));
Symbol s = symbolTable.getPrimarySymbol(addr("01001000"));
assertNotNull(s);
assertEquals("typeinfo_name", s.getName());
assertEquals("AP_HAL::HAL::Callbacks", s.getParentNamespace().getName(true));
assertEquals("typeinfo name for AP_HAL::HAL::Callbacks",
program.getListing().getComment(CodeUnit.PLATE_COMMENT, addr("01001000")));
Data d = program.getListing().getDefinedDataAt(addr("01001000"));
assertNotNull(d);
assertTrue(d.getDataType() instanceof TerminatedStringDataType);
assertEquals("ABC", d.getValue());
}
@Test
public void testDemangler_Format_EDG_DemangleOnlyKnownPatterns_False()
throws DemangledException {
String mangled = "_$_10MyFunction";
GnuDemangler demangler = new GnuDemangler();
demangler.canDemangle(program);// this perform initialization
DemangledObject result = demangler.demangle(mangled, false);
assertNotNull(result);
assertEquals("undefined MyFunction::~MyFunction(void)", result.getSignature(false));
}
@Test
public void testDemangler_Format_EDG_DemangleOnlyKnownPatterns_True()
throws DemangledException {
/*
Note:
This test is less of a requirement and more of an observation. This symbol was
seen in the wild and is claimed to be of the Edison Design Group (EDG) format.
It fails our parsing due to its resemblance to non-mangled text (see
the test testNonMangledSymbol()). If we update the code that checks for this
noise, then this test and it's parter should be consolidated.
*/
String mangled = "_$_10MyFunction";
GnuDemangler demangler = new GnuDemangler();
demangler.canDemangle(program);// this perform initialization
DemangledObject result = demangler.demangle(mangled, true);
assertNull(result);
}
private Address addr(String address) {
return program.getAddressFactory().getAddress(address);
}
}

View File

@@ -0,0 +1,336 @@
###############################################################################################
#
# GNU V3 MANGLED NAMES
#
###############################################################################################
_Z10enumToEnumP6MYENUM # enumToEnum(MYENUM *)
_Z12unionToUnion2_U # unionToUnion(_U)
_Z6toChari # toChar(int)
_Z6toEnumv # toEnum(void)
_Z6toLongi # toLong(int)
_Z7toFloati # toFloat(int)
_Z7toFloatidcls # toFloat(int,double,char,long,short)
_Z7toFloatPiPdPcPlPs # toFloat(int *,double *,char *,long *,short *)
_Z7toFloatPPiPPdPPcPPlPPs # toFloat(int * *,double * *,char * *,long * *,short * *)
_Z8toDoublei # toDouble(int)
_Z9toIntegerf # toInteger(float)
_Z9intToEnum6MYENUM # intToEnum(MYENUM)
###############################################################################################
_Znaj # operator new[](unsigned)
###############################################################################################
_ZN3FooC1Ei # Foo::Foo[in-charge](int)
_ZN3BarC1Ei # Bar::Bar[in-charge](int)
_ZN3Bar4FredC1Ei # Bar::Fred::Fred[in-charge](int)
###############################################################################################
_ZN3Bar4Fred4getXEv # Bar::Fred::getX(void)
_ZN3Foo4getEEl # Foo::getE(long)
_ZN3Foo4getXEi # Foo::getX(int)
_ZN3Foo4getXEv # Foo::getX(void)
_ZN3Foo6getBarEv # Foo::getBar(void)
_ZN3Foo6getFooEv # Foo::getFoo(void)
_ZN3Foo7getBoolEf # Foo::getBool(float)
_ZN3Foo7getBoolEv # Foo::getBool(void)
###############################################################################################
_ZN3FooaSEi # Foo::operator=(int)
_ZN3FoolsEi # Foo::operator<<(int)
_ZN3FoolsES_ # Foo::operator<<(Foo)
_ZN3FoorsEi # Foo::operator>>(int)
###############################################################################################
_GLOBAL__I__ZN6Magick21borderGeometryDefaultE # global constructors keyed to Magick::borderGeometryDefault
###############################################################################################
_ZNK6Magick8ColorYUV1yEv # Magick::ColorYUV::y(void) const
_ZNK6Magick5ColorcvSsEv # Magick::Color::operator<cast>(std::string)(void) const
_ZN6Magick12DrawablePathC1ERKS0_ # Magick::DrawablePath::DrawablePath[in-charge](const Magick::DrawablePath &)
_ZNK6Magick9pageImageclERNS_5ImageE # Magick::pageImage::operator()(Magick::Image &) const
_ZNK6Magick9pageImageclERNS0_5ImageE # Magick::pageImage::operator()(Magick::pageImage::Image &) const
_ZNK6Magick9pageImageclERNS0_5Image3abcE # Magick::pageImage::operator()(Magick::pageImage::Image::abc &) const
_ZN6MagickltERKNS_10CoordinateES2_ # Magick::operator<(const Magick::Coordinate &,const Magick::Coordinate &)
_ZN6MagickneERKNS_10CoordinateES2_ # Magick::operator!=(const Magick::Coordinate &,const Magick::Coordinate &)
_ZN6MagickgtERKNS_5ColorES2_ # Magick::operator>(const Magick::Color &,const Magick::Color &)
_ZN6Magick14PathCurvetoAbsC1ERKS0_ # Magick::PathCurvetoAbs::PathCurvetoAbs[in-charge](const Magick::PathCurvetoAbs &)
_ZN6Magick4Blob12updateNoCopyEPvjNS0_9AllocatorE # Magick::Blob::updateNoCopy(void *,unsigned int,Magick::Blob::Allocator)
###############################################################################################
_ZN6Magick18magickCleanUpGuardE # Magick::magickCleanUpGuard
_ZN6Magick18magickCleanUpGuardEv # Magick::magickCleanUpGuard(void)
_ZN6Magick18magickCleanUpGuardEi # Magick::magickCleanUpGuard(int)
_ZN6Magick21borderGeometryDefaultE # Magick::borderGeometryDefault
###############################################################################################
_ZNK6Magick18DrawablePopPatternclEPN9MagickLib12_DrawContextE # Magick::DrawablePopPattern::operator()(MagickLib::_DrawContext *) const
_ZNK6Magick9CoderInfo4nameEv # Magick::CoderInfo::name(void) const
###############################################################################################
_ZN6Magick5ImageC2EjjRKSsN9MagickLib11StorageTypeEPKv # Magick::Image::Image[not-in-charge](unsigned, unsigned, const std::basic_string<char, std::char_traits<char>, std::allocator<char>> &, MagickLib::StorageType, const void *)
###############################################################################################
_ZNSsC1ERKSs # std::string::std::string[in-charge](const std::string &)
_ZNSsC1EPKcRKSaIcE # std::string::std::string[in-charge](const char *,const std::allocator<char> &)
_ZNSsC1EPKcjRKSaIcE # std::string::std::string[in-charge](const char *,unsigned int,const std::allocator<char> &)
###############################################################################################
_ZN6Magick14DrawableBezierC1ERKSt4listINS_10CoordinateESaIS2_EE
_ZN6Magick12DrawablePathC2ERKSt4listINS_5VPathESaIS2_EE
###############################################################################################
_ZNSt10_List_baseIN6Magick11PathArcArgsESaIS1_EED2Ev # std::_List_base<Magick::PathArcArgs,std::allocator<Magick::PathArcArgs>>::~_List_base[not-in-charge](void)
_ZNSt24__default_alloc_templateILb1ELi0EE8allocateEj
_ZNSt10_List_baseIN6Magick5VPathESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick8DrawableESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick8DrawableESaIS1_EED2Ev
_ZNSt4listIN6Magick8DrawableESaIS1_EE14_M_create_nodeERKS1_
_ZNSt10_List_baseIN6Magick10CoordinateESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick5VPathESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick11PathArcArgsESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick15PathCurvetoArgsESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick24PathQuadraticCurvetoArgsESaIS1_EE5clearEv
_ZNSt10_List_baseIN6Magick10CoordinateESaIS1_EED2Ev
_ZNSt10_List_baseIN6Magick5VPathESaIS1_EED2Ev
_ZNSt10_List_baseIN6Magick15PathCurvetoArgsESaIS1_EED2Ev
_ZNSt10_List_baseIN6Magick24PathQuadraticCurvetoArgsESaIS1_EED2Ev
_ZNSt4listIN6Magick10CoordinateESaIS1_EE14_M_create_nodeERKS1_
_ZNSt4listIN6Magick11PathArcArgsESaIS1_EE14_M_create_nodeERKS1_
_ZNSt4listIN6Magick15PathCurvetoArgsESaIS1_EE14_M_create_nodeERKS1_
_ZNSt4listIN6Magick24PathQuadraticCurvetoArgsESaIS1_EE14_M_create_nodeERKS1_
_ZNKSt8_Rb_treeI8LocationS0_St9_IdentityIS0_ESt4lessIS0_ESaIS0_EE4findERKS0_ # std::_Rb_tree<Location,Location,std::_Identity<Location>,std::less<Location>,std::allocator<Location>>::find(const Location &) const
_ZNSt4listIN6Magick8DrawableESaIS1_EE14_M_create_nodeERKS1_ # std::list<Magick::Drawable,std::allocator<Magick::Drawable>>::_M_create_node(const Magick::Drawable &)
_ZNSt4listIN6Magick8DrawableESaIS0_EE14_M_create_nodeERKS1_ # std::list<Magick::Drawable,std::allocator<Magick>>::_M_create_node(const Magick::Drawable &)
_ZNSt4listIN6Magick8DrawableESaIS_EE14_M_create_nodeERKS1_ # std::list<Magick::Drawable,std::allocator<std::list>>::_M_create_node(const Magick::Drawable &)
# TEMPLATED CONSTRUCTORS
_ZN6Magick14PathCurvetoAbsC2ERKSt4listINS_15PathCurvetoArgsESaIS2_EE
_ZN6Magick14PathCurvetoAbsC1ERKSt4listINS_15PathCurvetoArgsESaIS2_EE
_ZN6Magick13PathLinetoRelC2ERKSt4listINS_10CoordinateESaIS2_EE
_ZNSt4listIN6Magick24PathQuadraticCurvetoArgsESaIS1_EE14_M_fill_insertESt14_List_iteratorIS1_RS1_PS1_EjRKS1_
_ZNSt4listIN6Magick24PathQuadraticCurvetoArgsESaIS1_EE18_M_insert_dispatchISt14_List_iteratorIS1_RKS1_PS6_EEEdS5_IS1_RS1_PS1_ET_SD_12__false_type
_ZNSt14__simple_allocISt10_List_nodeIN6Magick5VPathEESt24__default_alloc_templateILb1ELi0EEE10deallocateEPS3_j
_ZSt10__distanceISt14_List_iteratorIN6Magick10CoordinateERKS2_PS3_EENSt15iterator_traitsIT_E15difference_typeES8_S8_St18input_iterator_tag
#note: this mangled named contridicts.
#the "S1_" is supposed to refer to bbnode, but ends up referring
#to "std::less"
#_ZNSt3setIP6bbnodeSt4lessIS1_ESaIS1_EE6insertERKS1_ # std::set<bbnode *,std::less<bbnode *>,std::allocator<bbnode *>>::insert(const bbnode * &)
###############################################################################################
_ZNSt24__default_alloc_templateILb1ELi0EE8allocateEj # std::__default_alloc_template<(bool)1, (int)0>::allocate(unsigned)
###############################################################################################
_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_ #
###############################################################################################
_ZTch0_h40_NK8KHotKeys14Window_trigger4copyEPNS_11Action_dataE # covariant_return_thunk[0,40] KHotKeys::Window_trigger::copy(KHotKeys::Action_data *) const
_ZTch0_h40_NK8KHotKeys23Active_window_condition4copyEPNS_19Condition_list_baseE # covariant_return_thunk[0,40] KHotKeys::Active_window_condition::copy(KHotKeys::Condition_list_base *) const
###############################################################################################
_ZThn72_N8KHotKeys11KHotKeysAppD0Ev # nonvirtual_thunk[-72] KHotKeys::KHotKeysApp::~KHotKeysApp[in-charge deleting](void)
_ZThn40_N8KHotKeys14Window_triggerD1Ev # nonvirtual_thunk[-40] KHotKeys::Window_trigger::~Window_trigger[in-charge](void)
_ZThn204_N8KHotKeys11KHotKeysApp9functionsEv # nonvirtual_thunk[-204] KHotKeys::KHotKeysApp::functions(void)
_ZThn8_NSdD0Ev # nonvirtual_thunk[-8] std::iostream::~std::iostream[in-charge deleting](void)
_ZThn8_NSdD1Ev # nonvirtual_thunk[-8] std::iostream::~std::iostream[in-charge](void)
_ZThn8_NSdD1Ev # nonvirtual_thunk[-8] std::iostream::~std::iostream[in-charge](void)
###############################################################################################
_ZThn8_NSt13basic_fstreamIcSt11char_traitsIcEED0Ev # nonvirtual_thunk[-8] std::basic_fstream<char,std::char_traits<char>>::~basic_fstream[in-charge deleting](void)
_ZThn8_NSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev # nonvirtual_thunk[-8] std::basic_stringstream<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>::~basic_stringstream[in-charge deleting](void)
###############################################################################################
_ZTv0_n44_N4Arts20FileInputStream_skel14_interfaceNameEv # virtual_thunk[0,-44] Arts::FileInputStream_skel::_interfaceName(void)
_ZTv0_n48_N4Arts20FileInputStream_impl9streamEndEv # virtual_thunk[0,-48] Arts::FileInputStream_impl::streamEnd(void)
_ZTv0_n52_N4Arts16InputStream_baseD0Ev # virtual_thunk[0,-52] Arts::InputStream_base::~InputStream_base[in-charge deleting](void)
_ZTv0_n96_N4Arts20FileInputStream_skel17_isCompatibleWithERKSs # virtual_thunk[0,-96] Arts::FileInputStream_skel::_isCompatibleWith(const std::string &)
#_ZTv0_n88_N4Arts20FileInputStream_impl15request_outdataEPNS_10DataPacketIhEE # virtual_thunk[0,-88] Arts::FileInputStream_impl::request_outdata(Arts::DataPacket<unsigned char>*)
###############################################################################################
_ZTVN4Arts16InputStream_skelE # Arts::InputStream_skel::vtable
_ZTVN4Arts16SynthModule_skelE # Arts::SynthModule_skel::vtable
_ZTVN4Arts17StdoutWriter_implE # Arts::StdoutWriter_impl::vtable
_ZTVN4Arts25StdoutWriter_impl_FactoryE # Arts::StdoutWriter_impl_Factory::vtable
_ZTVN4Arts28FileInputStream_impl_FactoryE # Arts::FileInputStream_impl_Factory::vtable
_ZTVN10__cxxabiv121__vmi_class_type_infoE # __cxxabiv1::__vmi_class_type_info::vtable
###############################################################################################
_ZTTN4Arts14StdSynthModuleE # Arts::StdSynthModule::VTT
_ZTTN4Arts16SynthModule_skelE # Arts::SynthModule_skel::VTT
_ZTT13Observer_stub # Observer_stub::VTT
_ZTT8UIServer # UIServer::VTT
###############################################################################################
_ZTIN4Arts28FileInputStream_impl_FactoryE # Arts::FileInputStream_impl_Factory::typeinfo
_ZTIN4Arts20FileInputStream_baseE # Arts::FileInputStream_base::typeinfo
_ZTIN4Arts16InputStream_skelE # Arts::InputStream_skel::typeinfo
_ZTI13Observer_stub # Observer_stub::typeinfo
_ZTI18UIServerSystemTray # UIServerSystemTray::typeinfo
_ZTI8QPtrListI15KSSLCertificateE # QPtrList::typeinfo
###############################################################################################
#_ZTF
###############################################################################################
_ZTSN6Magick15DrawableViewboxE # typeinfo name for N6Magick15DrawableViewboxE
_ZTSN6Magick22DrawableRoundRectangleE # typeinfo name for N6Magick22DrawableRoundRectangleE
_ZTSN10__cxxabiv116__enum_type_infoE # typeinfo name for N10__cxxabiv116__enum_type_infoE
_ZTSNSt8ios_base7failureE # typeinfo name for NSt8ios_base7failureE
#_ZTSSt14unary_functionIPN9MagickLib12_DrawContextEvE # typeinfo name for std::unary_function<MagickLib::_DrawContext*,void>
#_ZTSSt5ctypeIcE # typeinfo name for std::ctype<char>
#_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE # typeinfo name for std::basic_ifstream<wchar_t, std::char_traits<wchar_t>>
#_ZTSSt12out_of_range # typeinfo name for std::out_of_range
#_ZTSSd # typeinfo name for std::basic_iostream<char, std::char_traits<char>>
#_ZTSSi # typeinfo name for std::basic_istream<char, std::char_traits<char>>
#_ZTSSo # typeinfo name for std::basic_ostream<char, std::char_traits<char>>
#_ZTSSt10__num_base # typeinfo name for std::__num_base
###############################################################################################
#_ZTJ
###############################################################################################
_ZTCN4Arts17StdoutWriter_implE68_NS_11Object_skelE # Arts::StdoutWriter_impl::construction_vtable[68]
_ZTCN4Arts20FileInputStream_implE0_NS_16SynthModule_baseE # Arts::FileInputStream_impl::construction_vtable[0]
_ZTCN4Arts20FileInputStream_implE112_NS_16InputStream_skelE # Arts::FileInputStream_impl::construction_vtable[112]
_ZTCN4Arts20FileInputStream_implE132_NS_16SynthModule_skelE # Arts::FileInputStream_impl::construction_vtable[132]
###############################################################################################
_ZGVZN10KDirLister11emitChangesEvE3dot # guard variable for KDirLister::emitChanges(void)::dot
_ZGVZN11KFileDialog16pathComboChangedERK7QStringE9localRoot # guard variable for KFileDialog::pathComboChanged(const_QString_&)::localRoot
_ZGVZNK17KSimpleFileFilter12passesFilterEPK9KFileItemE6dotdot # guard variable for KSimpleFileFilter::passesFilter(const_KFileItem_*)::dotdot
#_ZGVZN15KDirListerCache11slotEntriesEPN3KIO3JobERK10QValueListIS3_INS0_7UDSAtomEEEE3dot # guard variable for KDirListerCache::slotEntries(KIO::Job*,const QValueList<QValueList<KIO::USDAtom>> &)::dot
#_ZGVZN9__gnu_cxx20__common_pool_policyINS_6__poolELb1EE11_S_get_poolEvE7_S_pool # guard variable for __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true>::_S_get_pool()::_S_pool
_ZGRZNK17KSimpleFileFilter12passesFilterEPK9KFileItemE6dotdot # reference temporary for KSimpleFileFilter::passesFilter(const_KFileItem_*)::dotdot
#_ZGRZN15KDirListerCache11slotEntriesEPN3KIO3JobERK10QValueListIS3_INS0_7UDSAtomEEEE3dot # reference temporary for KDirListerCache::slotEntries(KIO::Job*,const QValueList<QValueList<KIO::USDAtom>> &)::dot
###############################################################################################
_ZZN11KFileDialog16staticMetaObjectEvE12param_slot_0 # KFileDialog::staticMetaObject(void)::param_slot_0
_ZZN11KFileDialog16staticMetaObjectEijE12param_slot_0 # KFileDialog::staticMetaObject(int,unsigned_int)::param_slot_0
_ZZN11KFileDialog16staticMetaObjectEvE12param_slot_1 # KFileDialog::staticMetaObject(void)::param_slot_1
_ZZNK9KFileItem6pixmapEiiE17defaultFolderIcon # KFileItem::pixmap(int,int)::defaultFolderIcon
_ZZNK10KDirLister13matchesFilterEPK9KFileItemE6dotdot # KDirLister::matchesFilter(const_KFileItem_*)::dotdot
_ZZN8Observer16staticMetaObjectEvE7slot_10 # Observer::staticMetaObject(void)::slot_10
_ZZN9KMimeType9findByURLERK4KURLjbbE9dotkdelnk # KMimeType::findByURL(const_KURL_&,unsigned_int,bool,bool)::dotkdelnk
_ZZN3KIO9http_postERK4KURLRK9QMemArrayIcEbE9bad_ports # KIO::http_post(const_KURL_&,const_QMemArray<char>_&,bool)::bad_ports
#_ZZN9__gnu_cxx20__common_pool_policyINS_6__poolELb1EE11_S_get_poolEvE7_S_pool # __gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true>::_S_get_pool()::_S_pool
###############################################################################################
_Znaj # operator<new>[](unsigned int)
_ZeqRK7QStringPKc # operator==(const QString &,const char *)
_ZdlPv # operator<delete>(void *)
_ZlsR11QDataStreamRK9QMemArrayIcE # operator<<(QDataStream &,const QMemArray<char> &)
_ZltRK7QStringS1_ # operator<(const QString &,const QString &)
#_ZlsI8QCStringER11QDataStreamS2_RK10QValueListIT_E # QDataStream&& operator<< <QCString>(QDataStream&, QValueList<QCString> const&)
_ZlsR16OutputCharStreamR11GroveString # operator<<(OutputCharStream &,GroveString &)
_ZeqRK6StringItEPKc # operator==(const String<unsigned short> &,const char *)
###############################################################################################
#
# OLD STYLE GNU GCC MANGLED NAMES
#
# These can be created using /usr/bin/gcc296.
#
###############################################################################################
###############################################################################################
# Functions...
###############################################################################################
__default_terminate__Fv # __default_terminate(void)
__fast_compare__FPCcT0 # __fast_compare(const char *,const char *)
pipeName__Fi # pipeName(int)
cocaConnect__FPCc # cocaConnect(const char *)
cocaConnectAction__FPvP6tTsTmr # cocaConnectAction(void *,tTsTmr *)
cocaMulticast__FP11msgGenStruc # cocaMulticast(msgGenStruc *)
mfgDataFill__FsP10tManufDataUiPc # mfgDataFill(short,tManufData *,unsigned int,char *)
printSem__FPP9semaphore # printSem(semaphore * *)
###############################################################################################
# Constructors...
###############################################################################################
__8ofstreamicii # ofstream::ofstream(int,char,int,int)
__8ofstreamiPcii # ofstream::ofstream(int,char *,int,int)
__8ofstreamiPCcii # ofstream::ofstream(int,const char *,int,int)
__8ofstreamiPCVcii # ofstream::ofstream(int,const volatile char *,int,int)
__11_ios_fields # _ios_fields::_ios_fields()
__11RtrvFsteCmdiPcT2 # RtrvFsteCmd::RtrvFsteCmd(int,char *,char *)
__17RtrvPmschedDsnCmdiPcT29MOD2_ENUM # RtrvPmschedDsnCmd::RtrvPmschedDsnCmd(int,char *,char *,MOD2_ENUM)
###############################################################################################
# Destructors...
###############################################################################################
_._8Document # Document::~Document()
_._8Documentfi # Document::~Document(float,int)
_._C8Documentcb # Document::~Document(char,bool) const
###############################################################################################
# C++ Methods...
###############################################################################################
__fb_init__11istreambase # istreambase::__fb_init()
flags__3iosUI # ios::flags(unsigned int0_t)
clear__8LogArrayUi # LogArray::clear(unsigned int)
isValid__8LogArrayUi # LogArray::isValid(unsigned int)
getDefaultValue__C12OpticsParKeyRlN21 # OpticsParKey::getDefaultValue(long &,long &,long &) const
getDefaultValue__C12OpticsParKeyRbN10_1 # OpticsParKey::getDefaultValue(bool &,bool &,bool &,bool &,bool &,bool &,bool &,bool &,bool &,bool &,bool &) const
getSsmRefStrip__8SyncImplRUcRScT1 # SyncImpl::getSsmRefStrip(unsigned char &,short &,char,unsigned char &)
###############################################################################################
__eq__C9type_infoRC9type_info # type_info::operator==(const type_info &) const
__ls__7ostreamP9streambuf # ostream::operator<<(streambuf *)
__opPc__C8MyString # MyString::operator char *() const
__opPb__C8MyString # MyString::operator bool *() const
__opl__C8MyStringi # MyString::operator long(int) const
###############################################################################################
setObjectId__14LmpGeneralImplPt9XpsUFLSeq2ZUcZUc # LmpGeneralImpl::setObjectId(XpsUFLSeq<unsigned char,unsigned char> *)
setObjectId__14LmpGeneralImplPt9XpsUFLSeq3ZUcZUcZUi # LmpGeneralImpl::setObjectId(XpsUFLSeq<unsigned char,unsigned char,unsigned int> *)
setObjectId__14LmpGeneralImplPt9XpsUFLSeq3ZUcZUcZUii # LmpGeneralImpl::setObjectId(XpsUFLSeq<unsigned char,unsigned char,unsigned int> *,int)
setObjectId__14LmpGeneralImplbPt9XpsUFLSeq3ZUcZUcZUii # LmpGeneralImpl::setObjectId(bool,XpsUFLSeq<unsigned char,unsigned char,unsigned int> *,int)
setObjectId__14LmpGeneralImplbPt9XpsUFLSeq10_ZbZbZbZbZbZbZbZbZbZbi # LmpGeneralImpl::setObjectId(bool,XpsUFLSeq<bool,bool,bool,bool,bool,bool,bool,bool,bool,bool> *,int)
###############################################################################################
# Function Pointers...
###############################################################################################
fPtr1__FPFi_fi # fPtr1(float (*)(int),int)
fPtr1__FPPFi_fi # fPtr1(float (**)(int),int)
fPtr1__FPFi_ci # fPtr1(char (*)(int),int)
fPtr1__FPFi_fiP9_MYSTRUCT # fPtr1(float (*)(int),int,_MYSTRUCT *)
fPtr1__FPFi_ciP9_MYSTRUCT # fPtr1(char (*)(int),int,_MYSTRUCT *)
fPtr2__FPFiPfc_fPFidPb_cidc # fPtr2(float (*)(int,float *,char),char (*)(int,double,bool *),int,double,char)
###############################################################################################
# Type Info...
###############################################################################################
__tf14ContentHandler # ContentHandler::type_info_function()
__tf11TreeHandler # TreeHandler::type_info_function()
__ti14ContentHandler # ContentHandler::type_info_node()
__ti9xml_error # xml_error::type_info_node()
###############################################################################################
_repository_id__C14CORBA_INV_FLAG # CORBA_INV_FLAG::_repository_id() const
_repository_id__Q210Ds123Media7General # Ds123Media::General::_repository_id()
_set_stub_factory__12CORBA_ObjectPFP7IOP_IOR_P12CORBA_Object # CORBA_Object::_set_stub_factory(CORBA_Object * (*)(IOP_IOR *))
_set_stub_factory__Q23Lmp7GeneralPFP7IOP_IOR_PQ23Lmp7General # Lmp::General::_set_stub_factory(Lmp::General * (*)(IOP_IOR *))
_factory__Q27FCTrunk12General_stubP7IOP_IOR # FCTrunk::General_stub::_factory(IOP_IOR *)
###############################################################################################
_4Node.FTAM_ERR_SEND_LOC_FILE # Node::FTAM_ERR_SEND_LOC_FILE
_4Node.SysErr # Node::SysErr
_4Rmon._tc__a_Rmon___CORBA__Char_21_32 # Rmon::_tc__a_Rmon___CORBA__Char_21_32
_6Optics._tc_General # Optics::_tc_General
_6XpsCDR.m_lut4 # XpsCDR::m_lut4
_7FCMedia._tc__a_FC___CORBA__Char_31_32 # FCMedia::_tc__a_FC___CORBA__Char_31_32
###############################################################################################
_GLOBAL_.D.chipSet # global destructors keyed to chipSet
_GLOBAL_.D.acHelp__Fv # global destructors keyed to acHelp(void)
_GLOBAL_.D.__7XcVtTblss # global destructors keyed to XcVtTbl::XcVtTbl(short,short)
_GLOBAL_.D._10ClientInfo.list # global destructors keyed to ClientInfo::list
_GLOBAL_.D.testCreateStsMonitor__FUiUiUiUiUiUiUi # global destructors keyed to testCreateStsMonitor(unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,unsigned int)
_GLOBAL_.D._._10opticalArc # global destructors keyed to opticalArc::~opticalArc()
_GLOBAL_.D.__10RollClientiPcPFPv_v # global destructors keyed to RollClient::RollClient(int,char *,void (*)(void *))
_GLOBAL_.D.__ls__FR7ostreamQ214OpticsTopology15eConnectionType # global destructors keyed to operator<<(ostream &,OpticsTopology::eConnectionType)
_GLOBAL_.D.__ls__FR7ostreamRC15CORBA_Exception # global destructors keyed to operator<<(ostream &,const CORBA_Exception &)
_GLOBAL_.D._release__4_var # global destructors keyed to _var::_release()
_GLOBAL_.D._type_id__12CORBA_Policy # global destructors keyed to CORBA_Policy::_type_id()
_GLOBAL_.D._type_id__Q22If15xAlsConfigError # global destructors keyed to If::xAlsConfigError::_type_id()
_GLOBAL_.D.__as__25tRmonAlarmPersistenceInfoRC28tRmonAlarmPersistenceInfo_V1 # global destructors keyed to tRmonAlarmPersistenceInfo::operator=(const tRmonAlarmPersistenceInfo_V1 &)
_GLOBAL_.D.__17RtrvRollClientStsiPcT29MOD2_ENUM # global destructors keyed to RtrvRollClientSts::RtrvRollClientSts(int,char *,char *,MOD2_ENUM)
###############################################################################################
_GLOBAL_.I.esiTable # global constructors keyed to esiTable
_GLOBAL_.I.corbaRmonAlarmAdminInfoGet__FUlPQ24Rmon15sAlarmAdminInfo # global constructors keyed to corbaRmonAlarmAdminInfoGet(unsigned long,Rmon::sAlarmAdminInfo *)
_GLOBAL_.I.convertVc4ToSts__12MetaRangeVc4i # global constructors keyed to MetaRangeVc4::convertVc4ToSts(int)
_GLOBAL_.I.acHelp__Fv # global constructors keyed to acHelp(void)
_GLOBAL_.I._10ClientInfo.list # global constructors keyed to ClientInfo::list
_GLOBAL_.I.__12PvmPluggable # global constructors keyed to PvmPluggable::PvmPluggable()
_GLOBAL_.I.__11FtpIoUploadPCcN41iUiRCQ25FtpIo12FttdConnInfo # global constructors keyed to FtpIoUpload::FtpIoUpload(const char *,const char *,const char *,const char *,const char *,int,unsigned int,const FtpIo::FttdConnInfo &)
_GLOBAL_.I.__17SetBulkRollClientiPcN429MOD2_ENUMPFPv_v # global constructors keyed to SetBulkRollClient::SetBulkRollClient(int,char *,char *,char *,char *,char *,MOD2_ENUM,void (*)(void *))
###############################################################################################
__t9allocator1ZP7Element # allocator<Element *>::allocator()
__t14XpsMapIterator2ZlZP14CORBA_TypeCode # XpsMapIterator<long,CORBA_TypeCode *>::XpsMapIterator()
__t6XpsMap2ZlZP14CORBA_TypeCodePFRCl_UlUlUlf # XpsMap<long,CORBA_TypeCode *>::XpsMap(unsigned long (*)(const long &),unsigned long,unsigned long,float)
_._t6XpsMap2ZlZP14CORBA_TypeCode # XpsMap<long,CORBA_TypeCode *>::~XpsMap()
_._t14XpsPolicy_impl1Zs # XpsPolicy_impl<short>::~XpsPolicy_impl()
_cast__Ct14XpsPolicy_impl1Zsl # XpsPolicy_impl<short>::_cast(long) const
erase__t6XpsMap2ZlZP14CORBA_TypeCode # XpsMap<long,CORBA_TypeCode *>::erase()
__vc__t6XpsMap2ZlZP14CORBA_TypeCodeRCl # XpsMap<long,CORBA_TypeCode *>::operator[](const long &)
###############################################################################################
_Q214LmpGeneralImpl13ProductConfig.dbVer # LmpGeneralImpl::ProductConfig::dbVer
###############################################################################################
invoke_request_wrapper__42PortableInterceptor_ClientRequestInfo_implUlP15IOP_ClientCodecR12CORBA_ObjectRt9XpsUFLSeq2ZUcZUcPcUlQ25CORBA13OperationModeUcP18CORBA_ReplyHandlerP9IOP_ParamUlT10_UlRt9XpsUVLSeq1ZQ23IOP14ServiceContextT14_RUcUxR17CORBA_Environment # PortableInterceptor_ClientRequestInfo_impl::invoke_request_wrapper(unsigned long,IOP_ClientCodec *,CORBA_Object &,XpsUFLSeq<unsigned char,unsigned char> &,char *,unsigned long,CORBA::OperationMode,unsigned char,CORBA_ReplyHandler *,IOP_Param *,unsigned long,IOP_Param *,unsigned long,XpsUVLSeq<IOP::ServiceContext> &,XpsUVLSeq<IOP::ServiceContext> &,unsigned char &,unsigned long long,CORBA_Environment &)
###############################################################################################
#get_codec_factory__8__ssliop # __ssliop::get_codec_factory()
#get_codec_factory__16__ssliop__ssliop # __ssliop__ssliop::get_codec_factory()
#get_codec_factory__8__ssliop # __ssliop::get_codec_factory()
#__get__codec__factory__16__ssliop__ssliop # __ssliop__ssliop::__get__codec__factory()
#__get__codec__4__factory__16__ssliop__ssliopi # __ssliop__ssliop::__get__codec__4__factory(int)
###############################################################################################

View File

@@ -0,0 +1,16 @@
__ZTV15_IOConfigThread #
__ZN8IOSyncer9metaClassE #
__ZN8IOSyncer10superClassE #
__ZN12KLDBootstrapD1Ev #
__ZN12KLDBootstrapD2Ev #
__ZN12KLDBootstrapC1Ev #
__ZN12KLDBootstrapC2Ev #
__ZL26kCharsetNameISOLatinHebrew
__ZN9__gnu_cxxL16__stl_prime_listE
__ZNSs6appendERKSs
__ZTV21MmsMessageClassHeader
__ZL30addRecipientsFromMmsWithHeaderPKcP10MmsMessageP9CTMessage # addRecipientsFromMmsWithHeader(char const*, MmsMessage*, CTMessage*)
__ZZN13MmsPduDecoder21_decodeMessageHeadersEP10MmsMessageE15requiredHeaders