Esempio n. 1
0
    def test_spec_sample_59(self):
        # Sample in figure 59 of DWARFv3
        s = BytesIO()
        s.write(
            b'\x02\xb9\x04' +
            b'\x0b' +
            b'\x38' +
            b'\x82' +
            b'\x73' +
            b'\x02\x02' +
            b'\x00\x01\x01')

        lp = self._make_program_in_stream(s)
        linetable = lp.get_entries()

        self.assertEqual(len(linetable), 7)
        self.assertIs(linetable[0].state, None)  # doesn't modify state
        self.assertEqual(linetable[0].command, DW_LNS_advance_pc)
        self.assertEqual(linetable[0].args, [0x239])
        self.assertLineState(linetable[1].state, address=0x239, line=3)
        self.assertEqual(linetable[1].command, 0xb)
        self.assertEqual(linetable[1].args, [2, 0])
        self.assertLineState(linetable[2].state, address=0x23c, line=5)
        self.assertLineState(linetable[3].state, address=0x244, line=6)
        self.assertLineState(linetable[4].state, address=0x24b, line=7, end_sequence=False)
        self.assertEqual(linetable[5].command, DW_LNS_advance_pc)
        self.assertEqual(linetable[5].args, [2])
        self.assertLineState(linetable[6].state, address=0x24d, line=7, end_sequence=True)
Esempio n. 2
0
    def test_spec_sample_60(self):
        # Sample in figure 60 of DWARFv3
        s = BytesIO()
        s.write(
            b'\x09\x39\x02' +
            b'\x0b' +
            b'\x09\x03\x00' +
            b'\x0b' +
            b'\x09\x08\x00' +
            b'\x0a' +
            b'\x09\x07\x00' +
            b'\x0a' +
            b'\x09\x02\x00' +
            b'\x00\x01\x01')

        lp = self._make_program_in_stream(s)
        linetable = lp.get_entries()

        self.assertEqual(len(linetable), 10)
        self.assertIs(linetable[0].state, None)  # doesn't modify state
        self.assertEqual(linetable[0].command, DW_LNS_fixed_advance_pc)
        self.assertEqual(linetable[0].args, [0x239])
        self.assertLineState(linetable[1].state, address=0x239, line=3)
        self.assertLineState(linetable[3].state, address=0x23c, line=5)
        self.assertLineState(linetable[5].state, address=0x244, line=6)
        self.assertLineState(linetable[7].state, address=0x24b, line=7, end_sequence=False)
        self.assertLineState(linetable[9].state, address=0x24d, line=7, end_sequence=True)
def do_relocation(rel_elf):
    data = rel_elf.get_section_by_name('.text').data()
    rh = RelocationHandler(rel_elf)

    stream = BytesIO()
    stream.write(data)

    rel = rel_elf.get_section_by_name('.rel.text')
    rh.apply_section_relocations(stream, rel)
    return stream.getvalue()
Esempio n. 4
0
    def test_basic(self):
        sio = BytesIO(b'abcdef')
        with preserve_stream_pos(sio):
            sio.seek(4)
        self.assertEqual(sio.tell(), 0)

        sio.seek(5)
        with preserve_stream_pos(sio):
            sio.seek(0)
        self.assertEqual(sio.tell(), 5)
Esempio n. 5
0
def do_relocation(rel_elf):
    data = rel_elf.get_section_by_name('.text').data()
    rh = RelocationHandler(rel_elf)

    stream = BytesIO()
    stream.write(data)

    rel = rel_elf.get_section_by_name('.rel.text')
    rh.apply_section_relocations(stream, rel)
    return stream.getvalue()
Esempio n. 6
0
    def test_basic(self):
        sio = BytesIO(b'abcdef')
        with preserve_stream_pos(sio):
            sio.seek(4)
        self.assertEqual(sio.tell(), 0)

        sio.seek(5)
        with preserve_stream_pos(sio):
            sio.seek(0)
        self.assertEqual(sio.tell(), 5)
