如何使用radare2查找从当前偏移量到给定地址的路径?

逆向工程 雷达2 调用图
2021-06-14 07:55:04

根据 Radare2 文档,这是查找路径的命令:

agt [addr]            find paths from current offset to given address

但是当我尝试该命令时,在运行aaaaa分析后,出现以下错误:

[0x00430044]> agt 0x0042aa98 > agtoutput.dot
Unable to find source or destination basic block

我可以确认这两个地址是函数,我可以单独绘制每个函数。此外,0x00430044确实导致0x0042aa98. 我可以从 gdb 跟踪中看到这一点。我查看了radare2 canal.c 代码 ,发现它正在查看RAnalFunction->bbs提供的地址。我尝试通过运行确保 bbs 填充了这些地址abb $s

abb [length]         analyze N bytes and extract basic blocks 

并将输出反馈到 r2。abb $s从各个地方跑来看看它是否会将基本块添加到 bbs 列表中。在不同地点分别为0x00x004300440x0042aa98但是没有任何效果,我总是收到“无法找到源或目标基本块”的错误消息。我可能会离开并进入兔子洞,但是“查找路径”功能非常有用,我真的很想让它工作吗?任何有关使用记录的agt功能的帮助将不胜感激。

2个回答

似乎该功能尚未实现。正如你在这个函数中看到的

...
if (root && dest) {
    if (dest == root) {
        eprintf ("Source and destination are the same\n");
        return NULL;
    }
    eprintf ("ROOT BB 0x%08"PFMT64x"\n", root->addr);
    eprintf ("DEST BB 0x%08"PFMT64x"\n", dest->addr);
    list = r_list_new ();
    printf ("=>  0x%08"PFMT64x"\n", root->jump);
} else {
    eprintf ("Unable to find source or destination basic block\n");
}
return list;
...

随意在官方存储库中打开一个问题,或者更好——为了我们所有人的利益,尝试自己实现它。

最后一件事,不要使用aaaaa,它甚至不存在,之后的任何分析命令aaa都是实验性的,可能会给您带来错误。反正你不用分析得那么深入。

有关radare2 中分析的更多信息,请参阅此答案

当我意识到这个功能没有实现时,我做了一个变通办法来得到我想要的。我输出了完整的程序调用图,然后制作了一个非常简单的 python 脚本,它使用 networkx 来查找节点之间的路径。这并不理想,但可以完成工作。

在radare2中,我将完整的程序调用图输出到一个.dot文件:

agC > agCfullProgramCallGraph.dot

然后我有一个 python 脚本,它获取该图并找到我感兴趣的连接节点的路径。

#!/usr/bin/env python
"""
Given a .dot graph, a source node, target node, this script prints out new graphs with all the paths between

"""       
import networkx as nx
from pygraphviz import *
class DotGraphvizUtil(object):

    def find_paths(self, dot_file_path, source, target):
        agraph = AGraph(dot_file_path)
        graphviz_graph = nx.nx_agraph.from_agraph(agraph)

        paths = nx.all_simple_paths(graphviz_graph, source=source, target=target)

        i = 0

        for path in paths:
            subgraph = nx.subgraph(graphviz_graph,path)
            print(path)
            nx.nx_agraph.write_dot(subgraph,"srcTargetGraph{}.dot".format(i))
            i =+ 1

        if i == 0:
            print("No paths found from {} {}".format(source, target))    

if __name__ == '__main__':
    dot_file = "agCfullProgramCallGraph.dot"
    dotGraph = DotGraphvizUtil()
    dotGraph.find_paths(dot_file_path=dot_file, source='0x004669bc', target='0x00466828')