Example #1
0
    def test_container_of(self):
        """From a pointer to a member, returns the parent struct"""
        # depends on offsetof
        ctypes = types.reload_ctypes(8, 8, 16)

        class X(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        x = X()
        x.a = 1
        x.b = 2
        addr_b = ctypes.addressof(x) + 16  # a + p
        o = utils.container_of(addr_b, X, 'b')
        self.assertEquals(ctypes.addressof(o), ctypes.addressof(x))

        ctypes = types.reload_ctypes(4, 4, 8)

        class Y(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        y = Y()
        y.a = 1
        y.b = 2
        addr_b = ctypes.addressof(y) + 8  # a + p
        o = utils.container_of(addr_b, Y, 'b')
        self.assertEquals(ctypes.addressof(o), ctypes.addressof(y))
        pass
Example #2
0
    def test_array2bytes(self):
        """array to bytes"""
        ctypes = types.reload_ctypes(4, 4, 8)
        a = (ctypes.c_long * 12)(4, 1, 1, 1, 2)
        x = 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)

        ctypes = types.reload_ctypes(8, 8, 16)
        a = (ctypes.c_long * 12)(4, 1, 1, 1, 2)
        x = 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 = (ctypes.c_char * 12).from_buffer_copy('1234567890AB')
        x = utils.array2bytes(a)
        self.assertEquals(b'1234567890AB', x)

        # mimics what ctypes gives us on memory loading.
        a = b'1234567890AB'
        x = utils.array2bytes(a)
        self.assertEquals(b'1234567890AB', x)
        pass
Example #3
0
    def test_offsetof(self):
        """returns the offset of a member fields in a record"""
        ctypes = types.reload_ctypes(4, 4, 8)

        class Y(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        o = utils.offsetof(Y, 'b')
        self.assertEquals(o, 8)

        ctypes = types.reload_ctypes(8, 8, 16)

        class X(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        o = utils.offsetof(X, 'b')
        self.assertEquals(o, 16)

        class X2(ctypes.Union):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        o = utils.offsetof(X2, 'b')
        self.assertEquals(o, 0)
        pass
Example #4
0
    def test_get_pointee_address(self):
        """tests get_pointee_address on host ctypes POINTER and haystack POINTER"""
        ctypes = types.reload_ctypes(8, 8, 16)

        class X(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        self.assertEquals(ctypes.sizeof(X), 17)
        i = X.from_buffer_copy(
            b'\xAA\xAA\xBB\xBB' +
            4 *
            '\xBB' +
            8 *
            '\x11' +
            '\xCC')
        a = utils.get_pointee_address(i.p)
        self.assertEquals(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 = utils.get_pointee_address(i.p)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        # change arch, and retry
        ctypes = types.reload_ctypes(4, 4, 8)

        class Y(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        self.assertEquals(ctypes.sizeof(Y), 9)
        i = Y.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\x11' + '\xCC')
        a = utils.get_pointee_address(i.p)
        self.assertEquals(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 = utils.get_pointee_address(i.p)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        # non-pointer, and void null pointer
        ctypes = types.load_ctypes_default()
        i = ctypes.c_int(69)
        self.assertEquals(utils.get_pointee_address(i), 0)
        pnull = ctypes.c_void_p(0)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        pass
Example #5
0
 def test_formatAddress(self):
     types.reload_ctypes(8, 8, 16)
     x = utils.formatAddress(0x12345678)
     self.assertEquals('0x0000000012345678', x)
     # 32b
     types.reload_ctypes(4, 4, 8)
     x = utils.formatAddress(0x12345678)
     self.assertEquals('0x12345678', x)
 def setUp(self):
     model.reset()
     from haystack import types
     types.reload_ctypes(4, 4, 8)
     self.cpu_bits = '32'
     self.os_name = 'linux'
     self.tgts = []
     self.process = None
     self.tests = {"test1": "test-ctypes1.%d" % (32),
                   "test2": "test-ctypes2.%d" % (32),
                   "test3": "test-ctypes3.%d" % (32),
                   }
 def setUp(self):
     model.reset()
     types.reload_ctypes(4, 4, 8)
     self.memdumpname = 'test/src/test-ctypes7.32.dump'
     self.classname = 'test.src.ctypes7.struct_Node'
     self._load_offsets_values(self.memdumpname)
     self.address = self.offsets['test1'][0]  # 0x8f40008
     # load layout in x32
     from test.src import ctypes7
     from test.src import ctypes7_gen32
     model.copyGeneratedClasses(ctypes7_gen32, ctypes7)
     model.registerModule(ctypes7)
     # apply constraints
     ctypes7.populate()
 def setUp(self):
     model.reset()
     types.reload_ctypes(8, 8, 16)
     self.memdumpname = 'test/src/test-ctypes7.64.dump'
     self.classname = 'test.src.ctypes7.struct_Node'
     self._load_offsets_values(self.memdumpname)
     self.address = self.offsets['test1'][0]  # 0x000000001b1e010
     # load layout in x64
     from test.src import ctypes7
     from test.src import ctypes7_gen64
     model.copyGeneratedClasses(ctypes7_gen64, ctypes7)
     model.registerModule(ctypes7)
     # apply constraints
     ctypes7.populate()
Example #9
0
    def test_bytes2array(self):
        """bytes to ctypes array"""
        ctypes = types.reload_ctypes(4, 4, 8)
        bytes = 4 * b'\xAA' + 4 * b'\xBB' + 4 * b'\xCC' + \
            4 * b'\xDD' + 4 * b'\xEE' + 4 * b'\xFF'
        array = utils.bytes2array(bytes, ctypes.c_ulong)
        self.assertEquals(array[0], 0xAAAAAAAA)
        self.assertEquals(len(array), 6)

        ctypes = types.reload_ctypes(8, 8, 16)
        bytes = 4 * b'\xAA' + 4 * b'\xBB' + 4 * b'\xCC' + \
            4 * b'\xDD' + 4 * b'\xEE' + 4 * b'\xFF'
        array = utils.bytes2array(bytes, ctypes.c_ulong)
        self.assertEquals(array[0], 0xBBBBBBBBAAAAAAAA)
        self.assertEquals(len(array), 3)
        pass
Example #10
0
 def test_unpackWord(self):
     # 64b
     types.reload_ctypes(8, 8, 16)
     one = b'\x01' + 7 * b'\x00'
     x = utils.unpackWord(one)
     self.assertEquals(x, 1)
     # 32b
     types.reload_ctypes(4, 4, 8)
     one32 = b'\x01' + 3 * b'\x00'
     x = utils.unpackWord(one32)
     self.assertEquals(x, 1)
     pass
     # endianness
     two32 = 3 * b'\x00' + '\x02'
     x = utils.unpackWord(two32, '>')
     self.assertEquals(x, 2)
     pass
Example #11
0
 def set_word_size(self, wordsize, ptrsize, ldsize):
     from haystack import types
     self.__size = wordsize
     # FIXME
     # win  32 bits, 4,4,8
     # linux 32 bits, 4,4,12
     # linux 64 bits, 8,8,16
     self.ctypes = types.reload_ctypes(wordsize, ptrsize, ldsize)
     return
 def setUp(self):
     model.reset()
     types.reload_ctypes(8, 8, 16)
     class MyConfig:
         def get_word_size(self):
             return 8
     self.memdumpname = 'test/src/test-ctypes6.64.dump'
     self.node_structname = 'test.src.ctypes6.struct_Node'
     self.usual_structname = 'test.src.ctypes6.struct_usual'
     self._load_offsets_values(self.memdumpname)
     self.address1 = self.offsets['test1'][0]  # struct_usual
     self.address2 = self.offsets['test2'][0]  # struct_Node
     self.address3 = self.offsets['test3'][0]  # struct_Node
     # load layout in x64
     from test.src import ctypes6
     from test.src import ctypes6_gen64
     model.copyGeneratedClasses(ctypes6_gen64, ctypes6)
     model.registerModule(ctypes6)
     # apply constraints
     ctypes6.populate(MyConfig())
    def test_walker_after_arch_change(self):
        x32 = types.reload_ctypes(4, 4, 8)
        x64 = types.reload_ctypes(8, 8, 16)

        from haystack.structures.libc import libcheapwalker
        from haystack.structures.win32 import winheapwalker
        from haystack.structures.win32 import win7heapwalker

        if False:
            # set the arch
            ctypes = types.set_ctypes(x32)
            libc_x32 = libcheapwalker.LibcHeapFinder(x32)
            winxp_x32 = winheapwalker.WinHeapFinder(x32)
            win7_x32 = win7heapwalker.Win7HeapFinder(x32)

            from haystack.structures.win32 import win7heap

            t = win7heap.HEAP_ENTRY

            for fi, tp in t._fields_:
                f = getattr(t, fi)
                print fi, " : ", hex(f.offset), hex(f.size)

            self.assertEquals(ctypes.sizeof(libc_x32.heap_type), 8)
            self.assertEquals(ctypes.sizeof(winxp_x32.heap_type), 1430)
            self.assertEquals(ctypes.sizeof(win7_x32.heap_type), 312)  # 0x138

        # set the arch
        model.reset()
        ctypes = types.set_ctypes(x64)
        libc_x64 = libcheapwalker.LibcHeapFinder(x64)
        winxp_x64 = winheapwalker.WinHeapFinder(x64)
        win7_x64 = win7heapwalker.Win7HeapFinder(x64)

        # import code
        # code.interact(local=locals())
        self.assertEquals(ctypes.sizeof(libc_x64.heap_type), 16)
        # who knows...
        self.assertEquals(ctypes.sizeof(win7_x64.heap_type), 520)
        # BUG FIXME, what is the size of winxp64 HEAP ?
        self.assertEquals(ctypes.sizeof(winxp_x64.heap_type), 2792)  #   0xae8
Example #14
0
    def test_get_subtype(self):
        ctypes = types.reset_ctypes()

        class X(ctypes.Structure):
            _fields_ = [('p', ctypes.POINTER(ctypes.c_long))]
        PX = ctypes.POINTER(X)
        self.assertEquals(utils.get_subtype(PX), X)

        ctypes = types.reload_ctypes(4, 4, 8)  # different arch

        class Y(ctypes.Structure):
            _fields_ = [('p', ctypes.POINTER(ctypes.c_long))]
        PY = ctypes.POINTER(Y)
        self.assertEquals(utils.get_subtype(PY), Y)
Example #15
0
    def test_mmap_hack32(self):
        ctypes = types.reload_ctypes(4, 4, 8)
        real_ctypes_long = ctypes.get_real_ctypes_member('c_ulong')
        fname = os.path.normpath(os.path.abspath(__file__))
        fin = file(fname)
        local_mmap_bytebuffer = mmap.mmap(
            fin.fileno(),
            1024,
            access=mmap.ACCESS_READ)
        fin.close()
        fin = None
        # yeap, that right, I'm stealing the pointer value. DEAL WITH IT.
        heapmap = struct.unpack('L', (real_ctypes_long).from_address(id(local_mmap_bytebuffer) +
                                                                     2 * (ctypes.sizeof(real_ctypes_long))))[0]
        log.debug('MMAP HACK: heapmap: 0x%0.8x' % (heapmap))
        maps = readLocalProcessMappings()
        ret = [m for m in maps if heapmap in m]
        # heapmap is a pointer value in local memory
        self.assertEquals(len(ret), 1)
        # heapmap is a pointer value to this executable?
        self.assertEquals(ret[0].pathname, fname)

        import ctypes
        self.assertIn('CTypesProxy-4:4:8', str(ctypes))