def test_add_dependencies_for_concrete_pointers_of_adds_a_definition_with_codelocation_in_binary_if_data_in_readonly_memory( self): arch = self.ArchMock() writable = False loader = self.LoaderMock( self.MainObjectMock(self.SectionMock(writable))) memory_datum = self.MemoryDataMock(self.memory_address, str.encode(self.string_in_memory), len(self.string_in_memory), 'string') cfg = self.CFGMock({self.memory_address: memory_datum}) register_definition = Definition( Register(0, 4), CodeLocation(0x42, 0), ) dependency_graph = DepGraph() dependency_graph.add_node(register_definition) dependency_graph.add_dependencies_for_concrete_pointers_of( [claripy.BVV(self.memory_address, arch.bits)], register_definition, cfg, loader, ) origin_codelocation = CodeLocation(0, 0, info={'readonly': True}) predecessor = list( dependency_graph.graph.predecessors(register_definition))[0] self.assertEqual(predecessor.codeloc, origin_codelocation)
def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_data_pointed_to_by_definition_is_already_in_dependency_graph( self): arch = self.ArchMock() loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True))) memory_datum = self.MemoryDataMock(self.memory_address, str.encode(self.string_in_memory), len(self.string_in_memory), 'string') cfg = self.CFGMock({self.memory_address: memory_datum}) memory_location_definition = Definition( MemoryLocation(self.memory_address, self.string_in_memory_length), CodeLocation(0, 0), ) register_definition = Definition( Register(0, 4), CodeLocation(0x42, 0), ) dependency_graph = DepGraph( networkx.DiGraph([(memory_location_definition, register_definition) ])) nodes_before_call = dependency_graph.nodes() dependency_graph.add_dependencies_for_concrete_pointers_of( [claripy.BVV(self.memory_address, arch.bits)], register_definition, cfg, loader) self.assertEqual(nodes_before_call, dependency_graph.nodes())
def perform_one(binary_path): proj = angr.Project(binary_path, load_options={'auto_load_libs': False}, use_sim_procedures=True, default_analysis_mode='symbolic') start = time.time() cfg = proj.analyses.CFGEmulated(context_sensitivity_level=2, keep_state=True, state_add_options=angr.sim_options.refs # refs are necessary for DDG to work ) end = time.time() duration = end - start l.info("CFG generated in %f seconds.", duration) ddg = proj.analyses.DDG(cfg, start=cfg.functions['main'].addr) # There should be at least 400 nodes nose.tools.assert_true(len(ddg.graph) >= 400) from angr.code_location import CodeLocation # Memory dependency 1 """ 00 | ------ IMark(0x400667, 3, 0) ------ 01 | t15 = GET:I64(rbp) 02 | t14 = Add64(t15,0xfffffffffffffffc) 03 | t17 = LDle:I32(t14) 04 | t45 = 32Uto64(t17) 05 | t16 = t45 06 | PUT(rip) = 0x000000000040066a ... 15 | ------ IMark(0x40066d, 4, 0) ------ 16 | t24 = Add64(t15,0xfffffffffffffffc) 17 | t7 = LDle:I32(t24) 18 | t5 = Add32(t7,0x00000001) 19 | STle(t24) = t5 20 | PUT(rip) = 0x0000000000400671 """ cl1 = CodeLocation(0x400667, 3) in_edges = ddg.graph.in_edges([cl1], data=True) # Where the memory address comes from memaddr_src = CodeLocation(0x400667, 2) # Where the data comes from data_src_0 = CodeLocation(0x40064c, 26) data_src_1 = CodeLocation(0x400667, 19) nose.tools.assert_equal(len(in_edges), 3) nose.tools.assert_in( (data_src_0, cl1), [ (src, dst) for src, dst, _ in in_edges ] ) nose.tools.assert_in( (data_src_1, cl1), [ (src, dst) for src, dst, _ in in_edges ] ) nose.tools.assert_in( (memaddr_src, cl1, {'data': 14, 'type': 'tmp', 'subtype': ('mem_addr', )}), in_edges )
def test_uses_function_call_arguments(self): bin_path = _binary_path('fauxware') project = angr.Project(bin_path, auto_load_libs=False) arch = project.arch cfg = project.analyses.CFGFast() main = cfg.functions['main'] project.analyses.CompleteCallingConventions(recover_variables=True) rda = project.analyses.ReachingDefinitions(subject=main, track_tmps=False, call_stack=[]) # 4007ae # rsi and rdi are all used by authenticate() context = (main.addr, ) code_location = CodeLocation(0x4007a0, DEFAULT_STATEMENT, ins_addr=0x4007ae, context=context) uses = rda.all_uses.get_uses_by_location(code_location) self.assertEqual(len(uses), 2) auth_rdi = next(iter(filter( lambda def_: isinstance(def_.atom, Register) and def_.atom.reg_offset == arch.registers['rdi'][0], uses ))) auth_rsi = next(iter(filter( lambda def_: isinstance(def_.atom, Register) and def_.atom.reg_offset == arch.registers['rsi'][0], uses ))) # 4007AB mov rdi, rax self.assertEqual(auth_rdi.codeloc.ins_addr, 0x4007ab) # 4007A8 mov rsi, rdx self.assertEqual(auth_rsi.codeloc.ins_addr, 0x4007a8)
def test_add_dependencies_for_concrete_pointers_of_create_memory_location_with_undefined_data_if_data_pointed_to_by_definition_is_not_known( self): arch = self.ArchMock() cfg = self.CFGMock({}) loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True))) datum_content = None datum_size = 0x4242 memory_datum = self.MemoryDataMock(self.memory_address, datum_content, datum_size, 'unknown') cfg = self.CFGMock({self.memory_address: memory_datum}) memory_definition = Definition( MemoryLocation(self.memory_address, datum_size), ExternalCodeLocation(), DataSet(UNDEFINED, datum_size * 8)) register_definition = Definition( Register(0, 4), CodeLocation(0x42, 0), DataSet(self.memory_address, arch.bits)) dependency_graph = DepGraph() dependency_graph.add_node(register_definition) dependency_graph.add_dependencies_for_concrete_pointers_of( register_definition, cfg, loader) nodes = list(dependency_graph.nodes()) predecessors = list( dependency_graph.graph.predecessors(register_definition)) self.assertEqual(nodes, [register_definition, memory_definition]) self.assertListEqual(predecessors, [memory_definition])
def test_add_dependencies_for_concrete_pointers_of_fails_if_the_given_definition_is_not_in_the_graph( self): dependency_graph = DepGraph() definition = Definition(Register(0, 4), CodeLocation(0x42, 0), DataSet(UNDEFINED, 4)) with self.assertRaises(AssertionError) as cm: dependency_graph.add_dependencies_for_concrete_pointers_of( definition, None, None) ex = cm.exception self.assertEqual( str(ex), 'The given Definition must be present in the given graph.')
def test_add_dependencies_for_concrete_pointers_of_does_nothing_if_pointer_is_not_concrete( self): arch = self.ArchMock() cfg = self.CFGMock({}) loader = self.LoaderMock(self.MainObjectMock(self.SectionMock(True))) register_definition = Definition(Register(0, 4), CodeLocation(0x42, 0), DataSet(UNDEFINED, arch.bits)) dependency_graph = DepGraph() dependency_graph.add_node(register_definition) nodes_before_call = dependency_graph.nodes() dependency_graph.add_dependencies_for_concrete_pointers_of( register_definition, cfg, loader) self.assertEqual(nodes_before_call, dependency_graph.nodes())
def _a_mock_definition(atom: Atom = None): # Randomise code locations to forcefully produce "different" <Definition>s. statement_index = unique_randrange(1000) code_location = CodeLocation(0x42, statement_index) return Definition(atom, code_location, DataSet(set(), 8), None)