【问题标题】:Multiprocessing With r2pipe使用 r2pipe 进行多处理
【发布时间】:2019-11-22 04:19:04
【问题描述】:

我在使用 r2pipe(Radare2 的 API)和 python 中的多处理 Pool.map 函数时遇到问题。我面临的问题是应用程序挂在 pool.join() 上。

我希望通过 multiprocessing.dummy 类使用多线程,以便通过 r2pipe 快速评估函数。我尝试使用 Manager 类将我的 r2pipe 对象作为命名空间传递。我也尝试过使用事件,但这些似乎都不起作用。

class Test:
    def __init__(self, filename=None):
        if filename:
            self.r2 = r2pipe.open(filename)
        else:
            self.r2 = r2pipe.open()
        self.r2.cmd('aaa')

    def t_func(self, args):
        f = args[0]
        r2_ns = args[1]
        print('afbj @ {}'.format(f['name']))
        try:
            bb = r2_ns.cmdj('afbj @ {}'.format(f['name']))
            if bb:
                return bb[0]['addr']
            else:
                return None
        except Exception as e:
            print(e)
            return None

    def thread(self):
        funcs = self.r2.cmdj('aflj')
        mgr = ThreadMgr()
        ns = mgr.Namespace()
        ns.r2 = self.r2
        pool = ThreadPool(2)
        results = pool.map(self.t_func, product(funcs, [ns.r2]))
        pool.close()
        pool.join()
        print(list(results))

这是我正在使用的课程。我在 main 函数中调用了 Test.thread 函数。

我希望应用程序打印出它将在 r2pipe afbj @ entry0 等中运行的命令。然后打印出包含第一个基本块地址 [40000, 50000, ...] 的结果列表。

应用程序确实打印出即将运行的命令,但在打印出结果之前挂起。

【问题讨论】:

    标签: python python-3.x python-multiprocessing python-multithreading radare2


    【解决方案1】:

    环境

    • radare2:radare2 4.2.0-git 23712 @ linux-x86-64 git.4.1.1-97-g5a48a4017 提交:5a48a401787c0eab31ecfb48bebf7cdfccb66e9b 构建:2020-01-09__21:44:51
    • r2pipe: 1.4.2
    • python: Python 3.6.9(默认,2019 年 11 月 7 日,10:44:02)
    • 系统: Ubuntu 18.04.3 LTS

    解决方案

    • 这可能是由于将相同的 r2pipe.open() 实例传递给池中的每个 t_func 调用。一种解决方案是将以下代码行移动到 t_func 中:
    r2 = r2pipe.open('filename')
    r2.cmd('aaa')
    
    • 这可行,但是重新分析每个线程/进程的速度非常慢。
    • 此外,允许radare2 完成尽可能多的工作并限制我们需要使用r2pipe 发送的命令数量通常会更快。
      • 这个问题通过使用命令来解决:afbj @@f
      • afbj # 列出给定函数的基本块并在 json 中显示结果
      • @@f #对每个函数执行命令

    示例

    更长的例子

    import r2pipe 
    
    R2: r2pipe.open_sync = r2pipe.open('/bin/ls')   
    R2.cmd("aaaa")         
    FUNCS: list = R2.cmd('afbj @@f').split("\n")[:-1]   
    RESULTS: list = []
    
    for func in FUNCS:
        basic_block_info: list = eval(func)
        first_block: dict = basic_block_info[0]
        address_first_block: int = first_block['addr']
        RESULTS.append(hex(address_first_block))
    
    print(RESULTS)  
    
    '''
    ['0x4a56', '0x1636c', '0x3758', '0x15690', '0x15420', '0x154f0', '0x15420',
     '0x154f0', '0x3780', '0x3790', '0x37a0', '0x37b0', '0x37c0', '0x37d0', '0x0',
     ...,
    '0x3e90', '0x6210', '0x62f0', '0x8f60', '0x99e0', '0xa860', '0xc640', '0x3e70',
     '0xd200', '0xd220', '0x133a0', '0x14480', '0x144e0', '0x145e0', '0x14840', '0x15cf0']
    '''
    

    更短的例子

    import r2pipe
    
    R2 = r2pipe.open('/bin/ls')                         
    R2.cmd("aaaa")
    print([hex(eval(func)[0]['addr']) for func in R2.cmd('afbj @@f').split("\n")[:-1]])
    

    【讨论】:

    猜你喜欢
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 2017-10-09
    相关资源
    最近更新 更多