Пример #1
0
    def reload_odb(self):

        if self.sjob.reloaded:
            return
        # ensure we only do this once
        self.sjob.reloaded = True
        self.sjob.save()

        logger.info('Reloading odb for job %s' % self.name)
        orig_binary_file = self.oda_master.odb_file.binary

        # get the procdump file
        f = api.get_procdump(self.sjob.server, self.sjob.task_id)
        f.name = self.oda_master.odb_file.binary.name

        binary_file = BinaryFile.create(f)
        binary_file.save()
        bfm = BinaryFileModel(binary_file.id)
        options = orig_binary_file.options

        # TODO: set the target to a new target type called 'cuckoo' or something and add support in ofd
        options.target = 'lime'
        bfm.options = options

        odb_file = OdbFile(bfm)
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        self.oda_master.odb_file = odb_file
        self.oda_master.save()
Пример #2
0
    def test_total_lines(self):
        odb_file = OdbFile(BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())

        dasm = Disassembler(odb_file)
        total_lines = dasm.total_lines()

        self.assertEquals(41614, total_lines)
Пример #3
0
    def test_add_bad_vma_fails(self):
        odb_file = OdbFile()

        op1 = CreateFunctionOperation(TEST_VMA, TEST_NAME, sym_type='U')
        odb_file.execute(op1)

        op2 = CreateFunctionOperation(TEST_VMA, TEST_NAME2, sym_type='U')

        self.assertRaises(ValidationError, odb_file.execute, op2)
