1import nose 2import angr 3 4import os 5test_location = os.path.join(os.path.dirname(os.path.realpath(str(__file__))), '..', '..', 'binaries', 'tests') 6 7arch_data = { # (steps, [hit addrs], finished) 8 'x86_64': (330, (0x1021c20, 0x1021980, 0x1021be0, 0x4004b0, 0x400440, 0x400570), True), 9 'i386': (425, (0x90198e0, 0x90195c0, 0x9019630, 0x90198a0, 0x8048370, 0x80482f8, 0x8048440, 0x804846D, 0x8048518), True), 10 'ppc': (381, (0x11022f50, 0x11022eb0, 0x10000340, 0x100002e8, 0x1000053C, 0x1000063C), True), 11 'ppc64': (372, (0x11047490, 0x100003fc, 0x10000368, 0x10000654, 0x10000770), True), 12 'mips': (363, (0x1016f20, 0x400500, 0x400470, 0x400640, 0x400750), True), 13 'mips64': (390, (0x12103b828, 0x120000870, 0x1200007e0, 0x120000A80, 0x120000B68), True), 14 'armel': (370, (0x10154b8, 0x1108244, 0x83a8, 0x8348, 0x84b0, 0x84E4, 0x85E8), True), 15 'aarch64': (370, (0x1020b04, 0x400430, 0x4003b8, 0x400538, 0x400570, 0x40062C), True), 16} 17 18def emulate(arch, binary, use_sim_procs, steps, hit_addrs, finished): 19 p = angr.Project(os.path.join(test_location, arch, binary), use_sim_procedures=use_sim_procs, rebase_granularity=0x1000000, load_debug_info=False) 20 state = p.factory.full_init_state(args=['./test_arrays'], add_options={angr.options.STRICT_PAGE_ACCESS, angr.options.ENABLE_NX, angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY, angr.options.USE_SYSTEM_TIMES}) 21 22 pg = p.factory.simulation_manager(state, resilience=True) 23 pg2 = pg.run(until=lambda lpg: len(lpg.active) != 1) 24 25 is_finished = False 26 if len(pg2.active) > 0: 27 state = pg2.active[0] 28 elif len(pg2.deadended) > 0: 29 state = pg2.deadended[0] 30 is_finished = True 31 elif len(pg2.errored) > 0: 32 state = pg2.errored[0].state # ErroredState object! 33 else: 34 raise ValueError("The result does not contain a state we can use for this test?") 35 36 nose.tools.assert_greater_equal(state.history.depth, steps) 37 38 # this is some wonky control flow that asserts that the items in hit_addrs appear in the state in order. 39 trace = state.history.bbl_addrs.hardcopy 40 reqs = list(hit_addrs) 41 while len(reqs) > 0: 42 req = reqs.pop(0) 43 while True: 44 nose.tools.assert_greater(len(trace), 0) 45 trace_head = trace.pop(0) 46 if trace_head == req: 47 break 48 nose.tools.assert_not_in(trace_head, reqs) 49 50 if finished: 51 nose.tools.assert_true(is_finished) 52 53def test_emulation(): 54 for arch in arch_data: 55 steps, hit_addrs, finished = arch_data[arch] 56 yield emulate, arch, 'test_arrays', False, steps, hit_addrs, finished 57 58def test_windows(): 59 yield emulate, 'i386', 'test_arrays.exe', True, 41, [], False # blocked on GetLastError or possibly dynamic loading 60 61def test_locale(): 62 p = angr.Project(os.path.join(test_location, 'i386', 'isalnum'), use_sim_procedures=False) 63 state = p.factory.full_init_state(args=['./isalnum'], add_options={angr.options.STRICT_PAGE_ACCESS}) 64 pg = p.factory.simulation_manager(state) 65 pg2 = pg.run(until=lambda lpg: len(lpg.active) != 1, 66 step_func=lambda lpg: lpg if len(lpg.active) == 1 else lpg.prune() 67 ) 68 nose.tools.assert_equal(len(pg2.active), 0) 69 nose.tools.assert_equal(len(pg2.deadended), 1) 70 nose.tools.assert_equal(pg2.deadended[0].history.events[-1].type, 'terminate') 71 nose.tools.assert_equal(pg2.deadended[0].history.events[-1].objects['exit_code']._model_concrete.value, 0) 72 73 74if __name__ == '__main__': 75 #emulate('armel', 'test_arrays', False, *arch_data['armel']) 76 #import sys; sys.exit() 77 for func, a, b, c, d, e, f in test_windows(): 78 print(a, b) 79 func(a, b, c, d, e, f) 80 print('locale') 81 test_locale() 82 for func, a, b, c, d, e, f in test_emulation(): 83 print(a, b) 84 func(a, b, c, d, e, f) 85