1import nose
2import angr
3
4import logging
5l = logging.getLogger("angr.tests.test_bindiff")
6
7import os
8test_location = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'binaries', 'tests')
9
10# todo make a better test
11def test_bindiff_x86_64():
12    binary_path_1 = os.path.join(test_location, 'x86_64', 'bindiff_a')
13    binary_path_2 = os.path.join(test_location, 'x86_64', 'bindiff_b')
14    b = angr.Project(binary_path_1, load_options={"auto_load_libs": False})
15    b2 = angr.Project(binary_path_2, load_options={"auto_load_libs": False})
16    bindiff = b.analyses.BinDiff(b2)
17
18    identical_functions = bindiff.identical_functions
19    differing_functions = bindiff.differing_functions
20    unmatched_functions = bindiff.unmatched_functions
21    # check identical functions
22    nose.tools.assert_in((0x40064c, 0x40066a), identical_functions)
23    # check differing functions
24    nose.tools.assert_in((0x400616, 0x400616), differing_functions)
25    # check unmatched functions
26    nose.tools.assert_less_equal(len(unmatched_functions[0]), 1)
27    nose.tools.assert_less_equal(len(unmatched_functions[1]), 2)
28    # check for no major regressions
29    nose.tools.assert_greater(len(identical_functions), len(differing_functions))
30    nose.tools.assert_less(len(differing_functions), 4)
31
32    # check a function diff
33    fdiff = bindiff.get_function_diff(0x400616, 0x400616)
34    block_matches = { (a.addr, b.addr) for a, b in fdiff.block_matches }
35    nose.tools.assert_in((0x40064a, 0x400668), block_matches)
36    nose.tools.assert_in((0x400616, 0x400616), block_matches)
37    nose.tools.assert_in((0x40061e, 0x40061e), block_matches)
38
39def run_all():
40    functions = globals()
41    all_functions = dict(filter((lambda kv: kv[0].startswith('test_')), functions.items()))
42    for f in sorted(all_functions.keys()):
43        if hasattr(all_functions[f], '__call__'):
44            all_functions[f]()
45
46if __name__ == "__main__":
47    logging.getLogger("angr.analyses.bindiff").setLevel(logging.DEBUG)
48
49    import sys
50    if len(sys.argv) > 1:
51        globals()['test_' + sys.argv[1]]()
52    else:
53        run_all()
54