Esempio n. 7
0
    def test_lne_set_discriminator(self):
        """
        Tests the handling of DWARFv4's new DW_LNE_set_discriminator opcode.
        """
        s = BytesIO()
        s.write(
            b'\x00\x02\x04\x05' +  # DW_LNE_set_discriminator (discriminator=0x05)
            b'\x01' +              # DW_LNS_copy
            b'\x00\x01\x01'        # DW_LNE_end_sequence
        )

        lp = self._make_program_in_stream(s)
        linetable = lp.get_entries()

        # We expect two entries, since DW_LNE_set_discriminator does not add
        # an entry of its own.
        self.assertEqual(len(linetable), 2)
        self.assertEqual(linetable[0].command, DW_LNS_copy)
        self.assertLineState(linetable[0].state, discriminator=0x05)
        self.assertLineState(linetable[1].state, discriminator=0x00, end_sequence=True)
Esempio n. 8
0
    def _read_dwarf_section(self, section, relocate_dwarf_sections):
        """
        Read the contents of a DWARF section from the stream and return a
        DebugSectionDescriptor. Apply relocations if asked to.
        """
        # The section data is read into a new stream, for processing
        section_stream = BytesIO()
        section_stream.write(section.get_data())

        if relocate_dwarf_sections:
            reloc_handler = RelocationHandler(self)
            reloc_section = reloc_handler.find_relocations_for_section(section)
            if reloc_section is not None:
                reloc_handler.apply_section_relocations(section_stream, reloc_section)

        return DebugSectionDescriptor(
            stream=section_stream,
            name=section.name,
            global_offset=section.PointerToRawData,
            size=section.SizeOfRawData,
            address=section.get_rva_from_offset(0))
Esempio n. 9
0
    def test_ehframe_fde_with_lsda_pointer(self):
        # CIE and FDE dumped from exceptions_0, offset 0xcc0
        # binary is at https://github.com/angr/binaries/blob/master/tests/x86_64/exceptions_0
        data = (
            b'' +
            # CIE
            b'\x1c\x00\x00\x00' +  # length
            b'\x00\x00\x00\x00' +  # ID
            b'\x01' +  # version
            b'\x7a\x50\x4c\x52\x00' +  # augmentation string
            b'\x01' +  # code alignment
            b'\x78' +  # data alignment
            b'\x10' +  # return address register
            b'\x07' +  # augmentation data length
            b'\x9b' +  # personality function pointer encoding
            b'\x3d\x13\x20\x00' +  # personality function pointer
            b'\x1b' +  # LSDA pointer encoding
            b'\x1b' +  # FDE encoding
            b'\x0c\x07\x08\x90' +  # initial instructions
            b'\x01\x00\x00' +
            # FDE
            b'\x24\x00\x00\x00' +  # length
            b'\x24\x00\x00\x00' +  # CIE reference pointer
            b'\x62\xfd\xff\xff' +  # pc begin
            b'\x89\x00\x00\x00' +  # pc range
            b'\x04' +  # augmentation data length
            b'\xb7\x00\x00\x00' +  # LSDA pointer
            b'\x41\x0e\x10\x86' +  # initial instructions
            b'\x02\x43\x0d\x06' + b'\x45\x83\x03\x02' + b'\x7f\x0c\x07\x08' +
            b'\x00\x00\x00')
        s = BytesIO(data)

        structs = DWARFStructs(little_endian=True,
                               dwarf_format=32,
                               address_size=8)
        cfi = CallFrameInfo(s, len(data), 0, structs, for_eh_frame=True)
        entries = cfi.get_entries()

        self.assertEqual(len(entries), 2)
        self.assertIsInstance(entries[0], CIE)
        self.assertIn('LSDA_encoding', entries[0].augmentation_dict)
        # check LSDA encoding
        lsda_encoding = entries[0].augmentation_dict['LSDA_encoding']
        basic_encoding = lsda_encoding & 0x0f
        modifier = lsda_encoding & 0xf0
        self.assertEqual(basic_encoding,
                         DW_EH_encoding_flags['DW_EH_PE_sdata4'])
        self.assertEqual(modifier, DW_EH_encoding_flags['DW_EH_PE_pcrel'])
        self.assertIsInstance(entries[1], FDE)
        self.assertEqual(entries[1].lsda_pointer, 232)
