예제 #1
0
    def __relocate__(self, data, symbol, section, namespace=None):
        '''Apply relocations for the specified ``symbol`` to the ``data``.'''
        namespace = namespace or {}

        # figure out the relocation information
        relocationva, relocationtype = self['VirtualAddress'].int(), self['Type'].int()

        # figure out the symbol type
        storageclass = symbol['StorageClass'].int()

        # get the symbol name so that it can be looked up against the namespace
        name = symbol['Name'].str()

        # lookup the symbol's value in the namespace first...otherwise, use what was actually assigned in the symbol table
        value = namespace.get(name, symbol['Value'].int())

        # extract the value that's already encoded within the section's data
        result = ptypes.bitmap.zero
        generator = ( bitmap.new(ch, 8) for ch in data[relocationva : relocationva + 4] )
        for x in generator:
            result = bitmap.insert(result, x)
        result = bitmap.int(result)

        currentva = relocationva + 4

        # FIXME: figure out the machine type in order to determine the relocation types and how to apply them

        # XXX: this is only for x86
        # figure out where to get the relocation's value from based on the relocation type
        if section is None:       # externally defined
            result = value
        elif relocationtype == 0:
            pass
        # XXX: will these relocations work?
        elif relocationtype == 6:                                           # 32-bit VA
            result = (value+result)
        #    print '>',name,hex(result),targetsectionname,hex(namespace[targetsectionname])
        elif relocationtype == 0x14:                                        # 32-bit relative displacement
            result = (value+result+4) - (currentva)
            #raise NotImplementedError(relocationtype)
        elif relocationtype == 7:                                           # use real virtual address (???)
            result = value
        elif relocationtype in [0xA, 0xB]:                                  # [section index, offset from section]
            raise NotImplementedError(relocationtype)
        else:
            raise NotImplementedError(relocationtype)

        # calculate relocation and assign it into an array
        result, serialized = bitmap.new(result, 32), array.array('B','')
        while result[1] > 0:
            result, value = bitmap.consume(result, 8)
            serialized.append(value)

        # update segment data with new serialized relocation
        if len(serialized) != 4:
            raise AssertionError("Expected size of relocation was expected to be {:d} bytes : {:d} != {:d}".format(4, len(serialized), 4))
        data[relocationva : relocationva + len(serialized)] = serialized

        # we're done. so return it back to the user
        return data
예제 #2
0
 def write(self, integer, length):
     '''Given the specified integer and its length, encode it into its little-endian form and return a string.'''
     res = array.array('B')
     binteger = bitmap.new(integer, 8 * length)
     octets = bitmap.split(binteger, 8)
     for item in reversed(octets):
         res.append(bitmap.int(item))
     return res.tostring()
