def test_array2bytes(self): """array to bytes""" my_ctypes = types.build_ctypes_proxy(4, 4, 8) my_utils = utils.Utils(my_ctypes) a = (my_ctypes.c_long * 12)(4, 1, 1, 1, 2) x = my_utils.array2bytes(a) self.assertEquals( b'\x04' + 3 * b'\x00' + b'\x01' + 3 * b'\x00' + b'\x01' + 3 * b'\x00' + b'\x01' + 3 * b'\x00' + b'\x02' + 3 * b'\x00' + 7 * 4 * '\x00', x) my_ctypes = types.build_ctypes_proxy(8, 8, 16) my_utils = utils.Utils(my_ctypes) a = (my_ctypes.c_long * 12)(4, 1, 1, 1, 2) x = my_utils.array2bytes(a) self.assertEquals( b'\x04' + 7 * b'\x00' + b'\x01' + 7 * b'\x00' + b'\x01' + 7 * b'\x00' + b'\x01' + 7 * b'\x00' + b'\x02' + 7 * b'\x00' + 7 * 8 * '\x00', x) a = (my_ctypes.c_char * 12).from_buffer_copy('1234567890AB') x = my_utils.array2bytes(a) self.assertEquals(b'1234567890AB', x) # mimics what ctypes gives us on memory loading. a = b'1234567890AB' x = my_utils.array2bytes(a) self.assertEquals(b'1234567890AB', x) pass
def test_container_of(self): """From a pointer to a member, returns the parent struct""" # depends on offsetof my_ctypes = types.build_ctypes_proxy(8, 8, 16) my_utils = utils.Utils(my_ctypes) class X(my_ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] x = X() x.a = 1 x.b = 2 addr_b = my_ctypes.addressof(x) + 16 # a + p o = my_utils.container_of(addr_b, X, 'b') self.assertEquals(my_ctypes.addressof(o), my_ctypes.addressof(x)) my_ctypes = types.build_ctypes_proxy(4, 4, 8) my_utils = utils.Utils(my_ctypes) class Y(ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] y = Y() y.a = 1 y.b = 2 addr_b = my_ctypes.addressof(y) + 8 # a + p o = my_utils.container_of(addr_b, Y, 'b') self.assertEquals(my_ctypes.addressof(o), my_ctypes.addressof(y)) pass
def test_offsetof(self): """returns the offset of a member fields in a record""" my_ctypes = types.build_ctypes_proxy(4, 4, 8) my_utils = utils.Utils(my_ctypes) class Y(my_ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] o = my_utils.offsetof(Y, 'b') self.assertEquals(o, 8) my_ctypes = types.build_ctypes_proxy(8, 8, 16) my_utils = utils.Utils(my_ctypes) class X(my_ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] o = my_utils.offsetof(X, 'b') self.assertEquals(o, 16) class X2(my_ctypes.Union): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] o = my_utils.offsetof(X2, 'b') self.assertEquals(o, 0) pass
def test_formatAddress(self): my_utils64 = utils.Utils(types.build_ctypes_proxy(8, 8, 16)) my_utils32 = utils.Utils(types.build_ctypes_proxy(4, 4, 8)) x = my_utils64.formatAddress(0x12345678) self.assertEquals('0x0000000012345678', x) # 32b x = my_utils32.formatAddress(0x12345678) self.assertEquals('0x12345678', x)
def __init__(self, memory_handler, my_constraints, target_ctypes=None): """ :param memory_handler: IMemoryHandler :param my_constraints: IModuleConstraints :param target_ctypes: Ctypes module, could be a different arch. :return: """ if not isinstance(memory_handler, interfaces.IMemoryHandler): raise TypeError("Feed me a IMemoryHandler") if my_constraints and not isinstance(my_constraints, interfaces.IModuleConstraints): raise TypeError("Feed me a IModuleConstraints") if target_ctypes is None: target_ctypes = memory_handler.get_target_platform( ).get_target_ctypes() if not hasattr(target_ctypes, 'c_ubyte'): raise TypeError("Feed me a target_ctypes as Ctypes modules") self._memory_handler = memory_handler self._ctypes = target_ctypes self._utils = utils.Utils(self._ctypes) self._constraints_base = None self._constraints_dynamic = None if my_constraints is not None: self._constraints_base = my_constraints.get_constraints() self._constraints_dynamic = my_constraints.get_dynamic_constraints( )
def test_unpackWord(self): # 64b my_utils = utils.Utils(types.build_ctypes_proxy(8, 8, 16)) one = b'\x01' + 7 * b'\x00' x = my_utils.unpackWord(one) self.assertEquals(x, 1) # 32b my_utils = utils.Utils(types.build_ctypes_proxy(4, 4, 8)) one32 = b'\x01' + 3 * b'\x00' x = my_utils.unpackWord(one32) self.assertEquals(x, 1) pass # endianness two32 = 3 * b'\x00' + '\x02' x = my_utils.unpackWord(two32, '>') self.assertEquals(x, 2) pass
def test_bytes2array(self): """bytes to ctypes array""" my_ctypes = types.build_ctypes_proxy(4, 4, 8) my_utils = utils.Utils(my_ctypes) bytes = 4 * b'\xAA' + 4 * b'\xBB' + 4 * b'\xCC' + \ 4 * b'\xDD' + 4 * b'\xEE' + 4 * b'\xFF' array = my_utils.bytes2array(bytes, my_ctypes.c_ulong) self.assertEquals(array[0], 0xAAAAAAAA) self.assertEquals(len(array), 6) my_ctypes = types.build_ctypes_proxy(8, 8, 16) my_utils = utils.Utils(my_ctypes) bytes = 4 * b'\xAA' + 4 * b'\xBB' + 4 * b'\xCC' + \ 4 * b'\xDD' + 4 * b'\xEE' + 4 * b'\xFF' array = my_utils.bytes2array(bytes, my_ctypes.c_ulong) self.assertEquals(array[0], 0xBBBBBBBBAAAAAAAA) self.assertEquals(len(array), 3) pass
def test_get_pointee_address(self): """tests get_pointee_address on host ctypes POINTER and haystack POINTER""" my_ctypes = types.build_ctypes_proxy(8, 8, 16) my_utils = utils.Utils(my_ctypes) class X(my_ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] self.assertEquals(my_ctypes.sizeof(X), 17) i = X.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\xBB' + 8 * '\x11' + '\xCC') a = my_utils.get_pointee_address(i.p) self.assertEquals(my_ctypes.sizeof(i.p), 8) self.assertNotEquals(a, 0) self.assertEquals(a, 0x1111111111111111) # 8*'\x11' # null pointer i = X.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\xBB' + 8 * '\x00' + '\xCC') pnull = my_utils.get_pointee_address(i.p) self.assertEquals(my_utils.get_pointee_address(pnull), 0) # change arch, and retry my_ctypes = types.build_ctypes_proxy(4, 4, 8) class Y(ctypes.Structure): _pack_ = True _fields_ = [('a', my_ctypes.c_long), ('p', my_ctypes.POINTER(my_ctypes.c_int)), ('b', my_ctypes.c_ubyte)] self.assertEquals(my_ctypes.sizeof(Y), 9) i = Y.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\x11' + '\xCC') a = my_utils.get_pointee_address(i.p) self.assertEquals(my_ctypes.sizeof(i.p), 4) self.assertNotEquals(a, 0) self.assertEquals(a, 0x11111111) # 4*'\x11' # null pointer i = Y.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\x00' + '\xCC') pnull = my_utils.get_pointee_address(i.p) self.assertEquals(my_utils.get_pointee_address(pnull), 0) # non-pointer, and void null pointer my_ctypes = types.load_ctypes_default() i = my_ctypes.c_int(69) self.assertEquals(my_utils.get_pointee_address(i), 0) pnull = my_ctypes.c_void_p(0) self.assertEquals(my_utils.get_pointee_address(pnull), 0) pass
def test_get_subtype(self): my_ctypes = types.load_ctypes_default() my_utils = utils.Utils(my_ctypes) class X(my_ctypes.Structure): _fields_ = [('p', my_ctypes.POINTER(my_ctypes.c_long))] PX = my_ctypes.POINTER(X) self.assertEquals(my_utils.get_subtype(PX), X) my_ctypes = types.build_ctypes_proxy(4, 4, 8) # different arch class Y(my_ctypes.Structure): _fields_ = [('p', my_ctypes.POINTER(my_ctypes.c_long))] PY = my_ctypes.POINTER(Y) self.assertEquals(my_utils.get_subtype(PY), Y)
def __init__(self, memory_handler): self._memory_handler = memory_handler self._ctypes = self._memory_handler.get_target_platform().get_target_ctypes() self._utils = utils.Utils(self._ctypes) self._model = self._memory_handler.get_model() self._addr_cache = {}
def set_ctypes(self, _ctypes): self._ctypes = _ctypes self._utils = utils.Utils(_ctypes)
def get_target_ctypes_utils(self): """Returns the ctypes proxy instance adequate for the target process' platform """ return utils.Utils(self.__ctypes_proxy)