Esempio n. 10
0
    def test_describe_CFI_instructions(self):
        # The data here represents a single CIE
        data = (
            b'' + b'\x16\x00\x00\x00' +  # length
            b'\xff\xff\xff\xff' +  # CIE_id
            b'\x03\x00\x04\x7c' +  # version, augmentation, caf, daf
            b'\x08' +  # return address
            b'\x0c\x07\x02' + b'\x10\x02\x07\x03\x01\x02\x00\x00\x06\x06')
        s = BytesIO(data)

        structs = DWARFStructs(little_endian=True,
                               dwarf_format=32,
                               address_size=4)
        cfi = CallFrameInfo(s, len(data), structs)
        entries = cfi.get_entries()

        set_global_machine_arch('x86')
        self.assertEqual(describe_CFI_instructions(entries[0]), (
            '  DW_CFA_def_cfa: r7 (edi) ofs 2\n' +
            '  DW_CFA_expression: r2 (edx) (DW_OP_addr: 201; DW_OP_deref; DW_OP_deref)\n'
        ))
Esempio n. 11
0
    def test_spec_sample_d6(self):
        # D.6 sample in DWARFv3
        s = BytesIO()
        data = (b'' +
            # first comes the CIE
            b'\x20\x00\x00\x00' +        # length
            b'\xff\xff\xff\xff' +        # CIE_id
            b'\x03\x00\x04\x7c' +        # version, augmentation, caf, daf
            b'\x08' +                    # return address
            b'\x0c\x07\x00' +
            b'\x08\x00' +
            b'\x07\x01' +
            b'\x07\x02' +
            b'\x07\x03' +
            b'\x08\x04' +
            b'\x08\x05' +
            b'\x08\x06' +
            b'\x08\x07' +
            b'\x09\x08\x01' +
            b'\x00' +

            # then comes the FDE
            b'\x28\x00\x00\x00' +        # length
            b'\x00\x00\x00\x00' +        # CIE_pointer (to CIE at 0)
            b'\x44\x33\x22\x11' +        # initial_location
            b'\x54\x00\x00\x00' +        # address range
            b'\x41' +
            b'\x0e\x0c' + b'\x41' +
            b'\x88\x01' + b'\x41' +
            b'\x86\x02' + b'\x41' +
            b'\x0d\x06' + b'\x41' +
            b'\x84\x03' + b'\x4b' +
            b'\xc4' + b'\x41' +
            b'\xc6' +
            b'\x0d\x07' + b'\x41' +
            b'\xc8' + b'\x41' +
            b'\x0e\x00' +
            b'\x00\x00'
            )
        s.write(data)

        structs = DWARFStructs(little_endian=True, dwarf_format=32, address_size=4)
        cfi = CallFrameInfo(s, len(data), structs)
        entries = cfi.get_entries()

        self.assertEqual(len(entries), 2)
        self.assertIsInstance(entries[0], CIE)
        self.assertEqual(entries[0]['length'], 32)
        self.assertEqual(entries[0]['data_alignment_factor'], -4)
        self.assertEqual(entries[0]['return_address_register'], 8)
        self.assertEqual(len(entries[0].instructions), 11)
        self.assertInstruction(entries[0].instructions[0],
            'DW_CFA_def_cfa', [7, 0])
        self.assertInstruction(entries[0].instructions[8],
            'DW_CFA_same_value', [7])
        self.assertInstruction(entries[0].instructions[9],
            'DW_CFA_register', [8, 1])

        self.assertTrue(isinstance(entries[1], FDE))
        self.assertEqual(entries[1]['length'], 40)
        self.assertEqual(entries[1]['CIE_pointer'], 0)
        self.assertEqual(entries[1]['address_range'], 84)
        self.assertIs(entries[1].cie, entries[0])
        self.assertEqual(len(entries[1].instructions), 21)
        self.assertInstruction(entries[1].instructions[0],
            'DW_CFA_advance_loc', [1])
        self.assertInstruction(entries[1].instructions[1],
            'DW_CFA_def_cfa_offset', [12])
        self.assertInstruction(entries[1].instructions[9],
            'DW_CFA_offset', [4, 3])
        self.assertInstruction(entries[1].instructions[18],
            'DW_CFA_def_cfa_offset', [0])
        self.assertInstruction(entries[1].instructions[20],
            'DW_CFA_nop', [])

        # Now let's decode it...
        decoded_CIE = entries[0].get_decoded()
        self.assertEqual(decoded_CIE.reg_order, list(range(9)))
        self.assertEqual(len(decoded_CIE.table), 1)
        self.assertEqual(decoded_CIE.table[0]['cfa'].reg, 7)
        self.assertEqual(decoded_CIE.table[0]['pc'], 0)
        self.assertEqual(decoded_CIE.table[0]['cfa'].offset, 0)
        self.assertEqual(decoded_CIE.table[0][4].type, RegisterRule.SAME_VALUE)
        self.assertEqual(decoded_CIE.table[0][8].type, RegisterRule.REGISTER)
        self.assertEqual(decoded_CIE.table[0][8].arg, 1)

        decoded_FDE = entries[1].get_decoded()
        self.assertEqual(decoded_FDE.reg_order, list(range(9)))
        self.assertEqual(decoded_FDE.table[0]['cfa'].reg, 7)
        self.assertEqual(decoded_FDE.table[0]['cfa'].offset, 0)
        self.assertEqual(decoded_FDE.table[0]['pc'], 0x11223344)
        self.assertEqual(decoded_FDE.table[0][8].type, RegisterRule.REGISTER)
        self.assertEqual(decoded_FDE.table[0][8].arg, 1)
        self.assertEqual(decoded_FDE.table[1]['cfa'].reg, 7)
        self.assertEqual(decoded_FDE.table[1]['cfa'].offset, 12)
        self.assertEqual(decoded_FDE.table[2][8].type, RegisterRule.OFFSET)
        self.assertEqual(decoded_FDE.table[2][8].arg, -4)
        self.assertEqual(decoded_FDE.table[2][4].type, RegisterRule.SAME_VALUE)
        self.assertEqual(decoded_FDE.table[5]['pc'], 0x11223344 + 20)
        self.assertEqual(decoded_FDE.table[5][4].type, RegisterRule.OFFSET)
        self.assertEqual(decoded_FDE.table[5][4].arg, -12)
        self.assertEqual(decoded_FDE.table[6]['pc'], 0x11223344 + 64)
        self.assertEqual(decoded_FDE.table[9]['pc'], 0x11223344 + 76)