Пример #4
0
    def test_load_string_arm(self):

        s = '01 20 40 E2 02 20 61 E0 01 30 D1 E4 00 00 53 E3 02 30 C1 E7 FB FF FF 1A 1E FF 2F E1'

        odb_file = OdbFile(BinaryString(s, 'arm'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        self.assertEqual(1, len(odb_file.get_structure_list(Branch)))
Пример #5
0
    def test_decompile_by_addr_nonexistent(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        decompiler = OdaDecompiler(odb_file)
        with self.assertRaises(OdaDecompilerException):
            decompiler.decompile(0x306b26)
Пример #6
0
    def undo_not_last_fails(self):
        odb_file = OdbFile()

        op1 = CreateFunctionOperation(TEST_VMA, TEST_NAME, sym_type='U')
        odb_file.execute(op1)

        op2 = CreateFunctionOperation(TEST_VMA2, TEST_NAME2, sym_type='U')
        odb_file.execute(op2)

        self.assertRaises(Exception, op1.undo, odb_file)
Пример #7
0
    def test_serialize(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())

        serialized = DefaultOdbSerializer().dumps(odb_file)

        loaded_odb_file = DefaultOdbSerializer().load(serialized)

        self.assertEqual(len(odb_file.get_structure_list(Function)),
                         len(loaded_odb_file.get_structure_list(Function)))
Пример #8
0
    def test_add(self):
        odb_file = OdbFile()
        odb_file.execute(CreateFunctionOperation(TEST_VMA, TEST_NAME))


        self.assertEquals(1, len(odb_file.get_structure_list(Function)))
        f = odb_file.get_structure_list(Function)[0]
        self.assertEquals(TEST_NAME, f.name)

        odb_file.operations[-1].undo(odb_file)

        self.assertEquals(0, len(odb_file.get_structure_list(Function)))
Пример #9
0
    def test_decompile_by_addr_good(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        decompiler = OdaDecompiler(odb_file)
        results = decompiler.decompile(0x406b26)
        self.assertEquals(0x4067A0, results.start)
        self.assertEquals(0x406BC0, results.end)
        self.assertNotEquals("", results.source)
Пример #10
0
    def test_basic_scan(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        self.assertEqual(215, len(odb_file.get_structure_list(Function)))

        for f in odb_file.get_structure_list(Function):
            print(f.name)

        self.assertEqual(2814, len(odb_file.get_structure_list(Branch)))
Пример #11
0
    def test_load_and_get(self):

        s = '01 20 40 E2 02 20 61 E0 01 30 D1 E4 00 00 53 E3 02 30 C1 E7 FB FF FF 1A 1E FF 2F E1'

        odb = OdbFile(BinaryString(s, 'arm'))
        odb.execute(LoadOperation())

        binary = odb.get_binary()
        options = binary.options

        self.assertEquals("arm", options.architecture)
        self.assertEquals(0, options.base_address)
        self.assertEquals('binary', options.target)
Пример #12
0
    def test_basic_binary_loader(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls.bin.x86-64'), 'binary',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())

        self.assertEquals(1, len(odb_file.get_structure_list(Section)))

        self.assertEquals(0, len(odb_file.get_structure_list(Symbol)))

        self.assertEquals(0, len(odb_file.get_structure_list(Function)))

        self.assertEquals(857, len(odb_file.get_structure_list(DataString)))
Пример #13
0
    def test_load_string(self):

        s = '55 31 D2 89 E5 8B 45 08 56 8B 75 0C 53 8D 58 FF 0F B6 0C 16 88 4C 13 01 83 C2 01 84 C9 75 F1 5B 5E 5D C3'

        odb_file = OdbFile(BinaryString(s, 'i386'))
        odb_file.execute(LoadOperation())

        passive_scan_operation = PassiveScanOperation()
        odb_file.execute(passive_scan_operation)

        self.assertEqual(1, len(odb_file.get_structure_list(Branch)))
        self.assertEqual(1, len(odb_file.get_structure_list(Parcel)))
        self.assertEqual(0, odb_file.get_structure_list(Parcel)[0].vma_start)
        self.assertEqual(35, odb_file.get_structure_list(Parcel)[0].vma_end)
Пример #14
0
    def test_analyzer_output(self):
        odb_file = OdbFile(BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        dasm = Disassembler(odb_file)

        # Disassemble at a provided vma
        units = dasm.display(0x4095e0, 200, False)

        # The provided address should be the first instruction
        self.assertEquals(0x4095e0, units[0].vma)
        self.assertEquals("mov", units[0].opcode)

        # Another random instruction
        self.assertEquals("test", units[18].opcode)
        self.assertEquals("al,al", units[18].operands)

        # Disassemble at a provided negative vma
        units = dasm.display(0x4095e0, -10, False)

        # The provided address should be the last instruction
        self.assertEquals(0x4095e0, units[9].vma)
        self.assertEquals("mov", units[9].opcode)
        # IDA finds this one through a function pointer in data section
        # self.assertEquals(True, units[9].isFunction)

        # 9 instructions earlier
        self.assertEquals(0x4095BB, units[0].vma)
        self.assertEquals("call", units[0].opcode)

        # Disassemble a function
        units = dasm.display(0x40BEE0, 10, False)
        self.assertEquals(True, units[0].isFunction)

        # Cross Parcel Boundaries
        units = dasm.display(0x412BF4, -10, False)
        self.assertEquals(0x412BF4, units[9].vma)
        self.assertEquals("ret", units[9].opcode)
        self.assertEquals(".fini", units[9].section_name)
        self.assertEquals(0x412BE1, units[2].vma)
        self.assertEquals("jmp", units[2].opcode)
        self.assertEquals(".text", units[2].section_name)

        # Cross Code/Data Boundaries
        units = dasm.display(0x412BF4, 10, False)
        self.assertEquals(0x412BF4, units[0].vma)
        self.assertEquals(0x412C00, units[1].vma)
        self.assertEquals(1, units[1].dataSize)
Пример #15
0
    def test_multiple_add(self):
        odb_file = OdbFile()

        op1 = CreateFunctionOperation(TEST_VMA, TEST_NAME, sym_type='U')
        odb_file.execute(op1)

        op2 = CreateFunctionOperation(TEST_VMA2, TEST_NAME2, sym_type='U')
        odb_file.execute(op2)

        self.assertEquals(2, len(odb_file.get_structure_list(Function)))

        op2.undo(odb_file)
        self.assertEquals(1, len(odb_file.get_structure_list(Function)))
        self.assertEquals(TEST_NAME, odb_file.get_structure_list(Function)[
            0].name)

        op1.undo(odb_file)
        self.assertEquals(0, len(odb_file.get_structure_list(Function)))
Пример #16
0
    def test_basic_graph_nodes(self):
        # we load this ELF as a raw binary, because it has an invalid opcode fairly early on
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('mkdir'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        bgv = BranchGraphView(odb_file, 0x401980)

        expectedNodes = [
            BranchGraphNode(0x401980, 0x401990, 0x12, 0x4019dd, 0x401992),
            BranchGraphNode(0x401992, 0x4019b0, 0x20, 0x4019d6, 0x4019b2),
            BranchGraphNode(0x4019b2, 0x4019b2, 0x06, 0x4019b8, None),
            BranchGraphNode(0x4019b8, 0x4019d4, 0x1e, 0x4019b8, 0x4019d6),
            BranchGraphNode(0x4019d6, 0x4019d6, 0x07, 0x4019dd, None),
            BranchGraphNode(0x4019dd, 0x4019e4, 0x13, None, None),
        ]

        self.assertCountEqual(expectedNodes, bgv._nodes.values())
Пример #17
0
    def test_basic_loader(self):
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())

        self.assertEquals(26, len(odb_file.get_structure_list(Section)))

        self.assertEquals(120, len(odb_file.get_structure_list(Symbol)))

        self.assertEquals(2, len(odb_file.get_structure_list(Function)))

        self.assertEquals(
            1,
            len([
                x for x in odb_file.get_structure_list(Function)
                if x.name == '_init'
            ]))
        self.assertEquals(
            1,
            len([
                x for x in odb_file.get_structure_list(Function)
                if x.name == '_fini'
            ]))

        self.assertEquals(1304, len(odb_file.get_structure_list(DataString)))

        self.assertEquals(
            1,
            len([
                s for s in odb_file.get_structure_list(DataString)
                if s.value == 'hide-control-chars'
            ]))
        self.assertEquals(
            1,
            len([
                s for s in odb_file.get_structure_list(DataString)
                if s.value == 'error initializing month strings'
            ]))
Пример #18
0
    def partial_update(self, request, pk):
        oda_master = OdaMaster.objects.get(
            short_name=request.data['short_name'],
            revision=request.data['revision'])

        previous_odb = oda_master.odb_file

        try:
            odb_file = OdbFile(
                BinaryString(request.data['binary_string'],
                             previous_odb.get_binary().options.architecture))
            odb_file.execute(LoadOperation())
            odb_file.execute(PassiveScanOperation())
        except (TypeError, UnicodeDecodeError, UnicodeEncodeError):
            return HttpResponseNotAllowed('Invalid hex digits')

        oda_master.odb_file = odb_file
        oda_master.save()

        logger.info("updating...")

        return Response({'binary_string': request.data['binary_string']})
Пример #19
0
    def test_add(self):

        odb_file = OdbFile()

        item = odb_file.execute(CreateCStructOperation('simpleStruct', True))

        builtin = BuiltinTypeFactory('uint8_t')
        item.append_field( BuiltinField(name='Field1',oda_type=builtin) )
        item.append_field( BuiltinField(name='Field2',oda_type=builtin) )
        item.append_field( BuiltinField(name='Field3',oda_type=builtin) )

        self.assertEquals(3, item.size)

        self.assertEquals(1, len(odb_file.get_structure_list(CStruct)))
Пример #20
0
def load_examples(owner=None):
    EXAMPLES_DIR = os.path.join(
        os.path.dirname(oda.apps.odaweb.examples.__file__), 'examples')

    for example in Examples:
        short_name = example['short_name']
        valid_file_storage_id = True

        if OdaMaster.objects.filter(short_name=short_name).exists():
            print('Example %s already exists in the database' % short_name)
            oda_master = OdaMaster.objects.filter(
                short_name=short_name).first()
        else:
            oda_master = OdaMaster(
                short_name=short_name,
                project_name=example['project_name'],
                owner=owner,
                default_permission=OdaMasterPermissionLevel.read.value)

        print('Adding example %s to database' % short_name)

        if 'data' in example:
            example_data = ''.join(example['data'].split())
            odb_file = OdbFile(
                BinaryString(example_data, example['options']['architecture']))
        elif 'file_name' in example:
            odb_file = OdbFile(
                BinaryFile(os.path.join(EXAMPLES_DIR, example['file_name']),
                           example['options']['target'],
                           example['options']['architecture']))

        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        if 'comments' in example:
            for vma, msg in example['comments']:
                odb_file.execute(CreateCommentOperation(vma, msg))
                print("Adding Comment %s To %s" % (msg, str(odb_file)))

        if 'labels' in example:
            for vma, label in example['labels']:
                odb_file.execute(CreateLabelOperation(vma, label))
                print("Saving label %s To %s" % (label, str(odb_file)))

        oda_master.odb_file = odb_file
        oda_master.save()
Пример #21
0
    def failing_test_follow_jmps_i386(self):

        odb_file = OdbFile(
            BinaryFile(
                self.get_test_bin_path(
                    'active_scan_follow_jmps/active_scan_follow_jmps.bin'),
                'binary', 'i386'))

        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))

        # number of parcels before the split
        self.assertEquals(1, len(parcels_before))

        # execute the active scan operation
        odb_file.execute(ActiveScanOperation(0x0))

        # number of parcels after the split
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(11, len(parcels_after))
Пример #22
0
    def helper_import_idb(self, fname, arch, target):

        # django configuration requires input file to be in /tmp, so copy there

        idb_path = NamedTemporaryFile(dir=settings.MEDIA_ROOT,
                                      delete=False).name
        copy(self.get_test_bin_path('idb/%s' % fname), idb_path)

        # verify we have a valid .idb file
        idbImport = IdbImport(open(idb_path, "rb"))
        self.assertTrue(idbImport.is_idb())

        # guess the architecture correctly
        actual_arch, actual_target = idbImport.guess_arch()
        self.assertEqual(arch, actual_arch)
        self.assertEqual(target, actual_target)

        # reconstruct as ELF
        elfPath = idbImport.reconstruct_elf()
        self.assertIsNotNone(elfPath)

        # create the binary file
        binary_file = BinaryFile.create_from_idb(File(open(idb_path, "rb")))
        binary_file.binary_options.architecture = arch
        binary_file.binary_options.target = target
        binary_file.binary_options.save()
        binary_file.save()

        # create the ODB file
        odb_file = OdbFile(BinaryFileModel(binary_file.id))
        odb_file.binary.set_the_file(File(open(elfPath, "rb")))
        odb_file.execute(IdbImportOperation())
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        return odb_file
Пример #23
0
    def partial_update(self, request, pk):
        oda_master = OdaMaster.objects.get(
            short_name=request.data['short_name'],
            revision=request.data['revision'])

        arch = request.data.get('architecture')
        ba = request.data.get('base_address', 0)
        base_address = hex(ba) if ba else 0
        endian = request.data.get('endian')
        selected_opts = request.data.get('selected_opts')

        logger.info("updating binary options ..." + str(oda_master))

        odb_file = oda_master.odb_file
        odb_file.execute(
            ModifySettingsFactory.set_values({
                'architecture': arch,
                'base_address': base_address,
                'endian': endian,
                'selected_opts': selected_opts
            }))

        odb_file = OdbFile(odb_file.binary)

        if odb_file.binary.idb_file():
            idbImport = IdbImport(File(odb_file.binary.idb_file()))
            path = idbImport.reconstruct_elf()
            odb_file.binary.set_the_file(File(open(path, "rb")))
            odb_file.execute(IdbImportOperation())

        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())
        oda_master.odb_file = odb_file
        oda_master.save()

        return Response({'status': 'ok'})
Пример #24
0
    def test_basic_active_scan(self):

        # we load this ELF as a raw binary, because it has an invalid opcode fairly early on
        odb_file = OdbFile(
            BinaryFile(self.get_test_bin_path('mkdir'), 'elf64-x86-64',
                       'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))
        p = parcels_before.find_parcel_by_vma(0x4002ce)
        gnu_hash_lda_before = parcels_before.vma_to_lda(0x4002cd)
        dynsym_lda_before = parcels_before.vma_to_lda(0x4002e0)
        dynstr_lda_before = parcels_before.vma_to_lda(0x400a18)

        # number of parcels before the split
        self.assertEquals(24, len(parcels_before))

        # execute the split operation
        odb_file.execute(ActiveScanOperation(0x4002ce))

        # number of parcels after the split
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(26, len(parcels_after))

        # get the three parcels
        p1 = parcels_after.find_parcel_by_vma(0x400298)
        p2 = parcels_after.find_parcel_by_vma(0x4002ce)
        p3 = parcels_after.find_parcel_by_vma(0x4002d5)

        # make sure they are all unique
        self.assertNotEqual(p1, p2)
        self.assertNotEqual(p1, p3)
        self.assertNotEqual(p2, p3)

        # check num_ldas in p1 (54 bytes)
        self.assertEquals(54, p1.num_ldas)

        # check num_ldas in p2 (3 instructions)
        self.assertEquals(3, p2.num_ldas)

        # check num_ldas in p3 (7 bytes)
        self.assertEquals(7, p3.num_ldas)

        # make sure vmas line up
        self.assertEquals(0x400298, p1.vma_start)
        self.assertEquals(0x4002ce, p1.vma_end)
        self.assertEquals(0x4002ce, p2.vma_start)
        self.assertEquals(0x4002d5, p2.vma_end)
        self.assertEquals(0x4002d5, p3.vma_start)
        self.assertEquals(0x4002dc, p3.vma_end)

        #
        # make sure vma->lda mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(gnu_hash_lda_before,
                          parcels_after.vma_to_lda(0x4002cd))
        self.assertEquals(gnu_hash_lda_before + 1,
                          parcels_after.vma_to_lda(0x4002ce))
        self.assertEquals(False, p1.is_code)
        self.assertEquals(False, p3.is_code)

        # these changed
        self.assertEquals(gnu_hash_lda_before + 2,
                          parcels_after.vma_to_lda(0x4002d0))
        self.assertEquals(gnu_hash_lda_before + 3,
                          parcels_after.vma_to_lda(0x4002d2))

        self.assertEquals(gnu_hash_lda_before + 4,
                          parcels_after.vma_to_lda(0x4002d5))
        self.assertEquals(gnu_hash_lda_before + 5,
                          parcels_after.vma_to_lda(0x4002d6))
        self.assertEquals(gnu_hash_lda_before + 6,
                          parcels_after.vma_to_lda(0x4002d7))
        self.assertEquals(gnu_hash_lda_before + 7,
                          parcels_after.vma_to_lda(0x4002d8))
        self.assertEquals(gnu_hash_lda_before + 8,
                          parcels_after.vma_to_lda(0x4002d9))
        self.assertEquals(gnu_hash_lda_before + 9,
                          parcels_after.vma_to_lda(0x4002da))
        self.assertEquals(gnu_hash_lda_before + 10,
                          parcels_after.vma_to_lda(0x4002db))
        self.assertEquals(True, p2.is_code)

        # 7 bytes turned into 3 instructions, so it shifted the following parcels by -4 ldas
        self.assertEquals(dynsym_lda_before - 4,
                          parcels_after.vma_to_lda(0x4002e0))
        self.assertEquals(dynstr_lda_before - 4,
                          parcels_after.vma_to_lda(0x400a18))

        #
        # make sure lda->vma mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(0x4002cd,
                          parcels_after.lda_to_vma(gnu_hash_lda_before))
        self.assertEquals(0x4002ce,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 1))

        # these changed
        self.assertEquals(0x4002d0,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 2))
        self.assertEquals(0x4002d2,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 3))

        self.assertEquals(0x4002d5,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 4))
        self.assertEquals(0x4002d6,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 5))
        self.assertEquals(0x4002d7,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 6))
        self.assertEquals(0x4002d8,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 7))
        self.assertEquals(0x4002d9,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 8))
        self.assertEquals(0x4002da,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 9))
        self.assertEquals(0x4002db,
                          parcels_after.lda_to_vma(gnu_hash_lda_before + 10))

        # 7 bytes turned into 3 instructions, so it shifted the following parcels by -4 ldas
        self.assertEquals(0x4002e0,
                          parcels_after.lda_to_vma(dynsym_lda_before - 4))
        self.assertEquals(0x400a18,
                          parcels_after.lda_to_vma(dynstr_lda_before - 4))
