Ghidra Python - 获取特定函数的 x-refs

逆向工程 Python 吉德拉
2021-06-19 14:50:29

为特定函数调用 x-refs 的最佳方法是什么?

我知道以下方法:

func = getFirstFunction()

while func is not None:
    func_name = func.getName()
    if func_name == <my_func>:
        entry_point = func.getEntryPoint()
        references = getReferencesTo(entry_point)

func = getFunctionAfter(func)

有没有办法在不遍历所有函数的情况下做到这一点?

3个回答

getReferencesTo 获取地址

toAddr() 将字符串转换为地址,您可以将两者结合

像这样

>>> getReferencesTo(toAddr("ZwCreateKey"))

array(ghidra.program.model.symbol.Reference, 
[
From: 14095680c To: 1401b33c0 Type: DATA Op: 0 IMPORTED, 
From: 140a22fbd To: 1401b33c0 Type: DATA Op: 0 DEFAULT, 
From: Entry Point To: 1401b33c0 Type: EXTERNAL Op: -1 DEFAULT, 
From: 140628dc5 To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1407478dd To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1406bdfcd To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1408db10c To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1406f5dec To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1407c7190 To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1407d01da To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 
From: 1405a8745 To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT, 

如果有更多使用推荐的 ReferenceManager,该功能将其显示限制为最大 4096 参考

>>> refs = currentProgram.referenceManager.getReferencesTo(toAddr("ZwCreateKey"))
>>> for i in refs:
...     print i
... 
From: 14095680c To: 1401b33c0 Type: DATA Op: 0 IMPORTED
From: 140a22fbd To: 1401b33c0 Type: DATA Op: 0 DEFAULT
From: Entry Point To: 1401b33c0 Type: EXTERNAL Op: -1 DEFAULT
From: 140628dc5 To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT
From: 1407478dd To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT
From: 1406bdfcd To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT
From: 1408db10c To: 1401b33c0 Type: UNCONDITIONAL_CALL Op: 0 DEFAULT

我不认为有一种方法可以按名称过滤函数,但是您可以使用 lambda 表达式将上述内容写得更简洁一些,并使用更多功能的方法。

fm = currentProgram.getFunctionManager()
funcs = fm.getFunctions(True)
filtered_funcs = filter(lambda f: f.getName() == '<your function name>', funcs)
x_refs = map(lambda f: getReferencesTo(f.getEntryPoint()), filtered_funcs)

您甚至可以将它们折叠得更多,但(可能)会损害可读性。

这可以通过符号表实现:

sym = currentProgram.symbolTable.getSymbol(func_name)

func = currentProgram.functionManager.getFunction(sym.key)
# the following should be equivalent
func = currentProgram.functionManager.getFunctionAt(sym.address)

refs = getReferencesTo(func.entryPoint)

在这种情况下的符号是 Ghidra 函数符号,不是那种可能包含在二进制中但可以被剥离的符号。它适用于诸如FUN_100008628entry或您重命名的任何函数之类的名称。