Esempio n. 12
0
 def test_large2(self):
     text = self._make_random_bytes(5000) + b'\x00' + b'jujajaja'
     sio = BytesIO(text)
     self.assertEqual(parse_cstring_from_stream(sio), text[:5000])
     self.assertEqual(parse_cstring_from_stream(sio, 2348), text[2348:5000])
Esempio n. 13
0
 def test_large1(self):
     text = b'i' * 400 + b'\x00' + b'bb'
     sio = BytesIO(text)
     self.assertEqual(parse_cstring_from_stream(sio), b'i' * 400)
     self.assertEqual(parse_cstring_from_stream(sio, 150), b'i' * 250)
Esempio n. 14
0
 def test_small2(self):
     sio = BytesIO(b'12345\x006789\x00abcdefg\x00iii')
     self.assertEqual(parse_cstring_from_stream(sio), b'12345')
     self.assertEqual(parse_cstring_from_stream(sio, 5), b'')
     self.assertEqual(parse_cstring_from_stream(sio, 6), b'6789')
Esempio n. 15
0
 def test_small1(self):
     sio = BytesIO(b'abcdefgh\x0012345')
     self.assertEqual(parse_cstring_from_stream(sio), b'abcdefgh')
     self.assertEqual(parse_cstring_from_stream(sio, 2), b'cdefgh')
     self.assertEqual(parse_cstring_from_stream(sio, 8), b'')
