def jeparse_chunks(): global jeheap # delete the chunks' list jeheap.chunks[:] = [] try: root = gdbutil.to_int(gdb.parse_and_eval('chunk_rtree.root')) height = gdbutil.to_int(gdb.parse_and_eval('chunk_rtree.height')) level2bits = [] for i in range(0, height): expr = 'chunk_rtree.level2bits[%d]' % (i) level2bits.append(gdbutil.to_int(gdb.parse_and_eval(expr))) except: print('[unmask_jemalloc] error: cannot parse chunk radix tree') sys.exit() # check if we're running on x86_64 if jeheap.DWORD_SIZE == 8: dw_fmt = 'g' else: dw_fmt = 'w' # parse the radix tree using a stack stack = [(root, 0)] while len(stack): (node, node_height) = stack.pop() child_cnt = 1 << level2bits[node_height] dump = gdb.execute('x/%d%sx %#x' % (child_cnt, dw_fmt, node), to_string=true) for line in dump.split('\n'): line = line[line.find(':') + 1:] for address in line.split(): address = int(address, 16) if address != 0: # leaf nodes hold pointers to actual values if node_height == height - 1: expr = '((arena_chunk_t *)%#x)->arena' % address arena = gdbutil.to_int(gdb.parse_and_eval(expr)) exists = false if arena in [i.addr for i in jeheap.arenas]: exists = true if exists: jeheap.chunks.append( jemalloc.arena_chunk(address, arena)) else: jeheap.chunks.append(jemalloc.arena_chunk(address)) # non-leaf nodes are inserted in the stack else: stack.append((address, node_height + 1))
def jeparse_chunks(): global jeheap # delete the chunks' list jeheap.chunks = [] try: root = gdbutil.to_int(gdb.parse_and_eval('chunk_rtree.root')) height = gdbutil.to_int(gdb.parse_and_eval('chunk_rtree.height')) level2bits = [] for i in range(0, height): expr = 'chunk_rtree.level2bits[%d]' % (i) level2bits.append(gdbutil.to_int(gdb.parse_and_eval(expr))) except: print '[unmask_jemalloc] error: cannot parse chunk radix tree' sys.exit() # check if we're running on x86_64 if jeheap.DWORD_SIZE == 8: dw_fmt = 'g' else: dw_fmt = 'w' # parse the radix tree using a stack stack = [(root, 0)] while len(stack): (node, node_height) = stack.pop() child_cnt = 1 << level2bits[node_height] dump = gdb.execute('x/%d%sx %#x' % (child_cnt, dw_fmt, node), to_string = true) for line in dump.split('\n'): line = line[line.find(':') + 1:] for address in line.split(): address = int(address, 16) if address != 0: # leaf nodes hold pointers to actual values if node_height == height - 1: expr = '((arena_chunk_t *)%#x)->arena' % address arena = gdbutil.to_int(gdb.parse_and_eval(expr)) exists = false if arena in [i.addr for i in jeheap.arenas]: exists = true if exists: jeheap.chunks.append(jemalloc.arena_chunk(address, arena)) else: jeheap.chunks.append(jemalloc.arena_chunk(address)) # non-leaf nodes are inserted in the stack else: stack.append((address, node_height + 1))
def parse_chunks(): global jeheap global dbg_engine # delete the chunks' list jeheap.chunks[:] = [] try: root = dbg.to_int(dbg.eval_expr(dbg.chunk_rtree_root_expr)) height = dbg.to_int(dbg.eval_expr(dbg.chunk_rtree_height_expr)) level2bits = [] for i in range(0, height): expr = dbg.chunk_rtree_level2bits_expr % (i) level2bits.append(dbg.to_int(dbg.eval_expr(expr))) except: print('[shadow] error: cannot parse chunk radix tree') sys.exit() # XXX: check if we're running on x86_64, # not required for windbg/pykd (see the dp command) if jeheap.DWORD_SIZE == 8: if dbg_engine == 'gdb': dw_fmt = 'g' else: # lldb dw_fmt = 'XXX' else: if dbg_engine == 'gdb': dw_fmt = 'w' else: # lldb dw_fmt = 'XXX' # parse the radix tree using a stack stack = [(root, 0)] while len(stack): (node, node_height) = stack.pop() child_cnt = 1 << level2bits[node_height] if dbg_engine == 'gdb': expr = dbg.chunk_radix_expr % (child_cnt, dw_fmt, node) elif dbg_engine == 'pykd': child_cnt = child_cnt / 6 # XXX: is this correct on 64-bits? expr = dbg.chunk_radix_expr % (node, child_cnt) else: # lldb expr = '' dump = dbg.execute(expr) for line in dump.split('\n'): line = line[line.find(dbg.address_separator) + \ len(dbg.address_separator):] for address in line.split(): try: address = int(address, 16) except: address = 0 if address != 0: # leaf nodes hold pointers to actual values if node_height == height - 1: expr = dbg.chunk_arena_expr % address try: arena_addr = dbg.to_int(dbg.eval_expr(expr)) except: arena_addr = 0 exists = false if arena_addr in [i.addr for i in jeheap.arenas]: exists = true if exists: jeheap.chunks.append( jemalloc.arena_chunk(address, arena_addr)) else: jeheap.chunks.append(jemalloc.arena_chunk(address)) # non-leaf nodes are inserted in the stack else: stack.append((address, node_height + 1))
def parse_chunks(): global jeheap global dbg_engine # delete the chunks' list jeheap.chunks[:] = [] try: root = dbg.to_int(dbg.eval_expr(dbg.chunk_rtree_root_expr)) height = dbg.to_int(dbg.eval_expr(dbg.chunk_rtree_height_expr)) level2bits = [] for i in range(0, height): expr = dbg.chunk_rtree_level2bits_expr % (i) level2bits.append(dbg.to_int(dbg.eval_expr(expr))) except: print("[shadow] error: cannot parse chunk radix tree") sys.exit() # XXX: check if we're running on x86_64, # not required for windbg/pykd (see the dp command) if jeheap.DWORD_SIZE == 8: if dbg_engine == "gdb": dw_fmt = "g" else: # lldb dw_fmt = "XXX" else: if dbg_engine == "gdb": dw_fmt = "w" else: # lldb dw_fmt = "XXX" # parse the radix tree using a stack stack = [(root, 0)] while len(stack): (node, node_height) = stack.pop() child_cnt = 1 << level2bits[node_height] if dbg_engine == "gdb": expr = dbg.chunk_radix_expr % (child_cnt, dw_fmt, node) elif dbg_engine == "pykd": if dbg.get_arch() == "x86": child_cnt = child_cnt / 6 expr = dbg.chunk_radix_expr % (node, child_cnt) else: # lldb expr = "" dump = dbg.execute(expr) for line in dump.split("\n"): line = line[line.find(dbg.address_separator) + len(dbg.address_separator) :] for address in line.split(): try: address = int(address, 16) except: address = 0 if address != 0: # leaf nodes hold pointers to actual values if node_height == height - 1: expr = dbg.chunk_arena_expr % address try: arena_addr = dbg.to_int(dbg.eval_expr(expr)) except: arena_addr = 0 exists = false if arena_addr in [i.addr for i in jeheap.arenas]: exists = true if exists: jeheap.chunks.append(jemalloc.arena_chunk(address, arena_addr)) else: jeheap.chunks.append(jemalloc.arena_chunk(address)) # non-leaf nodes are inserted in the stack else: stack.append((address, node_height + 1))
def jeparse_chunks(): global jeheap # delete the chunks' list jeheap.chunks[:] = [] try: height = gdbutil.to_int(gdb.parse_and_eval('je_chunks_rtree.height')) except: print('[unmask_jemalloc] error: cannot parse chunk radix tree') sys.exit() # check if we're running on x86_64 # TODO: make it global if jeheap.DWORD_SIZE == 8: dw_fmt = 'g' else: dw_fmt = 'w' # insert root node to stack first (on level[0]) stack = [] for level in range(0, 3): bits = gdbutil.to_int(gdb.parse_and_eval('je_chunks_rtree.levels[%d].bits' % (level))) for bit in range(0, bits): try: subtree = gdbutil.to_int(gdb.parse_and_eval('je_chunks_rtree.levels[%d].subtree[%d]' %(level, bit))) print(subtree) if subtree == 0: continue except: continue print("f****d!") while len(stack): (node, node_height) = stack.pop() child_cnt = gdbutil.to_int(node.bits) dump = gdb.execute('x/%d%sx %#x' % (child_cnt, dw_fmt, node), to_string = true) print(dump) print('--------') for line in dump.split('\n'): line = line[line.find(':') + 1:] for address in line.split(): address = int(address, 16) if address != 0: # leaf nodes hold pointers to actual values if node_height == height - 1: expr = '((arena_chunk_t *)%#x)->arena' % address arena = gdbutil.to_int(gdb.parse_and_eval(expr)) exists = false if arena in [i.addr for i in jeheap.arenas]: exists = true if exists: jeheap.chunks.append(jemalloc.arena_chunk(address, arena)) else: jeheap.chunks.append(jemalloc.arena_chunk(address)) # non-leaf nodes are inserted in the stack else: stack.append((address, node_height + 1))