Пример #25
0
    def test_split_to_data_at_start_of_parcel(self):
        odb_file = OdbFile(BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))

        # start of .fini section
        p = parcels_before.find_parcel_by_vma(0x412bec)
        num_p1_ldas_before = p.num_ldas
        fini_lda_before = parcels_before.vma_to_lda(0x412bec)

        # number of parcels before the split
        self.assertEquals(25, len(parcels_before))

        # execute the split operation
        odb_file.execute(SplitParcelOperation(0x412bec))

        # number of parcels after the split (should only add one more)
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(26, len(parcels_after))

        # get the two parcels
        p1 = parcels_after.find_parcel_by_vma(0x412bec)
        p2 = parcels_after.find_parcel_by_vma(0x412bf0)

        # make sure they are unique
        self.assertNotEqual(p1, p2)

        # check num_ldas in p1 (4 data bytes)
        self.assertEquals(4, p1.num_ldas)

        # check num_ldas in p2
        self.assertEquals(2, p2.num_ldas)

        # make sure vmas line up
        self.assertEquals(0x412bec, p1.vma_start)
        self.assertEquals(0x412bf0, p1.vma_end)
        self.assertEquals(0x412bf0, p2.vma_start)
        self.assertEquals(0x412bf5, p2.vma_end)

        #
        # make sure vma->lda mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(fini_lda_before, parcels_after.vma_to_lda(0x412bec))
        self.assertEquals(True, p2.is_code)

        # these changed
        self.assertEquals(fini_lda_before+1, parcels_after.vma_to_lda(0x412bed))
        self.assertEquals(fini_lda_before+2, parcels_after.vma_to_lda(0x412bee))
        self.assertEquals(fini_lda_before+3, parcels_after.vma_to_lda(0x412bef))
        self.assertEquals(fini_lda_before+4, parcels_after.vma_to_lda(0x412bf0))
        self.assertEquals(fini_lda_before+5, parcels_after.vma_to_lda(0x412bf4))
        self.assertEquals(False, p1.is_code)

        #
        # make sure lda->vma mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(0x412bec, parcels_after.lda_to_vma(fini_lda_before))

        # these changed
        self.assertEquals(0x412bed, parcels_after.lda_to_vma(fini_lda_before+1))
        self.assertEquals(0x412bee, parcels_after.lda_to_vma(fini_lda_before+2))
        self.assertEquals(0x412bef, parcels_after.lda_to_vma(fini_lda_before+3))
        self.assertEquals(0x412bf0, parcels_after.lda_to_vma(fini_lda_before+4))
        self.assertEquals(0x412bf4, parcels_after.lda_to_vma(fini_lda_before+5))
Пример #26
0
    def handle(self, *args, **options):

        binary_file = BinaryFile(args[0], args[1], args[2])
        odb_file = OdbFile(binary_file)
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())
Пример #27
0
    def test_split_to_data_single_inst_in_parcel(self):
        odb_file = OdbFile(BinaryFile(
            self.get_test_bin_path('code_split_single_instruction/split_parcel_single'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))

        # only one instruction in .single
        p = parcels_before.find_parcel_by_vma(0x400598)
        p_text = parcels_before.find_parcel_by_vma(0x400597)
        p_fini = parcels_before.find_parcel_by_vma(0x4005a0)
        p_got = parcels_before.find_parcel_by_vma(0x600fe0)
        num_ldas_before = p.num_ldas
        num_text_ldas_before = p_text.num_ldas
        num_fini_ldas_before = p_fini.num_ldas
        single_lda_before = p.lda_start
        fini_lda_before = p_fini.lda_start
        text_lda_before = p_text.lda_start
        got_lda_before = p_got.lda_start

        # number of parcels before the split
        self.assertEquals(25, len(parcels_before))

        # execute the split operation
        odb_file.execute(SplitParcelOperation(0x400598))

        # number of parcels after the split (should not have changed)
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(25, len(parcels_after))

        # get the parcels
        p = parcels_after.find_parcel_by_vma(0x400598)
        p_text = parcels_after.find_parcel_by_vma(0x400597)
        p_fini = parcels_after.find_parcel_by_vma(0x4005a0)

        # make sure they are all unique
        self.assertNotEqual(p, p_text)
        self.assertNotEqual(p, p_fini)
        self.assertNotEqual(p_text, p_fini)

        # check num_ldas in p (1 instruction become 7 data bytes)
        self.assertEquals(7, p.num_ldas)

        # check num_ldas in text didn't change
        self.assertEquals(num_text_ldas_before, p_text.num_ldas)

        # check num_ldas in fini didn't change
        self.assertEquals(num_fini_ldas_before, p_fini.num_ldas)

        # make sure vmas line up
        self.assertEquals(0x4003d0, p_text.vma_start)
        self.assertEquals(0x400598, p_text.vma_end)
        self.assertEquals(0x400598, p.vma_start)
        self.assertEquals(0x40059f, p.vma_end)
        self.assertEquals(0x4005a0, p_fini.vma_start)
        self.assertEquals(0x4005ae, p_fini.vma_end)

        #
        # make sure vma->lda mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(text_lda_before, parcels_after.vma_to_lda(0x4003d0))
        self.assertEquals(text_lda_before+num_text_ldas_before-1, parcels_after.vma_to_lda(0x400597))
        self.assertEquals(single_lda_before, parcels_after.vma_to_lda(0x400598))
        self.assertEquals(True, p_text.is_code)
        self.assertEquals(True, p_fini.is_code)

        # these changed
        self.assertEquals(single_lda_before+1, parcels_after.vma_to_lda(0x400599))
        self.assertEquals(single_lda_before+2, parcels_after.vma_to_lda(0x40059a))
        self.assertEquals(single_lda_before+3, parcels_after.vma_to_lda(0x40059b))
        self.assertEquals(single_lda_before+4, parcels_after.vma_to_lda(0x40059c))
        self.assertEquals(single_lda_before+5, parcels_after.vma_to_lda(0x40059d))
        self.assertEquals(single_lda_before+6, parcels_after.vma_to_lda(0x40059e))
        self.assertEquals(False, p.is_code)

        # 1 instruction turned into 7 data bytes, so it shifted the following parcels by 6 ldas
        self.assertEquals(fini_lda_before+6, parcels_after.vma_to_lda(0x4005a0))
        self.assertEquals(got_lda_before+6, parcels_after.vma_to_lda(0x600fe0))

        #
        # make sure lda->vma mappings line up
        #

        self.assertEquals(text_lda_before, parcels_after.vma_to_lda(0x4003d0))
        self.assertEquals(text_lda_before+num_text_ldas_before-1, parcels_after.vma_to_lda(0x400597))
        self.assertEquals(single_lda_before, parcels_after.vma_to_lda(0x400598))

        # these shouldn't have changed
        self.assertEquals(0x4003d0, parcels_after.lda_to_vma(text_lda_before))
        self.assertEquals(0x400597, parcels_after.lda_to_vma(text_lda_before+num_text_ldas_before-1))
        self.assertEquals(0x400598, parcels_after.lda_to_vma(single_lda_before))

        # these changed
        self.assertEquals(0x400599, parcels_after.lda_to_vma(single_lda_before+1))
        self.assertEquals(0x40059a, parcels_after.lda_to_vma(single_lda_before+2))
        self.assertEquals(0x40059b, parcels_after.lda_to_vma(single_lda_before+3))
        self.assertEquals(0x40059c, parcels_after.lda_to_vma(single_lda_before+4))
        self.assertEquals(0x40059d, parcels_after.lda_to_vma(single_lda_before+5))
        self.assertEquals(0x40059e, parcels_after.lda_to_vma(single_lda_before+6))

        # 1 instruction turned into 7 data bytes, so it shifted the following parcels by 6 ldas
        self.assertEquals(0x4005a0, parcels_after.lda_to_vma(fini_lda_before+6))
        self.assertEquals(0x600fe0, parcels_after.lda_to_vma(got_lda_before+6))
Пример #28
0
    def test_split_to_data_at_end_of_parcel(self):
        odb_file = OdbFile(BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))

        # last instruction in .plt
        p = parcels_before.find_parcel_by_vma(0x4029bb)
        p3 = parcels_before.find_parcel_by_vma(0x4029c0)
        num_p1_ldas_before = p.num_ldas
        num_p3_ldas_before = p3.num_ldas
        plt_lda_before = parcels_before.vma_to_lda(0x402320)
        text_lda_before = parcels_before.vma_to_lda(0x4029c0)

        # number of parcels before the split
        self.assertEquals(25, len(parcels_before))

        # execute the split operation
        odb_file.execute(SplitParcelOperation(0x4029bb))

        # number of parcels after the split (should only add one more)
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(26, len(parcels_after))

        # get the two parcels (plus the .text one following)
        p1 = parcels_after.find_parcel_by_vma(0x402320)
        p2 = parcels_after.find_parcel_by_vma(0x4029bb)
        p3 = parcels_after.find_parcel_by_vma(0x4029c0)

        # make sure they are all unique
        self.assertNotEqual(p1, p2)
        self.assertNotEqual(p1, p3)
        self.assertNotEqual(p2, p3)

        # check num_ldas in p1 (5 instructions)
        self.assertEquals(num_p1_ldas_before - 1, p1.num_ldas)

        # check num_ldas in p2 (this one instruction has now become 5 data bytes)
        self.assertEquals(5, p2.num_ldas)

        # check num_ldas in p3 (should not have changed)
        self.assertEquals(num_p3_ldas_before, p3.num_ldas)

        # make sure vmas line up
        self.assertEquals(0x402320, p1.vma_start)
        self.assertEquals(0x4029bb, p1.vma_end)
        self.assertEquals(0x4029bb, p2.vma_start)
        self.assertEquals(0x4029c0, p2.vma_end)
        self.assertEquals(0x4029c0, p3.vma_start)
        self.assertEquals(0x412bec, p3.vma_end)

        #
        # make sure vma->lda mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(plt_lda_before, parcels_after.vma_to_lda(0x402320))
        self.assertEquals(plt_lda_before+num_p1_ldas_before-2, parcels_after.vma_to_lda(0x4029b6))
        self.assertEquals(plt_lda_before+num_p1_ldas_before-1, parcels_after.vma_to_lda(0x4029bb))
        self.assertEquals(True, p1.is_code)
        self.assertEquals(True, p3.is_code)

        # these changed
        self.assertEquals(plt_lda_before+num_p1_ldas_before, parcels_after.vma_to_lda(0x4029bc))
        self.assertEquals(plt_lda_before+num_p1_ldas_before+1, parcels_after.vma_to_lda(0x4029bd))
        self.assertEquals(plt_lda_before+num_p1_ldas_before+2, parcels_after.vma_to_lda(0x4029be))
        self.assertEquals(plt_lda_before+num_p1_ldas_before+3, parcels_after.vma_to_lda(0x4029bf))
        self.assertEquals(plt_lda_before+num_p1_ldas_before+4, parcels_after.vma_to_lda(0x4029c0))
        self.assertEquals(False, p2.is_code)

        # 1 instruction turned into 5 data bytes, so it shifted the following parcels by 4 ldas
        self.assertEquals(text_lda_before+4, parcels_after.vma_to_lda(0x4029c0))

        #
        # make sure lda->vma mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(0x402320, parcels_after.lda_to_vma(plt_lda_before))
        self.assertEquals(0x4029b6, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before-2))
        self.assertEquals(0x4029bb, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before-1))

        # these changed
        self.assertEquals(0x4029bc, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before))
        self.assertEquals(0x4029bd, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before+1))
        self.assertEquals(0x4029be, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before+2))
        self.assertEquals(0x4029bf, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before+3))
        self.assertEquals(0x4029c0, parcels_after.lda_to_vma(plt_lda_before+num_p1_ldas_before+4))

        # 1 instruction turned into 5 data bytes, so it shifted the following parcels by 4 ldas
        self.assertEquals(0x4029c0, parcels_after.lda_to_vma(text_lda_before+4))
