mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 14:54:29 +08:00
Merge remote-tracking branch 'origin/Ghidra_12.1'
This commit is contained in:
+16
@@ -46,6 +46,7 @@ import ghidra.framework.plugintool.ComponentProviderAdapter;
|
|||||||
import ghidra.program.database.symbol.FunctionSymbol;
|
import ghidra.program.database.symbol.FunctionSymbol;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
|
import ghidra.program.model.symbol.ExternalLocation;
|
||||||
import ghidra.program.model.symbol.Symbol;
|
import ghidra.program.model.symbol.Symbol;
|
||||||
import ghidra.program.util.*;
|
import ghidra.program.util.*;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
@@ -757,7 +758,22 @@ public class CallTreeProvider extends ComponentProviderAdapter {
|
|||||||
isFiringNavigationEvent = true;
|
isFiringNavigationEvent = true;
|
||||||
GoToService goToService = tool.getService(GoToService.class);
|
GoToService goToService = tool.getService(GoToService.class);
|
||||||
if (goToService != null) {
|
if (goToService != null) {
|
||||||
|
Address locAddr = location.getAddress();
|
||||||
|
if (locAddr.isExternalAddress()) {
|
||||||
|
// NOTE: The simple form of GoTo(ProgramLocation) will always goto the linkage
|
||||||
|
// point and not the actual external program. We use the special form for
|
||||||
|
// external location to ensure it respects the navigation options.
|
||||||
|
Symbol symbol = currentProgram.getSymbolTable().getPrimarySymbol(locAddr);
|
||||||
|
if (symbol != null) {
|
||||||
|
ExternalLocation externalLocation =
|
||||||
|
currentProgram.getExternalManager().getExternalLocation(symbol);
|
||||||
|
goToService.goToExternalLocation(goToService.getDefaultNavigatable(),
|
||||||
|
externalLocation, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
goToService.goTo(location);
|
goToService.goTo(location);
|
||||||
|
}
|
||||||
isFiringNavigationEvent = false;
|
isFiringNavigationEvent = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-14
@@ -89,10 +89,61 @@ public class IncomingCallNode extends CallNode {
|
|||||||
private void doGenerateChildren(Address address, List<GTreeNode> results, TaskMonitor monitor)
|
private void doGenerateChildren(Address address, List<GTreeNode> results, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
|
|
||||||
ReferenceIterator refIter = program.getReferenceManager().getReferencesTo(address);
|
|
||||||
LazyMap<Function, List<GTreeNode>> nodesByFunction =
|
LazyMap<Function, List<GTreeNode>> nodesByFunction =
|
||||||
LazyMap.lazyMap(new HashMap<>(), k -> new ArrayList<>());
|
LazyMap.lazyMap(new HashMap<>(), k -> new ArrayList<>());
|
||||||
FunctionManager functionManager = program.getFunctionManager();
|
FunctionManager functionManager = program.getFunctionManager();
|
||||||
|
|
||||||
|
Set<Address> thunkAddrSet = Set.of();
|
||||||
|
Function currentFunction = functionManager.getFunctionAt(address);
|
||||||
|
if (currentFunction != null) {
|
||||||
|
|
||||||
|
if (currentFunction.isThunk() && !callTreeOptions.allowsThunks()) {
|
||||||
|
// If this is a thunk and thunks are filtered-out we must force current function
|
||||||
|
// to the real function
|
||||||
|
currentFunction = currentFunction.getThunkedFunction(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if current function is thunked
|
||||||
|
Address[] functionThunkAddresses =
|
||||||
|
currentFunction.getFunctionThunkAddresses(!callTreeOptions.allowsThunks());
|
||||||
|
if (functionThunkAddresses != null) {
|
||||||
|
thunkAddrSet = Set.of(functionThunkAddresses);
|
||||||
|
for (Address thunkAddr : functionThunkAddresses) {
|
||||||
|
if (address.equals(thunkAddr)) {
|
||||||
|
continue; // avoid possible recursive thunk (should not occur)
|
||||||
|
}
|
||||||
|
Function thunkFunction = functionManager.getFunctionAt(thunkAddr);
|
||||||
|
if (callTreeOptions.allowsThunks()) {
|
||||||
|
// include thunk node in tree
|
||||||
|
IncomingCallNode node =
|
||||||
|
new IncomingCallNode(program, thunkFunction, thunkAddr, true,
|
||||||
|
callTreeOptions);
|
||||||
|
addNode(nodesByFunction, node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do NOT include thunk in tree but follow references to the thunk
|
||||||
|
collectIncomingByReference(thunkAddr, nodesByFunction, thunkAddrSet,
|
||||||
|
monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collectIncomingByReference(address, nodesByFunction, thunkAddrSet, monitor);
|
||||||
|
|
||||||
|
List<GTreeNode> children = nodesByFunction.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(list -> list.stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
results.addAll(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectIncomingByReference(Address address,
|
||||||
|
LazyMap<Function, List<GTreeNode>> nodesByFunction,
|
||||||
|
Set<Address> ignoreFromSet, TaskMonitor monitor)
|
||||||
|
throws CancelledException {
|
||||||
|
FunctionManager functionManager = program.getFunctionManager();
|
||||||
|
ReferenceIterator refIter = program.getReferenceManager().getReferencesTo(address);
|
||||||
while (refIter.hasNext()) {
|
while (refIter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
Reference ref = refIter.next();
|
Reference ref = refIter.next();
|
||||||
@@ -102,13 +153,8 @@ public class IncomingCallNode extends CallNode {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are not showing thunks, then replace each thunk with all calls to that thunk
|
if (ignoreFromSet.contains(caller.getEntryPoint())) {
|
||||||
if (caller.isThunk() && !callTreeOptions.allowsThunks()) {
|
continue; // ignore references for a thunk relationship (e.g., jump, etc.)
|
||||||
Address callerEntry = caller.getEntryPoint();
|
|
||||||
if (!address.equals(callerEntry)) { // recursive reference from thunk to itself
|
|
||||||
doGenerateChildren(callerEntry, results, monitor);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IncomingCallNode node =
|
IncomingCallNode node =
|
||||||
@@ -116,12 +162,6 @@ public class IncomingCallNode extends CallNode {
|
|||||||
callTreeOptions);
|
callTreeOptions);
|
||||||
addNode(nodesByFunction, node);
|
addNode(nodesByFunction, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GTreeNode> children = nodesByFunction.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(list -> list.stream())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
results.addAll(children);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+25
-9
@@ -87,12 +87,34 @@ public class OutgoingCallNode extends CallNode {
|
|||||||
Function currentFunction = fm.getFunctionContaining(address);
|
Function currentFunction = fm.getFunctionContaining(address);
|
||||||
LazyMap<Function, List<GTreeNode>> nodesByFunction =
|
LazyMap<Function, List<GTreeNode>> nodesByFunction =
|
||||||
LazyMap.lazyMap(new HashMap<>(), k -> new ArrayList<>());
|
LazyMap.lazyMap(new HashMap<>(), k -> new ArrayList<>());
|
||||||
FunctionManager functionManager = program.getFunctionManager();
|
|
||||||
ReferenceManager refManager = program.getReferenceManager();
|
|
||||||
|
|
||||||
|
if (currentFunction.isThunk()) {
|
||||||
|
Function thunkedFunction =
|
||||||
|
currentFunction.getThunkedFunction(!callTreeOptions.allowsThunks());
|
||||||
|
ThunkReference thunkRef = new ThunkReference(currentFunction.getEntryPoint(),
|
||||||
|
thunkedFunction.getEntryPoint());
|
||||||
|
createNode(nodesByFunction, thunkRef, thunkedFunction);
|
||||||
|
}
|
||||||
|
else {
|
||||||
AddressRangeIterator rangeIter = currentFunction.getBody().getAddressRanges();
|
AddressRangeIterator rangeIter = currentFunction.getBody().getAddressRanges();
|
||||||
while (rangeIter.hasNext()) {
|
while (rangeIter.hasNext()) {
|
||||||
AddressRange range = rangeIter.next();
|
AddressRange range = rangeIter.next();
|
||||||
|
collectOutgoingByReference(range, nodesByFunction, monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GTreeNode> children = nodesByFunction.values()
|
||||||
|
.stream()
|
||||||
|
.flatMap(list -> list.stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
results.addAll(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectOutgoingByReference(AddressRange range,
|
||||||
|
LazyMap<Function, List<GTreeNode>> nodesByFunction,
|
||||||
|
TaskMonitor monitor) throws CancelledException {
|
||||||
|
FunctionManager functionManager = program.getFunctionManager();
|
||||||
|
ReferenceManager refManager = program.getReferenceManager();
|
||||||
ReferenceIterator refIter = refManager.getReferenceIterator(range.getMinAddress());
|
ReferenceIterator refIter = refManager.getReferenceIterator(range.getMinAddress());
|
||||||
while (refIter.hasNext()) {
|
while (refIter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
@@ -103,6 +125,7 @@ public class OutgoingCallNode extends CallNode {
|
|||||||
Address toAddress = reference.getToAddress();
|
Address toAddress = reference.getToAddress();
|
||||||
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
||||||
if (calledFunction == null) {
|
if (calledFunction == null) {
|
||||||
|
// Assume analysis has not be run fully
|
||||||
createNode(nodesByFunction, reference, calledFunction);
|
createNode(nodesByFunction, reference, calledFunction);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -118,13 +141,6 @@ public class OutgoingCallNode extends CallNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GTreeNode> children = nodesByFunction.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(list -> list.stream())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
results.addAll(children);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createNode(LazyMap<Function, List<GTreeNode>> nodes, Reference reference,
|
private void createNode(LazyMap<Function, List<GTreeNode>> nodes, Reference reference,
|
||||||
Function calledFunction) {
|
Function calledFunction) {
|
||||||
Address fromAddress = reference.getFromAddress();
|
Address fromAddress = reference.getFromAddress();
|
||||||
|
|||||||
Reference in New Issue
Block a user