Created
February 3, 2020 19:20
-
-
Save FrankSpierings/3b5e7a1f6c6d791b263765af1fd1d0fe to your computer and use it in GitHub Desktop.
Ghidra Script - Example of showing function call parameters within a function using the decompiler.
This file contains hidden or 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
#Example of showing function call parameters within a function using the decompiler. | |
#@author Frank Spierings | |
#@category | |
#@keybinding | |
#@menupath | |
#@toolbar | |
import ghidra.app.decompiler.DecompInterface as DecompInterface | |
import ghidra.app.decompiler.ClangTokenGroup as ClangTokenGroup | |
import ghidra.app.decompiler.ClangStatement as ClangStatement | |
import ghidra.app.decompiler.ClangFuncNameToken as ClangFuncNameToken | |
import ghidra.app.decompiler.ClangVariableToken as ClangVariableToken | |
import ghidra.program.model.data.Pointer as Pointer | |
import json | |
def get_functions(name): | |
return [f for f in currentProgram.getFunctionManager().getFunctions(True) if name in f.getName()] | |
def process_clang_token_group(ctg, results=[]): | |
tokens = (ctg.Child(i) for i in range(ctg.numChildren())) | |
for token in tokens: | |
# The body of a function is a token group as well as a statement is a token group | |
if type(token) == ClangTokenGroup: | |
results = process_clang_token_group(token, results=results) | |
elif type(token) == ClangStatement: | |
# print('{0} = {1}'.format(token.__class__.__name__, token)) | |
elements = (token.Child(i) for i in range(token.numChildren())) | |
index = 0 | |
isFunc = False | |
# Elements withing a statement, like a function call | |
for element in elements: | |
if type(element) == ClangFuncNameToken: | |
# print('Function: {0}'.format(element)) | |
isFunc = True | |
results.append({ | |
# 'address_min': str(element.getMinAddress()), | |
# 'address_max': str(element.getMaxAddress()), | |
'address': str(element.getMinAddress()), | |
'name': str(element), | |
'params': [] | |
}) | |
elif type(element) == ClangVariableToken: | |
# If we started in a function, continue processing parameters | |
if isFunc: | |
# print('Parameter[{0}]: {1}'.format(index, element)) | |
index += 1 | |
value = process_clang_variable_token(element) | |
param = {'value': value, | |
'address': str(element.getMinAddress())} | |
results[-1]['params'].append(param) | |
else: | |
pass | |
return results | |
def process_clang_variable_token(var): | |
listing = currentProgram.getListing() | |
address = var.getHighVariable().getStorage().getMinAddress() | |
if address: | |
value = listing.getDataAt(address) | |
if value: | |
if isinstance(value.getDataType(), Pointer): | |
ptr = value | |
value = listing.getDataAt(ptr.getValue()) | |
if not value: | |
value = '' | |
else: | |
value = value.getDefaultValueRepresentation() | |
return str(value) | |
else: | |
return str(value) | |
else: | |
return str(var) | |
else: | |
return str(var) | |
def process_code(func): | |
di = DecompInterface() | |
di.openProgram(currentProgram) | |
dr = di.decompileFunction(func, 2000, monitor); | |
df = dr.getDecompiledFunction() | |
if df: | |
print(df.c) | |
pass | |
r = process_clang_token_group(dr.getCCodeMarkup()) | |
print(json.dumps(r, indent=True)) | |
for f in get_functions('some_function'): | |
print(f) | |
process_code(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment