Example #1
0
    def test_serialize_odb_file(self):

        before = OdbFile(
            BinaryFile(self.get_test_bin_path('ls'), 'elf64-x86-64',
                       'i386:x86-64'))
        before.execute(LoadOperation())
        before.execute(PassiveScanOperation())

        sodb_file = before.serialize()

        after = OdbFile.deserialize(sodb_file)
        self.assertIsNotNone(after)

        # verify options
        self.assertEqual(before.binary, after.binary)

        # verify structures
        for stype in STRUCTURE_TYPES:
            self.assertEqual(len(before._items[stype.__name__]),
                             len(after._items[stype.__name__]))
            for b, a in zip(before.get_structure_list(stype),
                            after.get_structure_list(stype)):
                self.assertEqual(b, a)

        # verify operations
        self.assertEqual(len(before.operations), len(after.operations))
        for b, a in zip(before.operations, after.operations):
            self.assertEqual(b.__dict__, a.__dict__)
Example #2
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()
Example #3
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)))
Example #4
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)
Example #5
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)
Example #6
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)))
Example #7
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)
Example #8
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)
Example #9
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()
Example #10
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())
Example #11
0
File: views.py Project: ygemici/oda
    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']})
Example #12
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))
Example #13
0
File: views.py Project: ygemici/oda
    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'})
Example #14
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
Example #15
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))
Example #16
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))
Example #17
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))
Example #18
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))
Example #19
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())
Example #20
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))