def test_pack_bits_bigger_base(self):
     self.assertEqual(
         pack_bits(
             0b100000000000,
             ((2, 0), 3),
             ((10, 7), 15),
             ((4, 4), 1),
         ), 0b111110010011)
Beispiel #2
0
    def _resolve_labels(self):
        for address in self.labels_addresses:
            data = self.labels_addresses[address]
            label = data['label']
            relative = data.get('relative', False)

            absolute_address = self.get_label_absolute_address_by_name(label)
            if not relative:
                true_address = absolute_address
            else:
                true_address = self.get_label_relative_address_by_name(
                    label, data['start'])

            if true_address is None:
                raise UnknownLabel(label)

            if 'hook' in data:
                data['hook'](address, true_address)
                continue

            if 'filter' in data:
                true_address = data['filter'](true_address)

            if 'alignment' in data:
                if absolute_address % data['alignment'] != 0:
                    raise AlignmentError(label)

            size = data['size']
            total_bits = size * 8

            if 'bits' in data:
                total_bits = data['bits'][0] - data['bits'][1] + 1

            bits_to_check = data.get('bits_check', total_bits)

            if relative:
                if not in_bit_range_signed(true_address, bits_to_check):
                    raise NotInBitRange(true_address, bits_to_check, label)
            else:
                if true_address < 0 or not in_bit_range(
                        true_address, bits_to_check):
                    raise NotInBitRange(true_address, bits_to_check, label)

            if 'post_filter' in data:
                true_address = data['post_filter'](true_address)

            if 'bits' in data:
                true_address = pack_bits(
                    0, (data['bits'], true_address, relative),
                    check_bits='bits_check' not in data)

            for i in range(0, size):
                value = (true_address >> (8 * i)) & 0xFF
                self.assembled_bytes[address + i] |= value
Beispiel #3
0
    def _resolve_labels(self, linker):
        for address in self.labels_addresses:
            data = self.labels_addresses[address]
            label = data.label
            is_relative = data.relative != 0

            absolute_address = self.get_label_absolute_address_by_name(label)
            if not is_relative:
                true_address = absolute_address
            else:
                true_address = self.get_label_relative_address_by_name(
                    label, data.relative)

            if true_address is None:
                true_address = linker.resolve_unknown_symbol(
                    self, address, data)
                absolute_address = true_address

            if data.hook:
                data.hook(address, true_address)
                continue

            if absolute_address % data.alignment != 0:
                raise AlignmentError(label)

            size = data.size
            total_bits = data.bits_size

            if not is_relative and true_address < 0:
                raise OnlyForwardAddressesAllowed(label, true_address)

            if not in_bit_range_decimal(
                    true_address, total_bits, signed=is_relative):
                raise NotInBitRange(true_address, total_bits, label)

            if data.filter:
                true_address = data.filter(true_address)

            if data.bits:
                true_address = pack_bits(0, (data.bits, true_address))

            for i in range(0, size):
                value = (true_address >> (8 * i)) & 0xFF
                if self.big_endian:
                    self.assembled_bytes[address + ((size - 1) - i)] |= value
                else:
                    self.assembled_bytes[address + i] |= value

            if self.log:
                print('label "{0}" translated to ({1}) at address {2}'.format(
                    label, ','.join([
                        '0x{0:02x}'.format(x)
                        for x in self.assembled_bytes[address:address + size]
                    ]), hex(address)))
Beispiel #4
0
def _build_modrm(assembler, modrm):
    blob = pack_byte(pack_bits(0,
                               ((7, 6), modrm['mod']),
                               ((5, 3), modrm['reg']),
                               ((2, 0), modrm['rm'])))

    if modrm.get('displacement') is not None:
        blob += pack_le16s(assembler.parse_integer_or_label(
            modrm['displacement'].lstrip('+'),
            size=2,
            bits_size=16,
            offset=1,
            signed=True))
    return blob
 def test_pack_bits(self):
     self.assertEqual(pack_bits(0b00000000000, ((2, 0), 3), ((10, 7), 15)),
                      0b11110000011)
 def test_pack_bits_signed(self):
     self.assertEqual(pack_bits(0b00000000000, ((2, 0), -2), ((10, 7), 15)),
                      0b11110000110)
Beispiel #7
0
 def _build_opcode(self, base, *args):
     value = pack_bits(base, *args)
     if self.big_endian:
         return pack_be32u(value)
     return pack_le32u(value)