Example #1
0
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    pyop = gdb.Value(addr).cast(_type_pyop)
    try:
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >=0 and ob_refcnt < 0xffff:
            obtype = pyop['ob_type']
            if obtype != 0:
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    if type_ob_size > 0xffff:
                        return 0

                    for fieldname in ('tp_del', 'tp_mro', 'tp_init', 'tp_getset'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except (RuntimeError, UnicodeDecodeError):
        pass # Not a python object (or corrupt)
Example #2
0
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    pyop = gdb.Value(addr).cast(_type_pyop)
    try:
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >=0 and ob_refcnt < 0xffff:
            obtype = pyop['ob_type']
            if obtype != 0:
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    if type_ob_size > 0xffff:
                        return 0

                    for fieldname in ('tp_del', 'tp_mro', 'tp_init', 'tp_getset'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except (RuntimeError, UnicodeDecodeError):
        pass # Not a python object (or corrupt)
Example #3
0
def get_class_name(addr, size):
    # Try to detect a vtable ptr at the top of this object:
    vtable = gdb.Value(addr).cast(void_ptr_ptr).dereference()
    if not looks_like_ptr(vtable):
        return None

    info = execute('info sym (void *)0x%x' % long(vtable))
    # "vtable for Foo + 8 in section .rodata of /home/david/heap/test_cplusplus"
    m = re.match('vtable for (.*) \+ (.*)', info)
    if m:
        return m.group(1)
    # Not matched:
    return None
Example #4
0
def get_class_name(addr, size):
    # Try to detect a vtable ptr at the top of this object:
    vtable = gdb.Value(addr).cast(void_ptr_ptr).dereference()
    if not looks_like_ptr(vtable):
        return None

    info = execute('info sym (void *)0x%x' % long(vtable))
    # "vtable for Foo + 8 in section .rodata of /home/david/heap/test_cplusplus"
    m = re.match('vtable for (.*) \+ (.*)', info)
    if m:
        return m.group(1)
    # Not matched:
    return None
Example #5
0
def is_pyobject_ptr(addr):
    try:
        _type_pyop = caching_lookup_type('PyObject').pointer()
        _type_pyvarop = caching_lookup_type('PyVarObject').pointer()
    except RuntimeError:
        # not linked against python
        return None

    try:
        typeop = pyop = gdb.Value(addr).cast(_type_pyop)

        # If we follow type chain on a PyObject long enough, we should arrive
        # at 'type' and type(type) should be 'type'.
        # The levels are:     a <- b means a = type(b)
        # 0 - type
        # 1 - type <- class A
        #     type <- class M(type)
        # 2 - type <- class A <- A()
        #     type <- class M(type) <- class B(metaclass=M)
        # 3 - type <- class M(type) <- class B(metaclass=M) <- B()
        for i in range(4):
            if typeop['ob_type'] == typeop:
                return PyObjectPtr.from_pyobject_ptr(pyop)
            typeop = typeop['ob_type'].cast(_type_pyop)

        return 0

        # gdb.write('PYOP {}\n'.format(pyop))
        ob_refcnt = pyop['ob_refcnt']
        if ob_refcnt >= 0 and ob_refcnt < 0xffff:
            # gdb.write('refcnt ok {}\n'.format(int(ob_refcnt)))
            obtype = pyop['ob_type']
            if looks_like_ptr(obtype):
                # gdb.write('obtype ok {}\n'.format(obtype))
                type_refcnt = obtype.cast(_type_pyop)['ob_refcnt']
                if type_refcnt > 0 and type_refcnt < 0xffff:
                    # gdb.write('type refcnt ok\n')
                    # type_ob_size = obtype.cast(_type_pyvarop)['ob_size']

                    # if type_ob_size > 0xffff:
                    #     return 0

                    # gdb.write('ob size ok\n')

                    for fieldname in ('tp_base', 'tp_free', 'tp_repr',
                                      'tp_new'):
                        if not looks_like_ptr(obtype[fieldname]):
                            return 0

                    # gdb.write('methods ok\n')

                    # Then this looks like a Python object:
                    return PyObjectPtr.from_pyobject_ptr(pyop)

    except UnicodeDecodeError as e:
        # print('is_pyobject_ptr 0x{:x}'.format(addr))
        # gdb.write(str(e) + '\n')
        pass

    except RuntimeError:
        pass  # Not a python object (or corrupt)