GP-5505 Improved RecoverClassesFromRTTIScript abilty to use the LowCodeModeBit to find code references.

This commit is contained in:
ghidra007 2025-03-21 18:40:16 +00:00
parent fa554361d5
commit 2f83e26c0e
3 changed files with 217 additions and 246 deletions

View file

@ -16,52 +16,21 @@
//DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS. //DO NOT RUN. THIS IS NOT A SCRIPT! THIS IS A CLASS THAT IS USED BY SCRIPTS.
package classrecovery; package classrecovery;
import java.util.ArrayList; import java.util.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ghidra.app.cmd.function.CreateFunctionCmd; import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.plugin.core.analysis.ReferenceAddressPair; import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
import ghidra.app.util.PseudoDisassembler; import ghidra.app.util.PseudoDisassembler;
import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.Address; import ghidra.program.model.address.*;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.block.CodeBlock; import ghidra.program.model.block.CodeBlock;
import ghidra.program.model.block.IsolatedEntrySubModel; import ghidra.program.model.block.IsolatedEntrySubModel;
import ghidra.program.model.data.CategoryPath; import ghidra.program.model.data.*;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.IBO32DataType;
import ghidra.program.model.data.LongDataType;
import ghidra.program.model.data.Pointer;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.Structure;
import ghidra.program.model.data.Undefined4DataType;
import ghidra.program.model.data.Undefined8DataType;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Function; import ghidra.program.model.mem.*;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Listing;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.DumbMemBufferImpl;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.scalar.Scalar; import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.symbol.FlowType; import ghidra.program.model.symbol.*;
import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceIterator;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.model.symbol.SymbolType;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@ -133,6 +102,97 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
} }
} }
/**
* Method to determine if the given address contains a possible function pointer
* @param program the given program
*
* @param address the given address
* @return true if the given address contains a possible function pointer or
* false otherwise
* @throws CancelledException if cancelled
*/
public boolean isPossibleFunctionPointer(Program program, Address address)
throws CancelledException {
Address referencedAddress = getPointer(address);
if (referencedAddress == null) {
return false;
}
Address normalizedReferencedAddress =
PseudoDisassembler.getNormalizedDisassemblyAddress(program, referencedAddress);
if (normalizedReferencedAddress == null) {
return false;
}
Function function = getFunctionAt(normalizedReferencedAddress);
if (function != null) {
return true;
}
AddressSetView executeSet = program.getMemory().getExecuteSet();
if (!executeSet.contains(normalizedReferencedAddress)) {
return false;
}
Instruction instruction = getInstructionAt(normalizedReferencedAddress);
if (instruction != null) {
createFunction(normalizedReferencedAddress, null);
return true;
}
boolean disassemble = disassemble(normalizedReferencedAddress);
if (disassemble) {
Listing listing = program.getListing();
// check for the case where there is conflicting data at the thumb offset function
// pointer and if so clear the data and redisassemble and remove the bad bookmark
// long originalLongValue = extendedFlatAPI.getLongValueAt(address);
if (!referencedAddress.equals(normalizedReferencedAddress)) {
Data dataAt = listing.getDataAt(referencedAddress);
if (dataAt != null && dataAt.isDefined()) {
clearListing(referencedAddress);
disassemble = disassemble(address);
Bookmark bookmark =
getBookmarkAt(program, normalizedReferencedAddress, BookmarkType.ERROR,
"Bad Instruction", "conflicting data");
if (bookmark != null) {
removeBookmark(bookmark);
}
}
}
createFunction(normalizedReferencedAddress, null);
return true;
}
return false;
}
public Bookmark getBookmarkAt(Program program, Address address, String bookmarkType,
String category,
String commentContains) throws CancelledException {
Bookmark[] bookmarks = program.getBookmarkManager().getBookmarks(address);
for (Bookmark bookmark : bookmarks) {
monitor.checkCancelled();
if (bookmark.getType().getTypeString().equals(bookmarkType) &&
bookmark.getCategory().equals(category) &&
bookmark.getComment().contains(commentContains)) {
return bookmark;
}
}
return null;
}
/** /**
* Method to check to see if there is a valid function pointer at the given address. If it is * Method to check to see if there is a valid function pointer at the given address. If it is
* valid but not created, create it * valid but not created, create it
@ -255,8 +315,6 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
return null; return null;
} }
Address functionAddress = referencesFrom.get(0); Address functionAddress = referencesFrom.get(0);
Register lowBitCodeMode = currentProgram.getRegister("LowBitCodeMode"); Register lowBitCodeMode = currentProgram.getRegister("LowBitCodeMode");
@ -581,7 +639,6 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
return subroutineAddresses; return subroutineAddresses;
} }
/** /**
* Method to get a list of symbols either matching exactly (if exact flag is true) or containing (if exact flag is false) the given symbol name * Method to get a list of symbols either matching exactly (if exact flag is true) or containing (if exact flag is false) the given symbol name
* @param addressSet the address set to find matching symbols in * @param addressSet the address set to find matching symbols in
@ -856,7 +913,6 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
return false; return false;
} }
/** /**
* Method to retrieve a single referenced address from the given address * Method to retrieve a single referenced address from the given address
* @param address the given address to look for a single referenced address * @param address the given address to look for a single referenced address
@ -1363,5 +1419,4 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
return buffer.toString(); return buffer.toString();
} }
} }

View file

@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
import ghidra.app.cmd.label.DemanglerCmd; import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.plugin.core.analysis.ReferenceAddressPair; import ghidra.app.plugin.core.analysis.ReferenceAddressPair;
import ghidra.app.util.NamespaceUtils; import ghidra.app.util.NamespaceUtils;
import ghidra.app.util.PseudoDisassembler;
import ghidra.app.util.demangler.DemangledObject; import ghidra.app.util.demangler.DemangledObject;
import ghidra.app.util.demangler.DemanglerUtil; import ghidra.app.util.demangler.DemanglerUtil;
import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.ServiceProvider;
@ -31,7 +32,6 @@ import ghidra.program.flatapi.FlatProgramAPI;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.data.DataUtilities.ClearDataMode; import ghidra.program.model.data.DataUtilities.ClearDataMode;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.program.model.scalar.Scalar; import ghidra.program.model.scalar.Scalar;
@ -4395,60 +4395,51 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
*/ */
private boolean isPossibleFunctionPointer(Address address) throws CancelledException { private boolean isPossibleFunctionPointer(Address address) throws CancelledException {
// TODO: make one that works for all casea in helper Address referencedAddress = extendedFlatAPI.getSingleReferencedAddress(address);
if (referencedAddress == null) {
long longValue = extendedFlatAPI.getLongValueAt(address);
Register lowBitCodeMode = program.getRegister("LowBitCodeMode");
if (lowBitCodeMode != null) {
longValue = longValue & ~0x1;
}
Address possibleFunctionPointer = null;
try {
possibleFunctionPointer = address.getNewAddress(longValue);
}
catch (AddressOutOfBoundsException e) {
return false; return false;
} }
if (possibleFunctionPointer == null) { Address normalizedReferencedAddress =
PseudoDisassembler.getNormalizedDisassemblyAddress(program, referencedAddress);
if (normalizedReferencedAddress == null) {
return false; return false;
} }
Function function = api.getFunctionAt(possibleFunctionPointer); Function function = api.getFunctionAt(normalizedReferencedAddress);
if (function != null) { if (function != null) {
return true; return true;
} }
AddressSetView executeSet = program.getMemory().getExecuteSet(); AddressSetView executeSet = program.getMemory().getExecuteSet();
if (!executeSet.contains(possibleFunctionPointer)) { if (!executeSet.contains(normalizedReferencedAddress)) {
return false; return false;
} }
Instruction instruction = api.getInstructionAt(possibleFunctionPointer); Instruction instruction = api.getInstructionAt(normalizedReferencedAddress);
if (instruction != null) { if (instruction != null) {
api.createFunction(possibleFunctionPointer, null); api.createFunction(normalizedReferencedAddress, null);
return true; return true;
} }
boolean disassemble = api.disassemble(possibleFunctionPointer); boolean disassemble = api.disassemble(normalizedReferencedAddress);
if (disassemble) { if (disassemble) {
// check for the case where there is conflicting data at the thumb offset function // check for the case where there is conflicting data at the thumb offset function
// pointer and if so clear the data and redisassemble and remove the bad bookmark // pointer and if so clear the data and redisassemble and remove the bad bookmark
long originalLongValue = extendedFlatAPI.getLongValueAt(address); // long originalLongValue = extendedFlatAPI.getLongValueAt(address);
if (originalLongValue != longValue) { if (!referencedAddress.equals(normalizedReferencedAddress)) {
Address offsetPointer = address.getNewAddress(originalLongValue);
Data dataAt = listing.getDataAt(offsetPointer); Data dataAt = listing.getDataAt(referencedAddress);
if (dataAt != null && dataAt.isDefined()) { if (dataAt != null && dataAt.isDefined()) {
api.clearListing(offsetPointer); api.clearListing(referencedAddress);
disassemble = api.disassemble(address); disassemble = api.disassemble(address);
Bookmark bookmark = getBookmarkAt(possibleFunctionPointer, BookmarkType.ERROR, Bookmark bookmark =
getBookmarkAt(normalizedReferencedAddress, BookmarkType.ERROR,
"Bad Instruction", "conflicting data"); "Bad Instruction", "conflicting data");
if (bookmark != null) { if (bookmark != null) {
api.removeBookmark(bookmark); api.removeBookmark(bookmark);
@ -4456,7 +4447,7 @@ public class RTTIGccClassRecoverer extends RTTIClassRecoverer {
} }
} }
api.createFunction(possibleFunctionPointer, null); api.createFunction(normalizedReferencedAddress, null);
return true; return true;
} }
return false; return false;

View file

@ -20,7 +20,6 @@ import java.util.List;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.*; import ghidra.program.model.mem.*;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -64,9 +63,8 @@ public class Vtable {
DataTypeManager dataTypeManager; DataTypeManager dataTypeManager;
Listing listing; Listing listing;
public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef,
boolean isSpecial, boolean inExternalMemory,
public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef, boolean isSpecial, boolean inExternalMemory,
Vtable primaryVtable, Boolean isConstruction, TaskMonitor monitor) Vtable primaryVtable, Boolean isConstruction, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
@ -96,14 +94,17 @@ public class Vtable {
setup(); setup();
} }
public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef, boolean isSpecial, boolean inExternalMemory, TaskMonitor monitor) public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef,
boolean isSpecial, boolean inExternalMemory, TaskMonitor monitor)
throws CancelledException { throws CancelledException {
this(program, vtableAddress, typeinfoRef, isSpecial, inExternalMemory, null, null, monitor); this(program, vtableAddress, typeinfoRef, isSpecial, inExternalMemory, null, null, monitor);
} }
public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef, boolean isSpecial, boolean inExternalMemory, boolean isConstruction, public Vtable(Program program, Address vtableAddress, GccTypeinfoRef typeinfoRef,
boolean isSpecial, boolean inExternalMemory, boolean isConstruction,
TaskMonitor monitor) throws CancelledException { TaskMonitor monitor) throws CancelledException {
this(program, vtableAddress, typeinfoRef, isSpecial, inExternalMemory, null, isConstruction, monitor); this(program, vtableAddress, typeinfoRef, isSpecial, inExternalMemory, null, isConstruction,
monitor);
} }
protected void setup() throws CancelledException { protected void setup() throws CancelledException {
@ -146,7 +147,8 @@ public class Vtable {
try { try {
applyVtableData(); applyVtableData();
} catch (Exception e) { }
catch (Exception e) {
isValid = false; isValid = false;
} }
@ -196,7 +198,6 @@ public class Vtable {
return isValid; return isValid;
} }
public Address getTypeinfoRefAddress() { public Address getTypeinfoRefAddress() {
return typeinfoRef.getAddress(); return typeinfoRef.getAddress();
} }
@ -227,7 +228,8 @@ public class Vtable {
} }
topOffsetValue = extendedFlatAPI.getLongValueAt(topOffset); topOffsetValue = extendedFlatAPI.getLongValueAt(topOffset);
} catch (IllegalArgumentException e) { }
catch (IllegalArgumentException e) {
Msg.debug(this, "Invalid vtable: " + vtableAddress.toString() + " No offset field"); Msg.debug(this, "Invalid vtable: " + vtableAddress.toString() + " No offset field");
isValid = false; isValid = false;
} }
@ -252,7 +254,8 @@ public class Vtable {
// otherwise, use the topOffsetValue to figure it out // otherwise, use the topOffsetValue to figure it out
if (topOffsetValue == 0L) { if (topOffsetValue == 0L) {
isPrimary = true; isPrimary = true;
} else { }
else {
isPrimary = false; isPrimary = false;
} }
} }
@ -293,11 +296,13 @@ public class Vtable {
numVfunctions = getNumFunctionPointers(possVfunctionTop, true, false); numVfunctions = getNumFunctionPointers(possVfunctionTop, true, false);
if (numVfunctions == 0) { if (numVfunctions == 0) {
hasVfunctions = false; hasVfunctions = false;
} else { }
else {
hasVfunctions = true; hasVfunctions = true;
vfunctionTop = possVfunctionTop; vfunctionTop = possVfunctionTop;
} }
} catch (AddressOutOfBoundsException e) { }
catch (AddressOutOfBoundsException e) {
hasVfunctions = false; hasVfunctions = false;
} }
@ -311,14 +316,16 @@ public class Vtable {
// if it has a primary non-default symbol and it isn't "vftable" then it isn't a vftable // if it has a primary non-default symbol and it isn't "vftable" then it isn't a vftable
Symbol primarySymbol = symbolTable.getPrimarySymbol(topAddress); Symbol primarySymbol = symbolTable.getPrimarySymbol(topAddress);
if(primarySymbol != null && primarySymbol.getSource() != SourceType.DEFAULT && !primarySymbol.getName().contains("vftable")) { if (primarySymbol != null && primarySymbol.getSource() != SourceType.DEFAULT &&
!primarySymbol.getName().contains("vftable")) {
return numFunctionPointers; return numFunctionPointers;
} }
MemoryBlock currentBlock = program.getMemory().getBlock(topAddress); MemoryBlock currentBlock = program.getMemory().getBlock(topAddress);
boolean stillInCurrentTable = true; boolean stillInCurrentTable = true;
while (address != null && currentBlock.contains(address) && stillInCurrentTable while (address != null && currentBlock.contains(address) && stillInCurrentTable &&
&& (isPossibleFunctionPointer(address) || (allowNullFunctionPtrs && isPossibleNullPointer(address)))) { (extendedFlatAPI.isPossibleFunctionPointer(program, address) ||
(allowNullFunctionPtrs && isPossibleNullPointer(address)))) {
numFunctionPointers++; numFunctionPointers++;
address = address.add(defaultPointerSize); address = address.add(defaultPointerSize);
@ -345,7 +352,8 @@ public class Vtable {
// check to see if last is null ptr and next addr after that is typeinfo ref - indicating the null is really top of next vtable // check to see if last is null ptr and next addr after that is typeinfo ref - indicating the null is really top of next vtable
Address lastAddress = topAddress.add((numFunctionPointers - 1) * defaultPointerSize); Address lastAddress = topAddress.add((numFunctionPointers - 1) * defaultPointerSize);
if(isPossibleNullPointer(lastAddress) && (isTypeinfoRef(lastAddress.add(defaultPointerSize)))){ if (isPossibleNullPointer(lastAddress) &&
(isTypeinfoRef(lastAddress.add(defaultPointerSize)))) {
numFunctionPointers--; numFunctionPointers--;
} }
return numFunctionPointers; return numFunctionPointers;
@ -382,97 +390,6 @@ public class Vtable {
return true; return true;
} }
/**
* Method to determine if the given address contains a possible function pointer
*
* @param address the given address
* @return true if the given address contains a possible function pointer or
* false otherwise
* @throws CancelledException if cancelled
*/
private boolean isPossibleFunctionPointer(Address address) throws CancelledException {
long longValue = extendedFlatAPI.getLongValueAt(address);
Register lowBitCodeMode = program.getRegister("LowBitCodeMode");
if (lowBitCodeMode != null) {
longValue = longValue & ~0x1;
}
Address possibleFunctionPointer = null;
try {
possibleFunctionPointer = address.getNewAddress(longValue);
} catch (AddressOutOfBoundsException e) {
return false;
}
if (possibleFunctionPointer == null) {
return false;
}
Function function = extendedFlatAPI.getFunctionAt(possibleFunctionPointer);
if (function != null) {
return true;
}
AddressSetView executeSet = program.getMemory().getExecuteSet();
if (!executeSet.contains(possibleFunctionPointer)) {
return false;
}
Instruction instruction = extendedFlatAPI.getInstructionAt(possibleFunctionPointer);
if (instruction != null) {
extendedFlatAPI.createFunction(possibleFunctionPointer, null);
return true;
}
boolean disassemble = extendedFlatAPI.disassemble(possibleFunctionPointer);
if (disassemble) {
// check for the case where there is conflicting data at the thumb offset
// function
// pointer and if so clear the data and redisassemble and remove the bad
// bookmark
long originalLongValue = extendedFlatAPI.getLongValueAt(address);
if (originalLongValue != longValue) {
Address offsetPointer = address.getNewAddress(originalLongValue);
if (extendedFlatAPI.getDataAt(offsetPointer) != null) {
extendedFlatAPI.clearListing(offsetPointer);
disassemble = extendedFlatAPI.disassemble(address);
Bookmark bookmark = getBookmarkAt(possibleFunctionPointer, BookmarkType.ERROR, "Bad Instruction",
"conflicting data");
if (bookmark != null) {
extendedFlatAPI.removeBookmark(bookmark);
}
}
}
extendedFlatAPI.createFunction(possibleFunctionPointer, null);
return true;
}
return false;
}
private Bookmark getBookmarkAt(Address address, String bookmarkType, String category, String commentContains)
throws CancelledException {
Bookmark[] bookmarks = program.getBookmarkManager().getBookmarks(address);
for (Bookmark bookmark : bookmarks) {
monitor.checkCancelled();
if (bookmark.getType().getTypeString().equals(bookmarkType) && bookmark.getCategory().equals(category)
&& bookmark.getComment().contains(commentContains)) {
return bookmark;
}
}
return null;
}
public void setHasVfunctions(boolean flag) { public void setHasVfunctions(boolean flag) {
hasVfunctions = flag; hasVfunctions = flag;
} }
@ -492,7 +409,8 @@ public class Vtable {
return; return;
} }
if (!hasVfunctions) { if (!hasVfunctions) {
length = (int) (typeinfoRefAddress.getOffset() + defaultPointerSize - vtableAddress.getOffset()); length = (int) (typeinfoRefAddress.getOffset() + defaultPointerSize -
vtableAddress.getOffset());
return; return;
} }
@ -548,19 +466,21 @@ public class Vtable {
Address nextAddr = vtableAddress.add(length); Address nextAddr = vtableAddress.add(length);
Address typeinfoAddr = typeinfo.getAddress(); Address typeinfoAddr = typeinfo.getAddress();
int alignment = nextAddr.getSize() / 8; int alignment = nextAddr.getSize() / 8;
Address nextTypeinfoRefAddr = getNextReferenceTo(nextAddr, typeinfoAddr, alignment, limit); Address nextTypeinfoRefAddr =
getNextReferenceTo(nextAddr, typeinfoAddr, alignment, limit);
if (nextTypeinfoRefAddr == null) { if (nextTypeinfoRefAddr == null) {
keepChecking = false; keepChecking = false;
continue; continue;
} }
GccTypeinfoRef internalTypenfoRef = new GccTypeinfoRef(nextTypeinfoRefAddr, typeinfo, true); GccTypeinfoRef internalTypenfoRef =
new GccTypeinfoRef(nextTypeinfoRefAddr, typeinfo, true);
Vtable possibleInternalVtable = new Vtable(program, nextAddr,internalTypenfoRef, isSpecial, inExternalMemory, Vtable possibleInternalVtable =
new Vtable(program, nextAddr, internalTypenfoRef, isSpecial, inExternalMemory,
this, isConstruction, monitor); this, isConstruction, monitor);
if (!possibleInternalVtable.isValid()) { if (!possibleInternalVtable.isValid()) {
keepChecking = false; keepChecking = false;
@ -575,14 +495,16 @@ public class Vtable {
Namespace internalVtableNamespace = possibleInternalVtable.getNamespace(); Namespace internalVtableNamespace = possibleInternalVtable.getNamespace();
if (internalVtableNamespace != null && internalVtableNamespace.equals(classNamespace)) { if (internalVtableNamespace != null && internalVtableNamespace.equals(classNamespace)) {
addInternalVtable(possibleInternalVtable); addInternalVtable(possibleInternalVtable);
} else { }
else {
keepChecking = false; keepChecking = false;
} }
} }
} }
private Address getNextReferenceTo(Address startAddress, Address refdAddress, int alignment, int limit) { private Address getNextReferenceTo(Address startAddress, Address refdAddress, int alignment,
int limit) {
int offset = alignment; int offset = alignment;
while (offset < limit) { while (offset < limit) {
@ -635,7 +557,8 @@ public class Vtable {
// if not primary and the primary has same namespace then it is an internal // if not primary and the primary has same namespace then it is an internal
// vtable and can // vtable and can
// set the namespace to the typeinfo namespace // set the namespace to the typeinfo namespace
if (!primaryVtable.getNamespace().isGlobal() && primaryVtable.getNamespace().equals(typeinfoNamespace)) { if (!primaryVtable.getNamespace().isGlobal() &&
primaryVtable.getNamespace().equals(typeinfoNamespace)) {
setNamespace(typeinfoNamespace); setNamespace(typeinfoNamespace);
return; return;
} }
@ -707,7 +630,8 @@ public class Vtable {
try { try {
Data vftableArrayData = listing.createData(vftableAddress, vftableArrayDataType); Data vftableArrayData = listing.createData(vftableAddress, vftableArrayDataType);
return vftableArrayData; return vftableArrayData;
} catch (Exception e) { }
catch (Exception e) {
return null; return null;
} }
@ -751,7 +675,8 @@ public class Vtable {
try { try {
Address newAddress = address.add(offset); Address newAddress = address.add(offset);
return newAddress; return newAddress;
} catch (AddressOutOfBoundsException e) { }
catch (AddressOutOfBoundsException e) {
return null; return null;
} }
} }