def test_compound_add(self): odb_file = OdbFile() item = odb_file.execute(CreateCStructOperation('simpleStruct', True)) field_names = ['Field1', 'Field2', 'Field3'] field_types = ['uint8_t'] * 3 item = odb_file.execute(ModifyCStructOperation('simpleStruct', field_names, field_types)) item2 = odb_file.execute(CreateCStructOperation('complexStruct', True)) field_names = ['Field1', 'Field3'] field_types = ['uint8_t', 'simpleStruct'] item2 = odb_file.execute(ModifyCStructOperation('complexStruct', field_names, field_types)) struct_list = odb_file.get_structure_list(CStruct) self.assertEquals(2, len(struct_list)) self.assertEquals(4, struct_list[1].size) # delete field from simpleStruct field_names = ['Field1', 'Field3'] field_types = ['uint8_t'] * 2 item = odb_file.execute(ModifyCStructOperation('simpleStruct', field_names, field_types)) struct_list = odb_file.get_structure_list(CStruct) sizeLen = struct_list[1].size self.assertEquals(3, sizeLen )
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)))
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)))
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)))
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)
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__)
def test_add(self): odb_file = OdbFile() odb_file.execute(CreateCommentOperation(123, 'This is a comment')) self.assertEquals(1, len(odb_file.get_structure_list(Comment)))
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)))
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)))
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)))
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))
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)))
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' ]))
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))
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))
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))
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))
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))