• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import sys
2
3import traceback
4
5from cffi import api as _api
6
7
8sys.modules['ssl'] = None
9sys.modules['_hashlib'] = None
10
11
12_ffi = _api.FFI()
13_ffi.cdef(
14    """
15    void *malloc(size_t size);
16    void free(void *ptr);
17    void *realloc(void *ptr, size_t size);
18
19    int  CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
20
21    int backtrace(void **buffer, int size);
22    char **backtrace_symbols(void *const *buffer, int size);
23    void backtrace_symbols_fd(void *const *buffer, int size, int fd);
24    """)  # noqa
25_api = _ffi.verify(
26    """
27    #include <openssl/crypto.h>
28    #include <stdlib.h>
29    #include <execinfo.h>
30    """, libraries=["crypto"])
31C = _ffi.dlopen(None)
32
33verbose = False
34
35
36def log(s):
37    if verbose:
38        print(s)
39
40
41def _backtrace():
42    buf = _ffi.new("void*[]", 64)
43    result = _api.backtrace(buf, len(buf))
44    strings = _api.backtrace_symbols(buf, result)
45    stack = [_ffi.string(strings[i]) for i in range(result)]
46    C.free(strings)
47    return stack
48
49
50@_ffi.callback("void*(*)(size_t)")
51def malloc(n):
52    memory = C.malloc(n)
53    python_stack = traceback.extract_stack(limit=3)
54    c_stack = _backtrace()
55    heap[memory] = [(n, python_stack, c_stack)]
56    log("malloc(%d) -> %s" % (n, memory))
57    return memory
58
59
60@_ffi.callback("void*(*)(void*, size_t)")
61def realloc(p, n):
62    memory = C.realloc(p, n)
63    old = heap.pop(p)
64
65    python_stack = traceback.extract_stack(limit=3)
66    c_stack = _backtrace()
67
68    old.append((n, python_stack, c_stack))
69    heap[memory] = old
70    log("realloc(0x%x, %d) -> %s" % (int(_ffi.cast("int", p)), n, memory))
71    return memory
72
73
74@_ffi.callback("void(*)(void*)")
75def free(p):
76    if p != _ffi.NULL:
77        C.free(p)
78        del heap[p]
79        log("free(0x%x)" % (int(_ffi.cast("int", p)),))
80
81
82if _api.CRYPTO_set_mem_functions(malloc, realloc, free):
83    log('Enabled memory debugging')
84    heap = {}
85else:
86    log('Failed to enable memory debugging')
87    heap = None
88