def test_build(self): instructions = TextDisassembleReader( TestTextDisassembleReader.ASM_PATH).read_instructions() collector = MetadataCollector() collector.collect(instructions) corruptor = RandomCorruptor(10.0, 2, True) corruptor.save_corrupted_program = False instructions = corruptor.corrupt( from_instruction_list_to_dict(instructions)) problem = ProblemBuilder().build(instructions, collector) c = 1 for k, v in instructions.items(): c *= len(instructions[k]) print('Initial solutions: {}'.format(c)) solutions = problem.getSolutions() print('After constraints solutions: {}'.format(len(solutions))) #for x in range(1, min(4, len(solutions))): # print('---------------') # for v in solutions[x]: # print('{} : {}'.format(v, str(solutions[x][v]))) self.assertGreaterEqual(c, len(solutions))
def get_original_instruction(path, address, needs_collector): if needs_collector: program = TextDisassembleReader(path).read_instructions() collector = MetadataCollector() collector.collect(program) program = from_instruction_list_to_dict(program) return program[address][0], program, collector else: program = from_instruction_list_to_dict(TextDisassembleReader(path).read_instructions()) return program[address][0], program, None
def test_branch_unknown(self): """ Test that the branch_to method returns an actual instruction from the instruction lit if the address is static """ instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() jump_to = instructions[20].branch_to(instructions) self.assertEqual(jump_to, None)
def test_collect(self): instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() # Collect the metadata c = MetadataCollector() c.collect(instructions) # Check the counting self.assertEqual(3, len(c.condition_count)) """ prev_inst = None for inst in c.empty_spaces: if prev_inst is None: print('{}; 0; {}'.format(inst.encoding, inst)) else: print('{}; {}; {}'.format(inst.encoding, abs(prev_inst.encoding - inst.encoding), inst)) prev_inst = inst """ # Asser the max, mean, min distance between registers for i in range(0, AReg.STORAGE_COUNT): if i in c.storage_mean_dist: print("{}: {}, {}, {} ".format(i, c.storage_min_dist[i], c.storage_mean_dist[i], c.storage_max_dist[i])) self.assertTrue( c.storage_min_dist[i] <= c.storage_mean_dist[i] <= c.storage_max_dist[i], "{}: {}, {}, {} ".format(i, c.storage_min_dist[i], c.storage_mean_dist[i], c.storage_max_dist[i]))
def test_branch_to_static(self): """ Test that the branch_to method returns an actual instruction from the instruction lit if the address is static """ instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() bne = instructions[22] jump_to = bne.branch_to(instructions) self.assertEqual(jump_to, instructions[15])
def test_read(self): instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() self.assertEqual(24, len(instructions)) self.assertTrue('push' in str(instructions[0])) self.assertTrue('mov' in str(instructions[1])) self.assertEqual(0x00010790, instructions[0].address) self.assertEqual(0x000107ec, instructions[len(instructions) - 1].address)
def test_build_complex(self): instructions = TextDisassembleReader( self.ASM_2_PATH).read_instructions() cfg = ARMControlFlowGraph(instructions) cfg.build() print(write(cfg)) self._assert_instructions_are_not_repeated(cfg, instructions) self.assertTrue(10 < len(cfg.edges())) self.assertTrue(9 < len(cfg.nodes())) self.assertTrue(3 < self._count_conditional_nodes(cfg))
def _build_ssa(self, path): instructions = TextDisassembleReader( os.path.join(os.path.dirname(__file__), path)).read_instructions() cfg = ARMControlFlowGraph(instructions) cfg.node_printer = self cfg.build() d = cfg.get_dict_nodes() cfg.remove_conditionals() value_dep_graph = SSAFormBuilder(instructions, cfg, cfg.root_node).build() return cfg, value_dep_graph
def test_build(self): """ Build the dominator tree """ instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() graph_builder = ARMControlFlowGraph(instructions) graph_builder.build() dom_tree = build_dominator_tree(graph_builder.cfg, graph_builder.root_node) self.assertTrue(7 < len(dom_tree.edges())) self.assertTrue(8 < len(dom_tree.nodes())) print(write(dom_tree))
def test_build_simple(self): instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() cfg = ARMControlFlowGraph(instructions) cfg.build() print(write(cfg)) self.assertTrue(18 < len(cfg.edges())) self.assertTrue(15 < len(cfg.nodes())) self.assertEqual(2, self._count_conditional_nodes(cfg)) # This one is to catch a bug self.assertEqual(0, len(cfg.root_node.instructions)) self._assert_instructions_are_not_repeated(cfg, instructions)
def _build_cfg_with_dominators(self, path, printer=None, remove_conditionals=False): instructions = TextDisassembleReader( os.path.join(os.path.dirname(__file__), path)).read_instructions() cfg = ARMControlFlowGraph(instructions) cfg.node_printer = printer cfg.build() if remove_conditionals: cfg.remove_conditionals() build_dominator_tree(cfg, cfg.root_node) return cfg, instructions
def test_remove_conditionals(self): instructions = TextDisassembleReader(self.ASM_PATH).read_instructions() cfg = ARMControlFlowGraph(instructions) cfg.build() d = cfg.get_dict_nodes() cfg.remove_conditionals() print(write(cfg)) for n in cfg: self.assertNotEqual(CFGBlock.COND, n.kind) self.assertTrue(cfg.has_edge((d[6], d[7]))) self.assertTrue(cfg.has_edge((d[6], d[16]))) self.assertTrue(cfg.has_edge((d[13], d[14]))) self.assertTrue(cfg.has_edge((d[13], d[17])))
def test_corrupt_program(self): program = from_instruction_list_to_dict( TextDisassembleReader(TestCorruptor.ASM_PATH).read_instructions()) corrupt_program(program, 10.0, 2) corrupted = 0 for v in program.values(): #s = " -- " #for i in v: # s += str(i) + " -- " #print(s) if len(v) > 0: corrupted += 1 self.assertTrue(corrupted >= 2)
def test_corrupt_instruction(self): program = from_instruction_list_to_dict( TextDisassembleReader(TestCorruptor.ASM_PATH).read_instructions()) instructions = corrupt_instruction(program, program[0x000107ac][0], 0x000107ac, conditional=True, opcode=True, registers=True, amount=3) for inst in instructions: print(inst) self.assertTrue(len(instructions) <= 8) self.assertTrue(len(instructions) > 1)
def test_read_hello_world(self): instructions = TextDisassembleReader( self.HELLO_PATH).read_instructions() self.assertEqual(177, len(instructions)) self.assertTrue('push' in str(instructions[0])) self.assertTrue('bl' in str(instructions[1]))
import os from semantic_codec.architecture.disassembler_readers import TextDisassembleReader from semantic_codec.metadata.metadata_collector import MetadataCollector import numpy as np import matplotlib.mlab as mlab import matplotlib.pyplot as plt filename = os.path.join(os.path.dirname(__file__), 'tests/data/helloworld.armasm') fns = TextDisassembleReader(filename).read_functions() def collect_and_print(fun_name, instructions, program): c = MetadataCollector() print("Function: " + fun_name) c.collect(instructions) print(c.condition_count) print(c.instruction_count) print(c.storage_count) prev_inst = None for inst in c.empty_spaces: if prev_inst is None: print('{}; 0; {}'.format(inst.encoding, inst)) else: print('{}; {}; {}'.format(inst.encoding, abs(prev_inst.encoding - inst.encoding), inst)) prev_inst = inst x = [
def test_read_functions(self): fns = TextDisassembleReader(self.HELLO_PATH).read_functions() self.assertEqual(36, len(fns)) self.assertEqual(11, len(fns[23].instructions)) self.assertEqual(9, len(fns[21].instructions))