Esempio n. 16
0
    def test_spec_sample_d6(self):
        # D.6 sample in DWARFv3
        s = BytesIO()
        data = (
            b'' +
            # first comes the CIE
            b'\x20\x00\x00\x00' +  # length
            b'\xff\xff\xff\xff' +  # CIE_id
            b'\x03\x00\x04\x7c' +  # version, augmentation, caf, daf
            b'\x08' +  # return address
            b'\x0c\x07\x00' + b'\x08\x00' + b'\x07\x01' + b'\x07\x02' +
            b'\x07\x03' + b'\x08\x04' + b'\x08\x05' + b'\x08\x06' +
            b'\x08\x07' + b'\x09\x08\x01' + b'\x00' +

            # then comes the FDE
            b'\x28\x00\x00\x00' +  # length
            b'\x00\x00\x00\x00' +  # CIE_pointer (to CIE at 0)
            b'\x44\x33\x22\x11' +  # initial_location
            b'\x54\x00\x00\x00' +  # address range
            b'\x41' + b'\x0e\x0c' + b'\x41' + b'\x88\x01' + b'\x41' +
            b'\x86\x02' + b'\x41' + b'\x0d\x06' + b'\x41' + b'\x84\x03' +
            b'\x4b' + b'\xc4' + b'\x41' + b'\xc6' + b'\x0d\x07' + b'\x41' +
            b'\xc8' + b'\x41' + b'\x0e\x00' + b'\x00\x00')
        s.write(data)

        structs = DWARFStructs(little_endian=True,
                               dwarf_format=32,
                               address_size=4)
        cfi = CallFrameInfo(s, len(data), structs)
        entries = cfi.get_entries()

        self.assertEqual(len(entries), 2)
        self.assertIsInstance(entries[0], CIE)
        self.assertEqual(entries[0]['length'], 32)
        self.assertEqual(entries[0]['data_alignment_factor'], -4)
        self.assertEqual(entries[0]['return_address_register'], 8)
        self.assertEqual(len(entries[0].instructions), 11)
        self.assertInstruction(entries[0].instructions[0], 'DW_CFA_def_cfa',
                               [7, 0])
        self.assertInstruction(entries[0].instructions[8], 'DW_CFA_same_value',
                               [7])
        self.assertInstruction(entries[0].instructions[9], 'DW_CFA_register',
                               [8, 1])

        self.assertTrue(isinstance(entries[1], FDE))
        self.assertEqual(entries[1]['length'], 40)
        self.assertEqual(entries[1]['CIE_pointer'], 0)
        self.assertEqual(entries[1]['address_range'], 84)
        self.assertIs(entries[1].cie, entries[0])
        self.assertEqual(len(entries[1].instructions), 21)
        self.assertInstruction(entries[1].instructions[0],
                               'DW_CFA_advance_loc', [1])
        self.assertInstruction(entries[1].instructions[1],
                               'DW_CFA_def_cfa_offset', [12])
        self.assertInstruction(entries[1].instructions[9], 'DW_CFA_offset',
                               [4, 3])
        self.assertInstruction(entries[1].instructions[18],
                               'DW_CFA_def_cfa_offset', [0])
        self.assertInstruction(entries[1].instructions[20], 'DW_CFA_nop', [])

        # Now let's decode it...
        decoded_CIE = entries[0].get_decoded()
        self.assertEqual(decoded_CIE.reg_order, list(range(9)))
        self.assertEqual(len(decoded_CIE.table), 1)
        self.assertEqual(decoded_CIE.table[0]['cfa'].reg, 7)
        self.assertEqual(decoded_CIE.table[0]['pc'], 0)
        self.assertEqual(decoded_CIE.table[0]['cfa'].offset, 0)
        self.assertEqual(decoded_CIE.table[0][4].type, RegisterRule.SAME_VALUE)
        self.assertEqual(decoded_CIE.table[0][8].type, RegisterRule.REGISTER)
        self.assertEqual(decoded_CIE.table[0][8].arg, 1)

        decoded_FDE = entries[1].get_decoded()
        self.assertEqual(decoded_FDE.reg_order, list(range(9)))
        self.assertEqual(decoded_FDE.table[0]['cfa'].reg, 7)
        self.assertEqual(decoded_FDE.table[0]['cfa'].offset, 0)
        self.assertEqual(decoded_FDE.table[0]['pc'], 0x11223344)
        self.assertEqual(decoded_FDE.table[0][8].type, RegisterRule.REGISTER)
        self.assertEqual(decoded_FDE.table[0][8].arg, 1)
        self.assertEqual(decoded_FDE.table[1]['cfa'].reg, 7)
        self.assertEqual(decoded_FDE.table[1]['cfa'].offset, 12)
        self.assertEqual(decoded_FDE.table[2][8].type, RegisterRule.OFFSET)
        self.assertEqual(decoded_FDE.table[2][8].arg, -4)
        self.assertEqual(decoded_FDE.table[2][4].type, RegisterRule.SAME_VALUE)
        self.assertEqual(decoded_FDE.table[5]['pc'], 0x11223344 + 20)
        self.assertEqual(decoded_FDE.table[5][4].type, RegisterRule.OFFSET)
        self.assertEqual(decoded_FDE.table[5][4].arg, -12)
        self.assertEqual(decoded_FDE.table[6]['pc'], 0x11223344 + 64)
        self.assertEqual(decoded_FDE.table[9]['pc'], 0x11223344 + 76)