-
-
Save jordanpotti/a077a3cace599a156a7afe713dff58dc to your computer and use it in GitHub Desktop.
Convert Ghidra Call Trees to JSON for Neo4j Ingestion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#@author matterpreter | |
#@category | |
#@keybinding | |
#@menupath | |
#@toolbar | |
### | |
# To import to Neo4j: | |
# CREATE CONSTRAINT function_name ON (n:Function) ASSERT n.name IS UNIQUE | |
# | |
# Note: If you want to store this file on the Neo4j server, put it in /var/lib/neo4j/import/ | |
# | |
# CALL apoc.load.json("file:///xrefs.json") YIELD value | |
# UNWIND value as func | |
# MERGE (n:Function {name: func.FunctionName}) | |
# SET n.entrypoint=func.EntryPoint | |
# WITH n, func | |
# UNWIND func.CalledBy as cb | |
# MERGE (m:Function {name:cb}) | |
# MERGE (m)-[:Calls]->(n) | |
### | |
import json | |
# Collect all functions | |
fm = currentProgram.getFunctionManager() | |
funcs = fm.getFunctions(True) # True means 'forward' | |
f = open("xrefs.json", 'w') | |
data = [] | |
for func in funcs: | |
x = {} | |
x["FunctionName"] = func.getName() | |
x["EntryPoint"] = "0x{}".format(func.getEntryPoint()) | |
# Enumerate all of the inbound calls to the function | |
incomingRefs = getReferencesTo(func.getEntryPoint()) | |
refs = [] | |
for ref in incomingRefs: | |
fromAddr = ref.getFromAddress() | |
try: | |
refs.append(getFunctionContaining(fromAddr).getName()) | |
print(" Called by: {} @ 0x{}".format(getFunctionContaining(fromAddr), fromAddr)) | |
except: | |
continue | |
x["CalledBy"] = list(set(refs)) # Remove duplicates by converting to a set | |
data.append(x) | |
y = json.dumps(data, sort_keys=True, indent=4) | |
f.write(y) | |
f.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment