我正在尝试创建一个Angr脚本来解决该测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int value = atoi(argv[1]);
    char* foo = "foobar";
    int sum = 0;
    for (int i = 0; i < strlen(foo); ++i)
    {
        sum += foo[i];
    }
    return (sum == value);
}


我正在尝试找出需要将什么值传递给程序让它返回True。事实证明,这比预期的要简单。

返回值在基本块中设置:



您可以看到如果al中使用的值相等,则设置cmp

我看到的大多数解决方案都是基于满足特定条件时所采用的路径。给定该路径的地址,可以解决到达该路径的地址所需的约束。在我看来,这是行不通的。 >
我目前正在尝试将runexecutefinduntil参数一起使用:执行到rip == <end of function> and eax == 1

当前抛出的消息:

import angr
import claripy

def bv_to_int(bv):
    return claripy.backends.concrete.convert(bv).value

def main():
    p = angr.Project('angr_test')
    arg = claripy.BVS('arg', 4*8)

    st = p.factory.entry_state(args=[p.filename, arg])
    sm = p.factory.simulation_manager(st)

    sm.explore(find=lambda _s: bv_to_int(_s.regs.rip) >= 0x400708 and bv_to_int(_s.regs.al) == 1)

    print(sm.found[0].solver.eval(arg, cast_to=bytes))

if __name__ == "__main__":
    main()


任何帮助将不胜感激。

#1 楼

好的,我知道了。

首先,应使用run命令。这将在所有路径上运行。

运行后,eax的值实际上将包含两个可能的值(一个用于eax == 0,另一个用于eax == 1。需要告知求解器在arg处求解eax == 1。 >此脚本将提供正确的输出:

import angr
import claripy

def main():
    p = angr.Project('angr_test')
    arg = claripy.BVS('arg', 3*8)

    st = p.factory.entry_state(args=[p.filename, arg])
    sm = p.factory.simulation_manager(st)

    sm.run()

    sm.deadended[0].solver.add(sm.deadended[0].regs.eax == 1)

    print(sm.deadended[0].solver.eval(arg, cast_to=bytes))

if __name__ == "__main__":
    main()


#2 楼

直接来自文档:

> explore(stash='active', n=None, find=None, avoid=None,
> find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, **kwargs)



“ find”和“ avoid”参数可以是以下任意一个:查找一个地址集或地址列表以查找一个函数,该函数采用状态并返回其是否匹配。决定您是否处于所需状态的状态。您也可以根据需要为失败状态实现一个函数。

也许一些简单的方法可以为您提供帮助,例如

评论


我实际上已经尝试使用Explore和run(until = )。我将在当前脚本中对该问题进行说明。

–ben_re
19年2月7日在13:39