def parse_run(run_addr, proc=none): '''Given a run's address return a jemalloc.arena_run object''' global jeheap new_run = jemalloc.arena_run() new_run.start = run_addr try: new_run.bin_addr = dbg.read_memory(new_run.start, jeheap.DWORD_SIZE, proc) if jeheap.STANDALONE == false: new_run.size = dbg.read_memory(new_run.bin_addr + \ (6 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) new_run.end = new_run.start + new_run.size new_run.region_size = dbg.read_memory(new_run.bin_addr + \ (5 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) new_run.total_regions = dbg.read_memory(new_run.bin_addr + \ (7 * jeheap.DWORD_SIZE), jemalloc.INT_SIZE, proc) if new_run.total_regions > 10000 or new_run.total_regions <= 0: return none except: # print('[shadow] error parsing the metadata of run 0x%08x' % (run_addr)) return none # XXX: this isn't correct on jemalloc standalone *debug* variant try: new_run.free_regions = dbg.read_memory(new_run.start + \ jeheap.DWORD_SIZE + jemalloc.INT_SIZE, jemalloc.INT_SIZE, proc) except: # print('[shadow] error parsing the free regions of run 0x%08x' % (run_addr)) new_run.free_regions = 0 if new_run.free_regions < 0: new_run.free_regions = 0 # delete the run's regions new_run.regions[:] = [] # parse the run's regions new_run.reg0_offset = dbg.read_memory(new_run.bin_addr + \ (9 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) if new_run.reg0_offset > 10000 or new_run.reg0_offset <= 0: return none first_region_addr = reg0_addr = run_addr + new_run.reg0_offset regs_mask_bits = (new_run.total_regions / 8) + 1 regs_mask_addr = 0 regs_mask_str = '' if dbg_engine == 'gdb': regs_mask_addr = dbg.to_int(dbg.execute(dbg.regs_mask_addr_expr % \ (run_addr))) regs_mask_str = dbg.execute(dbg.regs_mask_addr_bits_expr % \ (regs_mask_bits, regs_mask_addr)) elif dbg_engine == 'pykd': regs_mask_addr = dbg.to_int(dbg.eval_expr(dbg.regs_mask_addr_expr % \ (run_addr))) regs_mask_str = dbg.execute(dbg.regs_mask_addr_bits_expr % \ (regs_mask_addr, regs_mask_bits)) else: # lldb regs_mask_str = '' regs_mask = '' if dbg_engine == 'gdb': for line in regs_mask_str.splitlines(): line = line[line.find(dbg.address_separator) + \ len(dbg.address_separator) : line.find('\n')] line = line.replace('\n', '') line = line.replace('\t', '') line = line.replace(' ', '') regs_mask += line elif dbg_engine == 'pykd': lines = regs_mask_str.splitlines() lines = lines[2:] for line in lines: line = line[line.find(dbg.address_separator) + \ len(dbg.address_separator) : \ line.rfind(dbg.address_separator)] line = line.replace('\n', '') line = line.replace('\t', '') line = line.replace(' ', '') regs_mask += line else: # lldb regs_mask = '' new_run.regs_mask = regs_mask first_region = jemalloc.region(0, first_region_addr, \ int(new_run.regs_mask[0])) try: first_region.content_preview = hex(dbg.read_memory(first_region.addr, \ jemalloc.INT_SIZE, proc)).rstrip('L') except: print('[shadow] error reading the first dword of region 0x%08x' \ % (first_region.addr)) first_region.content_preview = '' new_run.regions.append(first_region) for i in range(1, new_run.total_regions): try: current_region = jemalloc.region(i, 0, int(new_run.regs_mask[i])) except: current_region = jemalloc.region(i, 0, 0) current_region.addr = reg0_addr + (i * new_run.region_size) try: current_region.content_preview = \ hex(dbg.read_memory(current_region.addr, jemalloc.INT_SIZE, proc)).rstrip('L') except: current_region.content_preview = '' new_run.regions.append(current_region) return new_run
def jeparse_runs(proc): global jeheap for i in range(0, len(jeheap.arenas)): for j in range(0, len(jeheap.arenas[i].bins)): try: run_addr = jeheap.arenas[i].bins[j].run.start bin_addr = \ gdbutil.buf_to_le(proc.read_memory(run_addr, jeheap.DWORD_SIZE)) jeheap.arenas[i].bins[j].run.bin = bin_addr except RuntimeError: continue if jeheap.STANDALONE == false: jeheap.arenas[i].bins[j].run.size = \ gdbutil.buf_to_le(proc.read_memory(bin_addr + \ (6 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE)) jeheap.arenas[i].bins[j].run.end = \ run_addr + jeheap.arenas[i].bins[j].run.size jeheap.arenas[i].bins[j].run.total_regions = \ gdbutil.buf_to_le(proc.read_memory(bin_addr + \ (7 * jeheap.DWORD_SIZE), gdbutil.INT_SIZE)) # XXX: this isn't correct on jemalloc standalone *debug* variant jeheap.arenas[i].bins[j].run.free_regions = \ gdbutil.buf_to_le(proc.read_memory(run_addr + \ jeheap.DWORD_SIZE + gdbutil.INT_SIZE, gdbutil.INT_SIZE)) if jeheap.arenas[i].bins[j].run.free_regions < 0: jeheap.arenas[i].bins[j].run.free_regions = 0 # delete the run's regions jeheap.arenas[i].bins[j].run.regions[:] = [] reg0_offset = jeheap.arenas[i].bins[j].run.reg0_offset; first_region_addr = reg0_addr = run_addr + reg0_offset regs_mask_bits = \ (jeheap.arenas[i].bins[j].run.total_regions / 8) + 1 regs_mask_str = \ gdb.execute('x/%dbt arenas[%d].bins[%d].runcur.regs_mask' % \ (regs_mask_bits, i, j), to_string = true) regs_mask = '' for line in regs_mask_str.splitlines(): line = line[line.find(':') + 1 : line.find('\n')] line = line.replace('\n', '') line = line.replace('\t', '') line = line.replace(' ', '') regs_mask += line jeheap.arenas[i].bins[j].run.regs_mask = regs_mask first_region = jemalloc.region(0, first_region_addr, \ int(jeheap.arenas[i].bins[j].run.regs_mask[0])) addr = first_region.addr first_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') jeheap.arenas[i].bins[j].run.regions.append(first_region) for k in range(1, jeheap.arenas[i].bins[j].run.total_regions): try: current_region = jemalloc.region(k, 0, \ int(jeheap.arenas[i].bins[j].run.regs_mask[k])) except: current_region = jemalloc.region(k, 0, 0) addr = current_region.addr = \ reg0_addr + (k * jeheap.arenas[i].bins[j].run.region_size) current_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') jeheap.arenas[i].bins[j].run.regions.append(current_region)
def parse_run(run_addr, proc=none): """Given a run's address return a jemalloc.arena_run object""" global jeheap new_run = jemalloc.arena_run() new_run.start = run_addr try: new_run.bin_addr = dbg.read_memory(new_run.start, jeheap.DWORD_SIZE, proc) if jeheap.STANDALONE == false: new_run.size = dbg.read_memory(new_run.bin_addr + (6 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) new_run.end = new_run.start + new_run.size new_run.region_size = dbg.read_memory(new_run.bin_addr + (5 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) new_run.total_regions = dbg.read_memory(new_run.bin_addr + (7 * jeheap.DWORD_SIZE), jemalloc.INT_SIZE, proc) if new_run.total_regions > 10000 or new_run.total_regions <= 0: return none except: # print('[shadow] error parsing the metadata of run 0x%08x' % (run_addr)) return none # XXX: this isn't correct on jemalloc standalone *debug* variant try: new_run.free_regions = dbg.read_memory( new_run.start + jeheap.DWORD_SIZE + jemalloc.INT_SIZE, jemalloc.INT_SIZE, proc ) except: # print('[shadow] error parsing the free regions of run 0x%08x' % (run_addr)) new_run.free_regions = 0 if new_run.free_regions < 0: new_run.free_regions = 0 # delete the run's regions new_run.regions[:] = [] # parse the run's regions new_run.reg0_offset = dbg.read_memory(new_run.bin_addr + (9 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE, proc) if new_run.reg0_offset > 10000 or new_run.reg0_offset <= 0: return none first_region_addr = reg0_addr = run_addr + new_run.reg0_offset regs_mask_bits = (new_run.total_regions / 8) + 1 regs_mask_addr = 0 regs_mask_str = "" if dbg_engine == "gdb": regs_mask_addr = dbg.to_int(dbg.execute(dbg.regs_mask_addr_expr % (run_addr))) regs_mask_str = dbg.execute(dbg.regs_mask_addr_bits_expr % (regs_mask_bits, regs_mask_addr)) elif dbg_engine == "pykd": regs_mask_addr = dbg.to_int(dbg.eval_expr(dbg.regs_mask_addr_expr % (run_addr))) regs_mask_str = dbg.execute(dbg.regs_mask_addr_bits_expr % (regs_mask_addr, regs_mask_bits)) else: # lldb regs_mask_str = "" regs_mask = "" if dbg_engine == "gdb": for line in regs_mask_str.splitlines(): line = line[line.find(dbg.address_separator) + len(dbg.address_separator) : line.find("\n")] line = line.replace("\n", "") line = line.replace("\t", "") line = line.replace(" ", "") regs_mask += line elif dbg_engine == "pykd": lines = regs_mask_str.splitlines() lines = lines[2:] for line in lines: line = line[ line.find(dbg.address_separator) + len(dbg.address_separator) : line.rfind(dbg.address_separator) ] line = line.replace("\n", "") line = line.replace("\t", "") line = line.replace(" ", "") regs_mask += line else: # lldb regs_mask = "" new_run.regs_mask = regs_mask first_region = jemalloc.region(0, first_region_addr, int(new_run.regs_mask[0])) try: first_region.content_preview = hex(dbg.read_memory(first_region.addr, jemalloc.INT_SIZE, proc)).rstrip("L") except: print("[shadow] error reading the first dword of region 0x%08x" % (first_region.addr)) first_region.content_preview = "" new_run.regions.append(first_region) for i in range(1, new_run.total_regions): try: current_region = jemalloc.region(i, 0, int(new_run.regs_mask[i])) except: current_region = jemalloc.region(i, 0, 0) current_region.addr = reg0_addr + (i * new_run.region_size) try: current_region.content_preview = hex(dbg.read_memory(current_region.addr, jemalloc.INT_SIZE, proc)).rstrip( "L" ) except: current_region.content_preview = "" new_run.regions.append(current_region) return new_run
def jeparse_runs(proc): global jeheap for i in range(0, len(jeheap.arenas)): for j in range(0, len(jeheap.arenas[i].bins)): try: run_addr = jeheap.arenas[i].bins[j].run.start bin_addr = \ gdbutil.buf_to_le(proc.read_memory(run_addr, jeheap.DWORD_SIZE)) jeheap.arenas[i].bins[j].run.bin = bin_addr if jeheap.STANDALONE == false: jeheap.arenas[i].bins[j].run.size = \ gdbutil.buf_to_le(proc.read_memory(bin_addr + \ (6 * jeheap.DWORD_SIZE), jeheap.DWORD_SIZE)) jeheap.arenas[i].bins[j].run.end = \ run_addr + jeheap.arenas[i].bins[j].run.size jeheap.arenas[i].bins[j].run.total_regions = \ gdbutil.buf_to_le(proc.read_memory(bin_addr + \ (7 * jeheap.DWORD_SIZE), gdbutil.INT_SIZE)) except RuntimeError: continue # XXX: this isn't correct on jemalloc standalone *debug* variant try: jeheap.arenas[i].bins[j].run.free_regions = \ gdbutil.buf_to_le(proc.read_memory(run_addr + \ jeheap.DWORD_SIZE + gdbutil.INT_SIZE, gdbutil.INT_SIZE)) except RuntimeError: jeheap.arenas[i].bins[j].run.free_regions = 0 continue if jeheap.arenas[i].bins[j].run.free_regions < 0: jeheap.arenas[i].bins[j].run.free_regions = 0 # delete the run's regions jeheap.arenas[i].bins[j].run.regions[:] = [] # the run's regions reg0_offset = jeheap.arenas[i].bins[j].run.reg0_offset first_region_addr = reg0_addr = run_addr + reg0_offset regs_mask_bits = \ (jeheap.arenas[i].bins[j].run.total_regions / 8) + 1 regs_mask_str = \ gdb.execute('x/%dbt arenas[%d].bins[%d].runcur.regs_mask' % \ (regs_mask_bits, i, j), to_string = true) regs_mask = '' for line in regs_mask_str.splitlines(): line = line[line.find(':') + 1:line.find('\n')] line = line.replace('\n', '') line = line.replace('\t', '') line = line.replace(' ', '') regs_mask += line jeheap.arenas[i].bins[j].run.regs_mask = regs_mask first_region = jemalloc.region(0, first_region_addr, \ int(jeheap.arenas[i].bins[j].run.regs_mask[0])) addr = first_region.addr try: first_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') except RuntimeError: continue jeheap.arenas[i].bins[j].run.regions.append(first_region) for k in range(1, jeheap.arenas[i].bins[j].run.total_regions): try: current_region = jemalloc.region(k, 0, \ int(jeheap.arenas[i].bins[j].run.regs_mask[k])) except: current_region = jemalloc.region(k, 0, 0) addr = current_region.addr = \ reg0_addr + (k * jeheap.arenas[i].bins[j].run.region_size) try: current_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') except: continue jeheap.arenas[i].bins[j].run.regions.append(current_region)
def jeparse_runs(proc): global jeheap for i in range(0, len(jeheap.arenas)): for j in range(0, len(jeheap.arenas[i].bins)): try: run_addr = jeheap.arenas[i].bins[j].run.start bin_addr = gdbutil.buf_to_le(proc.read_memory(run_addr, jeheap.DWORD_SIZE)) jeheap.arenas[i].bins[j].run.bin = bin_addr except RuntimeError: continue # delete the run's regions jeheap.arenas[i].bins[j].run.regions[:] = [] # the run's regions reg0_offset = jeheap.arenas[i].bins[j].run.reg0_offset; first_region_addr = reg0_addr = run_addr + reg0_offset #regs_mask_bits = \ # (jeheap.arenas[i].bins[j].run.total_regions / 8) + 1 regs_mask_str = \ gdb.execute('x/%dbt je_arenas[%d].bins[%d].runcur.bitmap' % \ (BITMAP_GROUPS_MAX, i, j), to_string = true) regs_mask = '' for line in regs_mask_str.splitlines(): line = line[line.find(':') + 1 : line.find('\n')] line = line.replace('\n', '') line = line.replace('\t', '') line = line.replace(' ', '') regs_mask += line jeheap.arenas[i].bins[j].run.regs_mask = regs_mask first_region = jemalloc.region(0, first_region_addr, \ int(jeheap.arenas[i].bins[j].run.regs_mask[0])) addr = first_region.addr try: first_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') except RuntimeError: continue jeheap.arenas[i].bins[j].run.regions.append(first_region) for k in range(1, jeheap.arenas[i].bins[j].run.total_regions): try: current_region = jemalloc.region(k, 0, \ int(jeheap.arenas[i].bins[j].run.regs_mask[k])) except: current_region = jemalloc.region(k, 0, 0) addr = current_region.addr = \ reg0_addr + (k * jeheap.arenas[i].bins[j].run.region_size) try: current_region.content_preview = \ hex(gdbutil.buf_to_le(proc.read_memory(addr, \ gdbutil.INT_SIZE))).rstrip('L') except: continue jeheap.arenas[i].bins[j].run.regions.append(current_region)