Пример #29
0
    def test_split_to_data_basic(self):
        odb_file = OdbFile(BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64', 'i386:x86-64'))
        odb_file.execute(LoadOperation())
        odb_file.execute(PassiveScanOperation())

        parcels_before = ParcelList(odb_file.get_structure_list(Parcel))
        p = parcels_before.find_parcel_by_vma(0x4029c0)
        num_p1_ldas_before = p.num_ldas
        text_lda_before = parcels_before.vma_to_lda(0x4029c0)
        fini_lda_before = parcels_before.vma_to_lda(0x412bec)

        # number of parcels before the split
        self.assertEquals(25, len(parcels_before))

        # execute the split operation
        odb_file.execute(SplitParcelOperation(0x4029d5))

        # number of parcels after the split
        parcels_after = ParcelList(odb_file.get_structure_list(Parcel))
        self.assertEquals(27, len(parcels_after))

        # get the three parcels
        p1 = parcels_after.find_parcel_by_vma(0x4029c0)
        p2 = parcels_after.find_parcel_by_vma(0x4029d5)
        p3 = parcels_after.find_parcel_by_vma(0x4029da)

        # make sure they are all unique
        self.assertNotEqual(p1, p2)
        self.assertNotEqual(p1, p3)
        self.assertNotEqual(p2, p3)

        # check num_ldas in p1 (5 instructions)
        self.assertEquals(5, p1.num_ldas)

        # check num_ldas in p2 (this one instruction has now become 5 data bytes)
        self.assertEquals(5, p2.num_ldas)

        # check num_ldas in p3 (less 5 from p1 and less 1 from p2 - remember it used to only be 1 lda before the split)
        self.assertEquals(num_p1_ldas_before - 5 - 1, p3.num_ldas)

        # make sure vmas line up
        self.assertEquals(0x4029c0, p1.vma_start)
        self.assertEquals(0x4029d5, p1.vma_end)
        self.assertEquals(0x4029d5, p2.vma_start)
        self.assertEquals(0x4029da, p2.vma_end)
        self.assertEquals(0x4029da, p3.vma_start)
        self.assertEquals(0x412bec, p3.vma_end)

        #
        # make sure vma->lda mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(text_lda_before, parcels_after.vma_to_lda(0x4029c0))
        self.assertEquals(text_lda_before+5, parcels_after.vma_to_lda(0x4029d5))
        self.assertEquals(True, p1.is_code)
        self.assertEquals(True, p3.is_code)

        # these changed
        self.assertEquals(text_lda_before+6, parcels_after.vma_to_lda(0x4029d6))
        self.assertEquals(text_lda_before+7, parcels_after.vma_to_lda(0x4029d7))
        self.assertEquals(text_lda_before+8, parcels_after.vma_to_lda(0x4029d8))
        self.assertEquals(text_lda_before+9, parcels_after.vma_to_lda(0x4029d9))
        self.assertEquals(text_lda_before+10, parcels_after.vma_to_lda(0x4029da))
        self.assertEquals(text_lda_before+11, parcels_after.vma_to_lda(0x4029db))
        self.assertEquals(False, p2.is_code)

        # 1 instruction turned into 5 data bytes, so it shifted the following parcels by 4 ldas
        self.assertEquals(fini_lda_before+4, parcels_after.vma_to_lda(0x412bec))

        #
        # make sure lda->vma mappings line up
        #

        # these shouldn't have changed
        self.assertEquals(0x4029c0, parcels_after.lda_to_vma(text_lda_before))
        self.assertEquals(0x4029d5, parcels_after.lda_to_vma(text_lda_before+5))

        # these changed
        self.assertEquals(0x4029d6, parcels_after.lda_to_vma(text_lda_before+6))
        self.assertEquals(0x4029d7, parcels_after.lda_to_vma(text_lda_before+7))
        self.assertEquals(0x4029d8, parcels_after.lda_to_vma(text_lda_before+8))
        self.assertEquals(0x4029d9, parcels_after.lda_to_vma(text_lda_before+9))
        self.assertEquals(0x4029da, parcels_after.lda_to_vma(text_lda_before+10))
        self.assertEquals(0x4029db, parcels_after.lda_to_vma(text_lda_before+11))

        # 1 instruction turned into 5 data bytes, so it shifted the following parcels by 4 ldas
        self.assertEquals(0x412bec, parcels_after.lda_to_vma(fini_lda_before+4))