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
def encode(self, object, **kwds): szone,pu = self.getparent(szone_t),object.get() cookie = szone['cookie'].li.int() csum = self.generate_checksum(pu^cookie) t = bitmap.new(pu, object.size()*8) t = bitmap.rol(t, 4) cs = bitmap.new(bitmap.number(t)|csum, bitmap.size(t)) cs = bitmap.ror(cs, 4) logging.info("{:s}.ptr_union.encode : Encoded pointer 0x{:x} with 0x{:x} results in checksum 0x{:x} : {:s}".format(__name__, pu, cookie, csum, bitmap.hex(cs))) res = object.copy().set(bitmap.number(cs)) return super(ptr_union,self).encode(res, **kwds)
def set_bitmap_signed(): result = bitmap.new(0, -32) freeslot = 0 count = 3 result = bitmap.set(result, freeslot, 1, count) if bitmap.value(result) == 7: raise Success
def _write(self, value): res = bitmap.new(value, self.length * 8) string = "" while res[1] > 0: res, value = bitmap.consume(res, 8) string += chr(value) return string
def set(self, string): if string in self._values_.viewvalues(): res = dict((v, k) for k, v in self._values_.viewitems()) return self.set(res[string]) res = map(int, string.split('.')) val = [res.pop(0)*40 + res.pop(0)] for n in res: if n <= 127: val.append(n) continue # convert integer to a bitmap x = bitmap.new(0,0) while n > 0: x = bitmap.insert(x, (n&0xf,4)) n //= 0x10 # shuffle bitmap into oid components y = [] while bitmap.size(x) > 0: x,v = bitmap.consume(x, 7) y.insert(0, v) val.extend([x|0x80 for x in y[:-1]] + [y[-1]]) return super(OBJECT_IDENTIFIER, self).set(str().join(map(six.int2byte, val)))
def __alloc_arena(self, elementsize, pages=1): '''allocates an arena for elements of /elementsize/''' allocator = self.allocator size = allocator.getPageSize()*pages pointer = allocator.getWriteable(None, pages) res = bitmap.new(0, size / elementsize ) return (pointer, (int(elementsize), res))
def __alloc_arena(self, elementsize, pages=1): '''allocates an arena for elements of /elementsize/''' allocator = self.allocator size = allocator.getPageSize() * pages pointer = allocator.getWriteable(None, pages) res = bitmap.new(0, size // elementsize) return (pointer, (int(elementsize), res))
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()
def __relocate(self, data, symbol, sectionarray, currentsectionname, targetsectionname, namespace): relocationva, relocationtype = self["VirtualAddress"].int(), self["Type"].num() name = symbol["Name"].str() storageclass, value = symbol["StorageClass"].num(), namespace[name] if value is None: raise ValueError("Attempted relocation for an undefined symbol `%s'." % name) result = bitmap.new(0, 0) generator = (bitmap.new(ord(x), 8) for x in data[relocationva : relocationva + 4]) for x in generator: result = bitmap.insert(result, x) result = result[0] currentva = relocationva + 4 if targetsectionname 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) result, serialized = bitmap.new(result, 32), array.array("c", "") while result[1] > 0: result, value = bitmap.consume(result, 8) serialized.append(chr(value)) assert len(serialized) == 4 data[relocationva : relocationva + len(serialized)] = serialized return data
def encode(self, object, **kwds): szone, pu = self.getparent(szone_t), object.get() cookie = szone['cookie'].li.int() csum = self.generate_checksum(pu ^ cookie) t = bitmap.new(pu, object.size() * 8) t = bitmap.rol(t, 4) cs = bitmap.new(bitmap.number(t) | csum, bitmap.size(t)) cs = bitmap.ror(cs, 4) logging.info( "{:s}.ptr_union.encode : Encoded pointer 0x{:x} with 0x{:x} results in checksum 0x{:x} : {:s}" .format(__name__, pu, cookie, csum, bitmap.hex(cs))) res = object.copy().set(bitmap.number(cs)) return super(ptr_union, self).encode(res, **kwds)
def encodeInteger(number, bytes): '''given an integer and a number of bytes, will return a string encoded in the native endianness''' number &= (0x100**bytes) - 1 # convert to absolute using side-effect of & counter = bitmap.new(number, bytes * 8) res = '' while counter[1] > 0: counter, _ = bitmap.consume(counter, 8) res += chr(_) return res
def encodeInteger(number, bytes): '''given an integer and a number of bytes, will return a string encoded in the native endianness''' number &= (0x100**bytes) - 1 # convert to absolute using side-effect of & counter = bitmap.new(number,bytes*8) res = '' while counter[1] > 0: counter,_ = bitmap.consume(counter,8) res += chr(_) return res
def str(self): data = map(ord, self.serialize()) res = [data[0] / 40, data.pop(0) % 40] data = iter(data) for n in data: v = bitmap.new(0, 0) while n & 0x80: v = bitmap.push(v, (n & 0x7f, 7)) n = data.next() v = bitmap.push(v, (n, 7)) res.append(bitmap.number(v)) return '.'.join(map(str, res))
def set_bitmap_unsigned(): x = bitmap.new(0xf000000000000000,64) #x = bitmap.set(x, 60, count=4) print bitmap.string(x) y,res = bitmap.shift(x, 4) print res,bitmap.string(y) x = bitmap.new(0,0) x = bitmap.push(x, (0x1,4) ) x = bitmap.push(x, (0x2,4) ) x = bitmap.push(x, (0x3,4) ) x = bitmap.push(x, (0x4,4) ) print x,bitmap.string(x) x = bitmap.new(0,0) x = bitmap.insert(x, (0x1,4) ) x = bitmap.insert(x, (0x2,4) ) x = bitmap.insert(x, (0x3,4) ) x = bitmap.insert(x, (0x4,4) ) print x,bitmap.string(x) x = bitmap.consumer('\x12\x34') print x.consume(4) print x.consume(4) print x.consume(4) print x.consume(4) x = bitmap.new(0, 4) for i in six.moves.range(6): print x x = bitmap.add(x, 3) for i in six.moves.range(6): print x x = bitmap.sub(x, 6) x = bitmap.new(4,4) print bitmap.string(bitmap.ror(bitmap.ror(bitmap.ror(x))))
def set_bitmap_unsigned(): x = bitmap.new(0xf000000000000000, 64) #x = bitmap.set(x, 60, count=4) print(bitmap.string(x)) y, res = bitmap.shift(x, 4) print(res, bitmap.string(y)) x = bitmap.new(0, 0) x = bitmap.push(x, (0x1, 4)) x = bitmap.push(x, (0x2, 4)) x = bitmap.push(x, (0x3, 4)) x = bitmap.push(x, (0x4, 4)) print(x, bitmap.string(x)) x = bitmap.new(0, 0) x = bitmap.insert(x, (0x1, 4)) x = bitmap.insert(x, (0x2, 4)) x = bitmap.insert(x, (0x3, 4)) x = bitmap.insert(x, (0x4, 4)) print(x, bitmap.string(x)) x = bitmap.consumer(b'\x12\x34') print(x.consume(4)) print(x.consume(4)) print(x.consume(4)) print(x.consume(4)) x = bitmap.new(0, 4) for i in range(6): print(x) x = bitmap.add(x, 3) for i in range(6): print(x) x = bitmap.sub(x, 6) x = bitmap.new(4, 4) print(bitmap.string(bitmap.ror(bitmap.ror(bitmap.ror(x)))))
def decode(self, object, **kwds): szone,pu = self.getparent(szone_t),object.get() cookie = szone['cookie'].li.int() t = bitmap.new(pu, object.size()*8) t = bitmap.rol(t, 4) ptr = bitmap.number(t) & ~0xf cs = ptr ^ cookie if bitmap.number(t)&0xf != self.generate_checksum(cs): logging.warn("{:s}.ptr_union.decode : Checksum doesn't match with cookie 0x{:x} : 0x{:x} != 0x{:x}".format(__name__, cookie, bitmap.number(t)&0xf, self.generate_checksum(cs))) res = object.copy().set(ptr) return super(ptr_union,self).decode(res, **kwds)
def decodeInteger(string, signed=False): '''given a string encoded in the native byte-order, will produce an integer''' res = bitmap.new(0, 0) for ch in string: res = bitmap.insert(res, (ord(ch), 8)) res, _ = res if not signed: return res bitflag = (0x100**len(string)) // 2 signbit, value = res & bitflag, res & (bitflag - 1) if res & signbit: return value - bitflag return value
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'
def decodeInteger(string, signed=False): '''given a string encoded in the native byte-order, will produce an integer''' res = bitmap.new(0,0) for ch in string: res = bitmap.insert(res, (ord(ch),8)) res,_ = res if not signed: return res bitflag = (0x100**len(string)) / 2 signbit,value = res & bitflag, res & (bitflag - 1) if res & signbit: return value - bitflag return value
def test_tag(): res = bitmap.new(0x1e, 5) res = bitmap.zero res = bitmap.push(res, (0x1f, 5)) res = bitmap.push(res, (0x1, 1)) res = bitmap.push(res, (0x10, 7)) res = bitmap.push(res, (0x1, 0)) res = bitmap.push(res, (0x0, 7)) x = pbinary.new(ber.Tag, source=ptypes.prov.string(bitmap.data(res))) print x.l print x['TagLong'][0] print x.int() print int(x['TagLong'])
def decode(self, object, **kwds): szone, pu = self.getparent(szone_t), object.get() cookie = szone['cookie'].li.int() t = bitmap.new(pu, object.size() * 8) t = bitmap.rol(t, 4) ptr = bitmap.number(t) & ~0xf cs = ptr ^ cookie if bitmap.number(t) & 0xf != self.generate_checksum(cs): logging.warn( "{:s}.ptr_union.decode : Checksum doesn't match with cookie 0x{:x} : 0x{:x} != 0x{:x}" .format(__name__, cookie, bitmap.number(t) & 0xf, self.generate_checksum(cs))) res = object.copy().set(ptr) return super(ptr_union, self).decode(res, **kwds)
def summary(self): iterable = (item.int() for item in self) res = functools.reduce(lambda agg, item: agg * 0x100000000 + item, iterable, 0) num = bitmap.new(res, 128) components = bitmap.split(num, 16) # FIXME: there's got to be a more elegant way than a hacky state machine result, counter = [], 0 for item in map(bitmap.number, components): if counter < 2: if item == 0: counter = 1 if len(result) == 0: result.append('') continue elif counter > 0: result.extend(['', "{:x}".format(item)]) counter = 2 continue result.append("{:x}".format(item)) return ':'.join(result)
def set(self, string): res = map(int, string.split('.')) val = [res.pop(0) * 40 + res.pop(0)] for n in res: if n <= 127: val.append(n) continue # convert integer to a bitmap x = bitmap.new(0, 0) while n > 0: x = bitmap.insert(x, (n & 0xf, 4)) n /= 0x10 # shuffle bitmap into oid components y = [] while bitmap.size(x) > 0: x, v = bitmap.consume(x, 7) y.insert(0, v) val.extend([x | 0x80 for x in y[:-1]] + [y[-1]]) return super(OBJECT_IDENTIFIER).set(''.join(map(chr, val)))
def get_checksum(self): '''Returns the encoded checksum for the ptr_union''' pu = self.int() t = bitmap.new(pu, self.size() * 8) t = bitmap.rol(t, 4) return bitmap.number(t) & 0xf
def data_padding(): res = bitmap.new(0x123, 12) data = bitmap.data(res, reversed=0) if data.encode('hex') == '1230': raise Success
def data_padding_reversed(): res = bitmap.new(0x123, 12) data = bitmap.data(res, reversed=1) if data.encode('hex') == '3012': raise Success
x = x & mask x *= -1 else: x &= mask result.append(x) return special, tuple(result) def decode(string, *args, **kwds): return consume(iter(string), *args, **kwds) if True: a = bitmap.new(0x0b058547, 32) b = bitmap.data(a) print bitmap.string(a) j, (instr_index, ) = decode(b) print hex(instr_index << 2) #RAM:8C161580 0B 05 85 47 j loc_9FC7A134 # [note] simulator branches to 8c16151c #AC 82 00 00 #ROM:9FC7A138 14 40 FF D0 bnez $v0, loc_9FC7A07C #RAM:8C161560 14 40 FF D0 bnez $v0, loc_9FC7A0BC # 8c1614a4 #8c161564 if True: a = bitmap.new(0x1440ffd0, 32) b = bitmap.data(a)
def get_checksum(self): '''Returns the encoded checksum for the ptr_union''' pu = self.int() t = bitmap.new(pu, self.size()*8) t = bitmap.rol(t, 4) return bitmap.number(t) & 0xf
def get_pointer(self): '''Returns the encoded pointer''' res = bitmap.new(self.int(), self.size() * 8) res = bitmap.rol(res, 4) res = bitmap.number(res) & ~0xf return res
if b < 0: if x & sf: x = x & mask x *= -1 else: x &= mask result.append(x) return special,tuple(result) def decode(string, *args, **kwds): return consume( iter(string), *args, **kwds ) if True: a = bitmap.new(0x0b058547, 32) b = bitmap.data(a) print bitmap.string(a) j,(instr_index,) = decode(b) print hex(instr_index<<2) #RAM:8C161580 0B 05 85 47 j loc_9FC7A134 # [note] simulator branches to 8c16151c #AC 82 00 00 #ROM:9FC7A138 14 40 FF D0 bnez $v0, loc_9FC7A07C #RAM:8C161560 14 40 FF D0 bnez $v0, loc_9FC7A0BC # 8c1614a4 #8c161564 if True: a = bitmap.new(0x1440ffd0, 32) b = bitmap.data(a)
def data_padding_reversed(): res = bitmap.new(0x123, 12) data = bitmap.data(res, reversed=1) if tohex(data) == '3012': raise Success
def bitmap(self): res = bitmap.zero for index, msize, busy in self['metadata'].busyfree(): val = bitmap.new((2**msize - 1) if busy else 0, msize) res = bitmap.insert(res, val) return res
def bitmap_ror2_value(): res = bitmap.new(0b0110, 4) if bitmap.int(bitmap.ror(res, 2)) == 0b1001: raise Success
def bitmap(self): return bitmap.new(self.int(), self.size()*8)
def get_pointer(self): '''Returns the encoded pointer''' res = bitmap.new(self.int(), self.size()*8) res = bitmap.rol(res, 4) res = bitmap.number(res) & ~0xf return res
def summary(self): num = bitmap.new(super(in_addr,self).int(), 32) octets = bitmap.split(num, 8)[::-1] return '0x{:x} {:d}.{:d}.{:d}.{:d}'.format(*map(bitmap.number,[num]+octets))
def bitmap_rorX_size(): res = bitmap.new(0b0110, 4) if bitmap.size(bitmap.ror(res, 8)) == 4: raise Success
def data_padding(): res = bitmap.new(0x123, 12) data = bitmap.data(res, reversed=0) if tohex(data) == '1230': raise Success
def bitmap(self): iterable = (bitmap.new(six.byte2int(item), 8) for item in self.serialize()) return six.moves.reduce(bitmap.push, map(bitmap.reverse, iterable), bitmap.zero)
def bitmap_rol4_size(): res = bitmap.new(0b0110, 4) if bitmap.size(bitmap.rol(res, 4)) == 4: raise Success
def bitmap(self): return bitmap.new(self.int(), self.size() * 8)
def bitmap_rol1_value(): res = bitmap.new(0b0110, 4) if bitmap.int(bitmap.rol(res, 1)) == 0b1100: raise Success
def bitmap(self): iterable = (bitmap.new(item.int(), 8 * item.size()) for item in self) return six.moves.reduce(bitmap.push, map(bitmap.reverse, iterable), bitmap.zero)
def bitmap_ror4_value(): res = bitmap.new(0b0110, 4) if bitmap.int(bitmap.ror(res, 4)) == 0b0110: raise Success
def generate_checksum(self, ptr): pu = bitmap.new(ptr, self.size()*8) res = reduce(bitmap.add, map(bitmap.number,bitmap.split(pu,8)), bitmap.new(0,8)) return bitmap.number(res) & 0xf