예제 #3
0
 def str(self):
     data = bytearray(self.serialize())
     if len(data) > 0:
         res = [data[0] // 40, data.pop(0) % 40]
         data = iter(data)
         for n in data:
             val = bitmap.new(0,0)
             while n & 0x80:
                 val = bitmap.push(val, (n & 0x7f, 7))
                 n = next(data)
             val = bitmap.push(val, (n, 7))
             res.append(bitmap.int(val))
         return '.'.join(map("{:d}".format, res))
     return '0'
예제 #4
0
    def enumerate(self):
        index, res = 0, self.header()
        while bitmap.size(res) > 1:
            # check to see if the msize moves us to a header bit that's unset
            if bitmap.int(bitmap.get(res, 0, 1))  == 0:
                fixup = bitmap.runlength(res, 0, 0)
                logging.warn('Index {:d} of header is not set. Possibly corrupt? Forced to consume {:d} bits.'.format(index, fixup))
                res, _ = bitmap.consume(res, fixup)
                if bitmap.size(res) == 0: break

            # search for how long this run is
            msize = bitmap.runlength(res, 0, 1) + 1
            yield index, msize

            # consume msize bits
            index += msize
            res, _ = bitmap.consume(res, msize)
        return
예제 #5
0
    def used(self):
        m, res = self.getparent(magazine_t), self.header()
        index = m['mag_bytes_free_at_start'].int() / self.QUANTUM
        sentinel = (m['num_bytes_in_magazine'].int() - m['mag_bytes_free_at_end'].int()) / self.QUANTUM
        while index <= sentinel:
            # check to see if the msize moves us to a header bit that's unset
            if bitmap.int(bitmap.get(res, 0, 1))  == 0:
                fixup = bitmap.runlength(res, 0, 0)
                logging.warn('Index {:d} of header is not set. Possibly corrupt? Forced to consume {:d} bits.'.format(index, fixup))
                res, _ = bitmap.consume(res, fixup)
                if bitmap.size(res) == 0: break

            # search for how long this run is
            msize = bitmap.runlength(res, 0, 1) + 1
            yield index, msize

            # consume msize bits
            index += msize
            res, _ = bitmap.consume(res, msize)
        return
예제 #6
0
    def enumerate(self):
        index, res = 0, self.header()
        while bitmap.size(res) > 1:
            # check to see if the msize moves us to a header bit that's unset
            if bitmap.int(bitmap.get(res, 0, 1)) == 0:
                fixup = bitmap.runlength(res, 0, 0)
                logging.warn(
                    'Index {:d} of header is not set. Possibly corrupt? Forced to consume {:d} bits.'
                    .format(index, fixup))
                res, _ = bitmap.consume(res, fixup)
                if bitmap.size(res) == 0: break

            # search for how long this run is
            msize = bitmap.runlength(res, 0, 1) + 1
            yield index, msize

            # consume msize bits
            index += msize
            res, _ = bitmap.consume(res, msize)
        return
예제 #7
0
    def used(self):
        m, res = self.getparent(magazine_t), self.header()
        index = m['mag_bytes_free_at_start'].int() / self.QUANTUM
        sentinel = (m['num_bytes_in_magazine'].int() -
                    m['mag_bytes_free_at_end'].int()) / self.QUANTUM
        while index <= sentinel:
            # check to see if the msize moves us to a header bit that's unset
            if bitmap.int(bitmap.get(res, 0, 1)) == 0:
                fixup = bitmap.runlength(res, 0, 0)
                logging.warn(
                    'Index {:d} of header is not set. Possibly corrupt? Forced to consume {:d} bits.'
                    .format(index, fixup))
                res, _ = bitmap.consume(res, fixup)
                if bitmap.size(res) == 0: break

            # search for how long this run is
            msize = bitmap.runlength(res, 0, 1) + 1
            yield index, msize

            # consume msize bits
            index += msize
            res, _ = bitmap.consume(res, msize)
        return
예제 #8
0
 def bitmap_rol1_value():
     res = bitmap.new(0b0110, 4)
     if bitmap.int(bitmap.rol(res, 1)) == 0b1100:
         raise Success
예제 #9
0
 def busyfree(self):
     inuse = self.inuse()
     for index, msize in self.used():
         res = bitmap.get(inuse, index, 1)
         yield index, msize, bool(bitmap.int(res))
     return
예제 #10
0
 def freeQ(self, index):
     '''Returns whether the chunk at the specified index is free'''
     index = self.__check_header(index)
     inuse = self.inuse()
     freeQ = bitmap.int(bitmap.get(inuse, index, 1))
     return bool(freeQ == 0)
예제 #11
0
 def __check_header(self, index):
     header = self.header()
     headerQ = bitmap.int(bitmap.get(header, index, 1))
     if headerQ == 0:
         raise ValueError('index {:d} is not a header'.format(index))
     return index
예제 #12
0
 def freeQ(self, index):
     '''Returns whether the chunk at the specified index is free'''
     index = self.__check_header(index)
     inuse = self.inuse()
     freeQ = bitmap.int(bitmap.get(inuse, index, 1))
     return bool(freeQ == 0)
예제 #13
0
 def __check_header(self, index):
     header = self.header()
     headerQ = bitmap.int(bitmap.get(header, index, 1))
     if headerQ == 0:
         raise ValueError('index {:d} is not a header'.format(index))
     return index
예제 #14
0
    def __relocate__(self, data, symbol, section, namespace=None):
        '''Apply relocations for the specified ``symbol`` to the ``data``.'''
        raise NotImplementedError(
            'This internal method has been deprecated due to a refactor')

        namespace = namespace or {}

        # figure out the relocation information
        relocationva, relocationtype = self['VirtualAddress'].int(
        ), self['Type'].int()

        # figure out the symbol type
        storageclass = symbol['StorageClass'].int()

        # get the symbol name so that it can be looked up against the namespace
        name = symbol['Name'].str()

        # lookup the symbol's value in the namespace first...otherwise, use what was actually assigned in the symbol table
        value = namespace.get(name, symbol['Value'].int())

        # extract the value that's already encoded within the section's data
        result = ptypes.bitmap.zero
        generator = (bitmap.new(ch, 8)
                     for ch in data[relocationva:relocationva + 4])
        for x in generator:
            result = bitmap.insert(result, x)
        result = bitmap.int(result)

        currentva = relocationva + 4

        # FIXME: figure out the machine type in order to determine the relocation types and how to apply them

        # XXX: this is only for x86
        # figure out where to get the relocation's value from based on the relocation type
        if section is None:  # externally defined
            result = value
        elif relocationtype == 0:
            pass
        # XXX: will these relocations work?
        elif relocationtype == 6:  # 32-bit VA
            result = (value + result)
        #    print('>',name,hex(result),targetsectionname,hex(namespace[targetsectionname]))
        elif relocationtype == 0x14:  # 32-bit relative displacement
            result = (value + result + 4) - (currentva)
            #raise NotImplementedError(relocationtype)
        elif relocationtype == 7:  # use real virtual address (???)
            result = value
        elif relocationtype in [0xA,
                                0xB]:  # [section index, offset from section]
            raise NotImplementedError(relocationtype)
        else:
            raise NotImplementedError(relocationtype)

        # calculate relocation and assign it into an array
        result, serialized = bitmap.new(result, 32), array.array('B', '')
        while result[1] > 0:
            result, value = bitmap.consume(result, 8)
            serialized.append(value)

        # update segment data with new serialized relocation
        if len(serialized) != 4:
            raise AssertionError(
                "Expected size of relocation was expected to be {:d} bytes : {:d} != {:d}"
                .format(4, len(serialized), 4))
        data[relocationva:relocationva + len(serialized)] = serialized

        # we're done. so return it back to the user
        return data
예제 #15
0
 def bitmap_ror2_value():
     res = bitmap.new(0b0110, 4)
     if bitmap.int(bitmap.ror(res, 2)) == 0b1001:
         raise Success
예제 #16
0
 def bitmap_ror4_value():
     res = bitmap.new(0b0110, 4)
     if bitmap.int(bitmap.ror(res, 4)) == 0b0110:
         raise Success
예제 #17
0
 def busyfree(self):
     inuse = self.inuse()
     for index, msize in self.used():
         res = bitmap.get(inuse, index, 1)
         yield index, msize, bool(bitmap.int(res))
     return