def FuzzySymbolLookup(symbol_name): try: gdb.parse_and_eval(symbol_name) return symbol_name except gdb.error as err: # No symbol in current context. We might be dealing with static symbol # disambiguation employed by compilers. For example, on debian's current # python build, the 'interp_head' symbol (which we need) has been renamed # to 'interp_head.42174'. This mangling is of course compiler-specific. # We try to get around it by using gdb's built-in regex support when # looking up variables # Format: # All variables matching regular expression "<symbol_name>": # # File <source_file>: # <Type><real_symbol_name>; # We're only interested in <real_symbol_name>. listing = gdb.execute('info variables %s' % symbol_name, to_string=True) # sigh... We want whatever was in front of ;, but barring any *s. # If you are a compiler dev who mangles symbols using ';' and '*', # you deserve this breakage. mangled_name = re.search(r'\**(\S+);$', listing, re.MULTILINE) try: if mangled_name: gdb.parse_and_eval('\'%s\'' % mangled_name.group(1)) return '\'%s\'' % mangled_name.group(1) except gdb.error: # We could raise this, but the original exception will likely describe # the problem better raise err
def _next_instn_jump_len(gdb_frame): '-> None means don\'t jump' try: arch_name = gdb_frame.architecture().name() except AttributeError: arch_name = None if arch_name.startswith('powerpc:'): # 'powerpc:common64' on ppc64 big endian i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4)) if (i == b'\x7d\x82\x10\x08') or (i == b'\x08\x10\x82\x7d'): return 4 else: # not stopped on a breakpoint instruction return None triplet = _target_triplet() if re.match(r'^arm-', triplet): i = bytes(gdb.selected_inferior().read_memory(gdb.parse_and_eval('$pc'), 4)) if i == b'\xf0\x01\xf0\xe7': return 4 elif i.startswith(b'\x01\xde'): return 2 elif i == b'\xf0\xf7\x00\xa0 ': # 'arm_linux_thumb2_le_breakpoint' from arm-linux-tdep.c in GDB return 4 else: # not stopped on a breakpoint instruction return None return None
def root_documents(): gdb.newest_frame().older().select() # Have gdb.Value live_instances = gdb.parse_and_eval('g_liveInstances') print live_instances document = gdb.lookup_type('WebCore::Document') print document for field in document.fields(): if field.name.find('dump') >= 0: print ' ' + field.name #symbol = gdb.lookup_global_symbol('listLiveInstances') #print symbol dumper = gdb.parse_and_eval('listLiveInstances') print type_code[dumper.type.code] print live_instances begin = live_instances['begin'] print begin print type_code[begin.type.code] print begin.type print begin.dynamic_type # result = begin () print '---' print live_instances['m_impl'] print live_instances['m_impl']['m_table'] print live_instances.type for field in live_instances.type.fields(): print field.name for field2 in live_instances[field.name].type.fields(): print ' ' + field2.name print live_instances.address
def trace (self): self.type = 'list' self.curr = None self.main = gdb.parse_and_eval('rb_main_thread') self.unwind = gdb.parameter('unwindonsignal') gdb.execute('set unwindonsignal on') gdb.execute('watch rb_curr_thread') gdb.breakpoints()[-1].silent = True num = gdb.breakpoints()[-1].number try: prev = None while True: gdb.execute('continue') curr = gdb.parse_and_eval('rb_curr_thread') if curr == prev: break self.print_thread(curr) prev = curr except KeyboardInterrupt: None gdb.execute('delete %d' % num) gdb.execute('set unwindonsignal %s' % (self.unwind and 'on' or 'off'))
def invoke(self, arg='', from_tty=False, sig=0): gdb.newest_frame().select() regs = [0] * 19 # parse_and_eval seems to be the only way to access target registers for i in range(16): regs[i] = int(gdb.parse_and_eval("(unsigned long)$r%d" % i)) regs[16] = int(gdb.parse_and_eval("(unsigned long)$xpsr")) # Don't know how to include other registers in core dump prstatus = ARM_prstatus() prstatus.pr_cursig = sig # Is it possible to include a target register description? notes = note_desc("CORE", 1, prstatus.dumps() + struct.pack("<19L", *regs)) inf = gdb.selected_inferior() # How do we query the memory map from GDB? # TODO: Use 'info mem' ram = inf.read_memory(0x20000000, 128*1024) ccmram = inf.read_memory(0x10000000, 64*1024) scs = inf.read_memory(0xE000ED00, 0x40) core = CoreFile() core.set_type(Elf32_Ehdr.ET_CORE) core.set_machine(0x28) #ARM core.add_program(Elf32_Phdr.PT_NOTE, 0, notes) core.add_program(Elf32_Phdr.PT_LOAD, 0x10000000, ccmram) core.add_program(Elf32_Phdr.PT_LOAD, 0x20000000, ram) core.add_program(Elf32_Phdr.PT_LOAD, 0xE000ED00, scs) fn = arg if arg else gcore_file_name.value fn += "-" + time.strftime("%y%m%d-%H%M%S") core.dump(open(fn, "w")) print "(core dumped to %r)" % fn
def stop(self): rcx_val_raw = gdb.parse_and_eval('$rcx').cast(self.long_int) rcx_val = int(rcx_val_raw) & 0xffffffffffffffff fix = 2**64 if rcx_val == self.sysenter_esp: print("[+] Reading RAX...") rax_val_raw = gdb.parse_and_eval('$rax').cast(self.long_int) rax_val = int(rax_val_raw) & 0xffffffffffffffff print("[+] Copy Chain initial ptr: %x " % rax_val) rax_val_str = "0x%x" % rax_val print("-----") memory_raw = gdb.execute("x/10g %s" % rax_val_str, to_string = True) content = memory_raw.split('\n') for row in content: if row: data = row.split('\t') print("%s\t%s\t%s" % (data[0], hex(int(data[1]) + fix), hex(int(data[2]) + fix))) print("-----") return True return False
def get_arg(self, num): if num == 0: return long(gdb.parse_and_eval("$r0")) elif num == 1: return long(gdb.parse_and_eval("$r1")) else: raise Exception("get_arg %d is not supported." %num)
def invoke (self, arg, from_tty): self.dont_repeat() num = arg and int(arg) or 100 self.setup() try: while num > 0: num -= 1 gdb.execute('continue') frame = gdb.selected_frame() if frame.pc() != self.func: raise KeyboardInterrupt node = gdb.parse_and_eval('(NODE*) $rsi') file = node['nd_file'].string() line = gdb.parse_and_eval('nd_line(%s)' % node) method = gdb.parse_and_eval('rb_id2name($rcx)') method = method > 0 and method.string() or '(unknown)' print "%s in %s:%d" % (method,file,line) self.teardown() except KeyboardInterrupt: self.teardown() except RuntimeError, text: self.teardown() if not re.search('signaled while in a function called from GDB', text): raise
def print_stack (self, th, frame, node): while True: stk_pos = th['stk_pos'] stk_ptr = th['stk_ptr'] stk_len = th['stk_len'] addr = gdb.parse_and_eval('(VALUE*)%s' % frame) if not self.is_heap_stack and th != self.curr and stk_pos < addr and addr < (stk_pos+stk_len): frame = (addr-stk_pos) + stk_ptr frame = gdb.parse_and_eval('(struct FRAME *)%s' % frame) node = frame['node'] file = node['nd_file'].string() line = gdb.parse_and_eval('nd_line(%s)' % node) type = gdb.parse_and_eval('(enum node_type) nd_type(%s)' % node) if frame['last_func']: try: method = gdb.parse_and_eval('rb_id2name(%s)' % frame['last_func']).string() except: method = '(unknown)' else: method = '(unknown)' print " ", print str(type).lower().center(18), "%s in %s:%d" % (method, file, line) if frame['prev'] == 0 or frame['last_func'] == 0: break frame = frame['prev'] node = frame['node'] if node == 0: break
def invoke(self, arg, from_tty): lsa = gdb.parse_and_eval('logalloc::shard_segment_pool') segment_size = int(gdb.parse_and_eval('logalloc::segment::size')) lsa_mem = int(lsa['_segments_in_use']) * segment_size non_lsa_mem = int(lsa['_non_lsa_memory_in_use']) total_mem = lsa_mem + non_lsa_mem gdb.write('Log Structured Allocator\n\nLSA memory in use: {lsa_mem:>16}\n' 'Non-LSA memory in use: {non_lsa_mem:>12}\nTotal memory in use: {total_mem:>14}\n\n' .format(lsa_mem=lsa_mem, non_lsa_mem = non_lsa_mem, total_mem = total_mem)) er_goal = int(lsa['_current_emergency_reserve_goal']) er_max = int(lsa['_emergency_reserve_max']) er_current = int(lsa['_emergency_reserve']['_size']) gdb.write('Emergency reserve goal: {er_goal:>11}\nEmergency reserve max: {er_max:>12}\n' 'Emergency reserve current: {er_current:>8}\n\n' .format(er_goal=er_goal, er_max=er_max, er_current=er_current)) lsa_tracker = gdb.parse_and_eval('logalloc::tracker_instance._impl')['_M_t']['_M_head_impl'] regions = lsa_tracker['_regions'] region = regions['_M_impl']['_M_start'] gdb.write('LSA regions:\n') while region != regions['_M_impl']['_M_finish']: gdb.write(' Region #{r_id}\n - reclaimable: {r_en:>14}\n' ' - evictable: {r_ev:16}\n - non-LSA memory: {r_non_lsa:>11}\n' ' - closed LSA memory: {r_lsa:>8}\n - unused memory: {r_unused:>12}\n' .format(r_id=int(region['_id']), r_en=bool(region['_reclaiming_enabled']), r_ev=bool(region['_evictable']), r_non_lsa=int(region['_non_lsa_occupancy']['_total_space']), r_lsa=int(region['_closed_occupancy']['_total_space']), r_unused=int(region['_closed_occupancy']['_free_space']))) region = region + 1
def find_vrf_references(vrf_ptr): global filter_vrf_pointer global print_db_header print_db_header = False filter_vrf_pointer = gdb.parse_and_eval("(VrfEntry *)" + str(vrf_ptr)) print("looking for VRF Delete Actor") if int(filter_vrf_pointer["deleter_"]["px"]) != 0: if filter_vrf_pointer["deleter_"]["px"].dereference()["table_"]["px"] == filter_vrf_pointer: print("Delete Actor in VRF is also holding a reference") print("looking for Agent Route Tables") table_count = int(gdb.parse_and_eval("Agent::ROUTE_TABLE_MAX")) for num in range(1, table_count): if filter_vrf_pointer["rt_table_delete_bmap_"] & (1 << num) == 0: rt_table = filter_vrf_pointer["rt_table_db_"][num] print("Active route table = " + str(rt_table) + " table type = " + str(rt_table.dynamic_type)) print("looking for Virtual Networks") dump_vn_entries(db_entry_filter_vrf) print("looking for Interfaces") dump_intf_entries(db_entry_filter_vrf) print("looking for Nexthops") dump_nh_entries(db_entry_filter_vrf) print("looking for Mirror Entries") dump_mirror_entries(db_entry_filter_vrf) print("looking for VRF Assign Entries") dump_vrf_assign_entries(db_entry_filter_vrf) print_db_header = True
def __call__(self, pending_frame): if self.recurse_level > 0: gdb.write("TestUnwinder: Recursion detected - returning early.\n") return None self.recurse_level += 1 TestUnwinder.inc_count() if TestUnwinder.test == 'check_user_reg_pc' : pc = pending_frame.read_register('pc') pc_as_int = int(pc.cast(gdb.lookup_type('int'))) # gdb.write("In unwinder: pc=%x\n" % pc_as_int) elif TestUnwinder.test == 'check_pae_pc' : pc = gdb.parse_and_eval('$pc') pc_as_int = int(pc.cast(gdb.lookup_type('int'))) # gdb.write("In unwinder: pc=%x\n" % pc_as_int) elif TestUnwinder.test == 'check_undefined_symbol' : try: val = gdb.parse_and_eval("undefined_symbol") except Exception as arg: pass self.recurse_level -= 1 return None
def print_parcels(): ### Retrieve Action Table entries number_of_actions = gdb.parse_and_eval('here->actions->n') actions = gdb.parse_and_eval('here->actions->entries') ### Display parcels for current rank. print ("--------------------\nScheduler Parcels:\n--------------------") ### Retrieve Worker Threads number_of_workers = gdb.parse_and_eval('here->sched->n_workers') print ("Total number of worker threads: %d" % number_of_workers) workers = gdb.parse_and_eval('here->sched->workers') ### Loop through each worker thread and print all the parcels for i in range(0, int(number_of_workers)): print ("--------------------\nWorker %d info:\n--------------------" % i) worker = workers[i] ### Retrieve current parcel current = worker['current'] print ("Current parcel address: %s" % current) current_parcel = current.dereference() action_nbr = current_parcel['action'] print ("Current action: %s " % actions[action_nbr]['key']) size = current_parcel['size'] print ("Parcel size: %d" % size) data_ptr = current_parcel['buffer'] print ("Buffer address: %s" % data_ptr)
def invoke(self, arg, from_tty): gdb.execute('target remote :1234') global status_enum status_enum.running = gdb.parse_and_eval('sched::thread::running') status_enum.waiting = gdb.parse_and_eval('sched::thread::waiting') status_enum.queued = gdb.parse_and_eval('sched::thread::queued') status_enum.waking = gdb.parse_and_eval('sched::thread::waking')
def check_step(): "Step an instruction, check it moved." start_pc = gdb.parse_and_eval('$pc') gdb.execute("si") end_pc = gdb.parse_and_eval('$pc') return not (start_pc == end_pc)
def _fill_locals_dict(self, executor, local_dict_pointer): "Fill a remotely allocated dict with values from the Cython C stack" cython_func = self.get_cython_function() for name, cyvar in cython_func.locals.iteritems(): if (cyvar.type == PythonObject and self.is_initialized(cython_func, name)): try: val = gdb.parse_and_eval(cyvar.cname) except RuntimeError: continue else: if val.is_optimized_out: continue pystringp = executor.alloc_pystring(name) code = ''' (PyObject *) PyDict_SetItem( (PyObject *) %d, (PyObject *) %d, (PyObject *) %s) ''' % (local_dict_pointer, pystringp, cyvar.cname) try: if gdb.parse_and_eval(code) < 0: gdb.parse_and_eval('PyErr_Print()') raise gdb.GdbError("Unable to execute Python code.") finally: # PyDict_SetItem doesn't steal our reference executor.xdecref(pystringp)
def stop(self): registers = ["$edx"] for register in registers: try: length = int(gdb.parse_and_eval('$ecx')) # IDA Demo 6.6 + GDB FTW! p = struct.pack(">i", length) length = struct.unpack("<I", p)[0] address = gdb.parse_and_eval(register) address = int(address) p = struct.pack(">i", address) u = struct.unpack("<I", p) address = u[0] except: traceback.print_exc() return True try: data = gdb.inferiors()[0].read_memory(address, length) # reduce noise by checking for password ("passsword12345"), not strictly required :-) if "70617373776f72643132333435" in str(binascii.hexlify(data)): self.trailing_calls = 1 print(register, binascii.hexlify(data), length) elif self.trailing_calls > 0: print(register, binascii.hexlify(data), length) self.trailing_calls = self.trailing_calls - 1 except gdb.MemoryError: traceback.print_exc() return True except: traceback.print_exc() return True # return False to continue the execution of the program return False
def check(): print "" print "Check heap regions......................." n = gdb.parse_and_eval("num_regions") blks = gdb.parse_and_eval("regions") i = 0 while i < n: blk = blks + i addr = int(blk['p'].cast(gdb.lookup_type('long'))) my_blk = gdb.heap_block(addr) match = True if blk['inuse']: if blk['p'] != my_blk.address or blk['size'] != my_blk.size or not my_blk.inuse: match = False else: if my_blk.inuse: match = False if not match: print "[%d] addr=0x%x size=%u inuse=%d" % (i, blk['p'], blk['size'], blk['inuse']) print "[%d] addr=0x%x size=%u inuse=%d" % (i, my_blk.address, my_blk.size, my_blk.inuse) raise Exception('core analyzer returns wrong heap block info') i = i + 1 print "%d heap memory blocks are verified" % (n) print "Passed ......................." print ""
def invoke(self, arg, from_tty): cpu_mem = gdb.parse_and_eval('memory::cpu_mem') small_pools = cpu_mem['small_pools'] nr = small_pools['nr_small_pools'] page_size = int(gdb.parse_and_eval('memory::page_size')) gdb.write('{objsize:>5} {span_size:>6} {use_count:>10} {memory:>12} {wasted_percent:>5}\n' .format(objsize='objsz', span_size='spansz', use_count='usedobj', memory='memory', wasted_percent='wst%')) for i in range(int(nr)): sp = small_pools['_u']['a'][i] object_size = int(sp['_object_size']) span_size = int(sp['_span_size']) * page_size free_count = int(sp['_free_count']) spans_in_use = int(sp['_spans_in_use']) memory = spans_in_use * span_size use_count = spans_in_use * int(span_size / object_size) - free_count wasted = free_count * object_size wasted_percent = wasted * 100.0 / memory if memory else 0 gdb.write('{objsize:5} {span_size:6} {use_count:10} {memory:12} {wasted_percent:5.1f}\n' .format(objsize=object_size, span_size=span_size, use_count=use_count, memory=memory, wasted_percent=wasted_percent)) gdb.write('Page spans:\n') gdb.write('{index:5} {size:>13} {total}\n'.format(index="index", size="size [B]", total="free [B]")) for index in range(int(cpu_mem['nr_span_lists'])): span_list = cpu_mem['fsu']['free_spans'][index] front = int(span_list['_front']) pages = cpu_mem['pages'] total = 0 while front: span = pages[front] total += int(span['span_size']) front = int(span['link']['_next']) gdb.write('{index:5} {size:13} {total}\n'.format(index=index, size=(1<<index)*page_size, total=total*page_size))
def stop(self): registers = ["$edx"] for register in registers: try: length = int(gdb.parse_and_eval('$ecx')) # IDA Pro + GDB FTW! p = struct.pack(">i", length) length = struct.unpack("<I", p)[0] address = gdb.parse_and_eval(register) address = int(address) p = struct.pack(">i", address) u = struct.unpack("<I", p) address = u[0] except: traceback.print_exc() return True try: data = gdb.inferiors()[0].read_memory(address, length) print(register, binascii.hexlify(data), length) except gdb.MemoryError: traceback.print_exc() return True except: traceback.print_exc() return True # return False to continue the execution of the program return False
def all_traces(): constants = TraceConstants() inf = gdb.selected_inferior() trace_log = gdb.lookup_global_symbol('trace_log').value() max_trace = ulong(gdb.parse_and_eval('max_trace')) trace_log = inf.read_memory(trace_log.address, max_trace) trace_page_size = ulong(gdb.parse_and_eval('trace_page_size')) last = ulong(gdb.lookup_global_symbol('trace_record_last').value()['_M_i']) last %= max_trace pivot = align_up(last, trace_page_size) trace_log = trace_log[pivot:] + trace_log[:pivot] last += max_trace - pivot backtrace_len = constants.backtrace_len i = 0 while i < last: tp_key, thread, time, cpu, flags = struct.unpack('QQQII', trace_log[i:i+32]) if tp_key == 0: i = align_up(i + 8, trace_page_size) continue tp = gdb.Value(tp_key).cast(gdb.lookup_type('tracepoint_base').pointer()) sig = sig_to_string(ulong(tp['sig'])) # FIXME: cache i += 32 backtrace = None if flags & 1: backtrace = struct.unpack('Q' * backtrace_len, trace_log[i:i+8*backtrace_len]) i += 8 * backtrace_len size = struct.calcsize(sig) data = struct.unpack(sig, trace_log[i:i+size]) i += size i = align_up(i, 8) yield Trace(tp, thread, time, cpu, data, backtrace=backtrace)
def stop(self): registers = ["$edx"] # reduce noise, not strictly required :-) fff = gdb.execute("bt", to_string=True) if "0x4013af0f" in fff or "0x644800f4" in fff: print("Skipping ...") return False for register in registers: try: length = int(gdb.parse_and_eval('$ecx')) # IDA Pro + GDB FTW! p = struct.pack(">i", length) length = struct.unpack("<I", p)[0] address = gdb.parse_and_eval(register) address = int(address) p = struct.pack(">i", address) u = struct.unpack("<I", p) address = u[0] except: traceback.print_exc() return True try: data = gdb.inferiors()[0].read_memory(address, length) print(register, binascii.hexlify(data), length) except gdb.MemoryError: traceback.print_exc() return True except: traceback.print_exc() return True # return False to continue the execution of the program return False
def python_categorization(usage_set): # special-cased categorization for CPython # The Objects/stringobject.c:interned dictionary is typically large, # with its PyDictEntry table occuping 200k on a 64-bit build of python 2.6 # Identify it: try: val_interned = gdb.parse_and_eval('interned') pyop = PyDictObjectPtr.from_pyobject_ptr(val_interned) ma_table = long(pyop.field('ma_table')) usage_set.set_addr_category(ma_table, Category('cpython', 'PyDictEntry table', 'interned'), level=1) except RuntimeError: pass # Various kinds of per-type optimized allocator # See Modules/gcmodule.c:clear_freelists # The Objects/intobject.c: block_list try: val_block_list = gdb.parse_and_eval('block_list') if str(val_block_list.type.target()) != 'PyIntBlock': raise RuntimeError while long(val_block_list) != 0: usage_set.set_addr_category(long(val_block_list), Category('cpython', '_intblock', ''), level=0) val_block_list = val_block_list['next'] except RuntimeError: pass
def invoke(self, arg, from_tty): ptr = int(arg, 0) owning_thread = None for t, start, size in seastar_memory_layout(): if ptr >= start and ptr < start + size: owning_thread = t break if not owning_thread: gdb.write("Not managed by seastar\n") return msg = "thread %d" % t.num owning_thread.switch() cpu_mem = gdb.parse_and_eval('memory::cpu_mem') page_size = int(gdb.parse_and_eval('memory::page_size')) offset = ptr - int(cpu_mem['memory']) page = cpu_mem['pages'][offset / page_size]; if page['free']: msg += ', page is free' gdb.write(msg + '\n') return pool = page['pool'] offset_in_span = page['offset_in_span'] * page_size + ptr % page_size first_page_in_span = cpu_mem['pages'][offset / page_size - page['offset_in_span']]; if pool: object_size = int(pool['_object_size']) msg += ', small (size <= %d)' % object_size offset_in_object = offset_in_span % object_size free_object_ptr = gdb.lookup_type('void').pointer().pointer() char_ptr = gdb.lookup_type('char').pointer() # pool's free list next_free = pool['_free'] free = False while next_free: if ptr >= next_free and ptr < next_free.reinterpret_cast(char_ptr) + object_size: free = True break next_free = next_free.reinterpret_cast(free_object_ptr).dereference() if not free: # span's free list next_free = first_page_in_span['freelist'] while next_free: if ptr >= next_free and ptr < next_free.reinterpret_cast(char_ptr) + object_size: free = True break next_free = next_free.reinterpret_cast(free_object_ptr).dereference() if free: msg += ', free' else: msg += ', live (0x%x +%d)' % (ptr - offset_in_object, offset_in_object) else: msg += ', large' gdb.write(msg + '\n') return
def stop(self): bp_in_urts = is_bp_in_urts() if bp_in_urts == True: if SIZE == 4: tcs_addr_1 = gdb.parse_and_eval("$eax") tcs_addr = ctypes.c_uint32(tcs_addr_1).value elif SIZE == 8: tcs_addr_1 = gdb.parse_and_eval("$rdi") tcs_addr = ctypes.c_uint64(tcs_addr_1).value enclave_info_addr = gdb.parse_and_eval("*(void **)&g_debug_enclave_info_list") if enclave_info_addr != 0: node = retrieve_enclave_info(enclave_info_addr) else: return False if node != None: node.append_tcs_list(tcs_addr) string = read_from_memory(tcs_addr + 8, 4) if string == None: return False flag = struct.unpack('I', string)[0] flag |= 1 gdb_cmd = "set *(unsigned int *)%#x = %#x" %(tcs_addr + 8, flag) gdb.execute(gdb_cmd, False, True) return False
def invoke(self, arg, from_tty): args = gdb.string_to_argv(arg) zero = 0 if len(args) < 1: print 'Usage: kgraph <object> [zeropoint]' return x = gdb.parse_and_eval(args[0]) if len(args) > 1: zero = int(gdb.parse_and_eval(args[1])) data = self.kk.crunch(x) (rms, maxi, mini) = self.kk.calcrms(data, zero) fig = plot.figure() ax = fig.add_subplot(111) ax.grid(True) label = "%s RMS=%f" % (args[0], rms) ax.plot(data, '.', label=label) ax.plot((maxi, mini), (data[maxi], data[mini]), "kD", label="max-min") plot.figtext(0.01,0.01, "RMS=%f max:%d, min:%d, start=%d" % (rms, max(data), min(data), zero)) print("rms: %f max:%d, min:%d" % (rms, max(data), min(data))) print("maxi/mini at ", maxi, mini) leg = ax.legend()#label, 'upper right', shadow=False) leg.get_frame().set_alpha(0.5) plot.show()
def to_string(self): type = self.val tdesc = get_type_description(type) if tdesc: get_port_in = gdb.parse_and_eval("sol_flow_node_type_get_port_in") get_port_out = gdb.parse_and_eval("sol_flow_node_type_get_port_out") p_type = type.address ports_in = self._ports_description_to_string(tdesc["ports_in"], lambda idx: get_port_in(p_type, idx)) ports_out = self._ports_description_to_string(tdesc["ports_out"], lambda idx: get_port_out(p_type, idx)) options = self._options_description_to_string(tdesc["options"]) return "%s=%s" \ "\n name=\"%s\"," \ "\n category=\"%s\"," \ "\n description=\"%s\"," \ "\n ports_in={%s}," \ "\n ports_out={%s}," \ "\n options={%s})" % ( tdesc["symbol"].string(), type.address, tdesc["name"].string(), tdesc["category"].string(), tdesc["description"].string(), ports_in, ports_out, options) return "(struct sol_flow_node_type)%s (no node type description)" % (type.address,)
def _print_ports(self, type, tdesc, member, filter): array = tdesc[member] if not array: return did = 0 i = 0 if member == "ports_in": get_port_type = gdb.parse_and_eval("sol_flow_node_type_get_port_in") else: get_port_type = gdb.parse_and_eval("sol_flow_node_type_get_port_out") while array[i]: port = array[i] if filter["type"] == "all" or \ (filter["type"] == "number" and filter["number"] == i) or \ (filter["type"] == "name" and filter["name"](port["name"].string())): if did == 0: gdb.write("%s:\n" % member) did += 1 gdb.write(" %d: %s (%s)\n description: %s\n" % ( i, port["name"].string(), port["data_type"].string(), port["description"].string(), )) port_type = get_port_type(type, i) if port_type["connect"]: gdb.write(" connect(): %s\n" % (port_type["connect"],)) if port_type["disconnect"]: gdb.write(" disconnect(): %s\n" % (port_type["disconnect"],)) if member == "ports_in" and port_type["process"]: gdb.write(" process(): %s\n" % (port_type["process"],)) gdb.write("\n") i += 1
def handle_basetype(self, tp_name, p): basetype_dict = {"type": tp_name} if tp_name in "bool int long": obj = gdb.parse_and_eval("*(PyIntObject *)(%s)" % p) basetype_dict["value"] = str(obj["ob_ival"]) elif tp_name == "float": obj = gdb.parse_and_eval("*(PyFloatObject *)(%s)" % p) basetype_dict["value"] = str(obj["ob_fval"]) elif tp_name == "str": obj = gdb.parse_and_eval("*(PyStringObject *)(%s)" % p) inferior = gdb.selected_inferior() ob_size = int(str(obj["ob_size"])) value = inferior.read_memory(int(str(obj["ob_sval"].address), 16), ob_size) basetype_dict["value"] = str(value) basetype_dict["length"] = ob_size elif tp_name == "bytearray": obj = gdb.parse_and_eval("*(PyByteArrayObject *)(%s)" % p) basetype.update({ "value": obj["ob_bytes"].string(), "ob_alloc": obj["ob_alloc"].string(), "ob_exports": obj["ob_exports"].string() }) elif tp_name == "complex": obj = gdb.parse_and_eval("*(PyComplexObject *)(%s)" % p) basetype_dict["real"] = str(obj["cval"]["real"]) basetype_dict["image"] = str(obj["cval"]["imag"]) return basetype_dict
def stop(self): # fff = gdb.execute('bt', to_string=True) # get the string length = int(gdb.parse_and_eval('$ecx')) length = socket.ntohl(length) print(length) registers = ["$edx"] # registers = ["$esp", "$ebp", "$esi", "$eax", "$ecx", "$edx", "$ebx", "$edi"] for register in registers: address = gdb.parse_and_eval(register) address = int(address) p = struct.pack(">i", address) u = struct.unpack("<I", p) address = u[0] print(address) try: data = gdb.inferiors()[0].read_memory(address, length) print(register, binascii.hexlify(data), length, address) except gdb.MemoryError: print("FFFFFFFFFFFFFFFFFF") except: # print("Register %s failed." % register) traceback.print_exc() return False # return False to continue the execution of the program return False
def GET_RTX_FORMAT(code): val_rtx_format = gdb.parse_and_eval('rtx_format') return val_rtx_format[code].string()
def invoke(self, arg, from_tty): ptr = int(arg, 0) owning_thread = None for t, start, size in seastar_memory_layout(): if ptr >= start and ptr < start + size: owning_thread = t break if not owning_thread: gdb.write("Not managed by seastar\n") return msg = "thread %d" % t.num owning_thread.switch() cpu_mem = gdb.parse_and_eval('\'seastar::memory::cpu_mem\'') page_size = int(gdb.parse_and_eval('\'seastar::memory::page_size\'')) offset = ptr - int(cpu_mem['memory']) page = cpu_mem['pages'][offset / page_size]; if page['free']: msg += ', page is free' gdb.write(msg + '\n') return pool = page['pool'] offset_in_span = int(page['offset_in_span']) * page_size + ptr % page_size first_page_in_span = cpu_mem['pages'][offset / page_size - page['offset_in_span']]; if pool: object_size = int(pool['_object_size']) msg += ', small (size <= %d)' % object_size offset_in_object = offset_in_span % object_size free_object_ptr = gdb.lookup_type('void').pointer().pointer() char_ptr = gdb.lookup_type('char').pointer() # pool's free list next_free = pool['_free'] free = False while next_free: if ptr >= next_free and ptr < next_free.reinterpret_cast(char_ptr) + object_size: free = True break next_free = next_free.reinterpret_cast(free_object_ptr).dereference() if not free: # span's free list next_free = first_page_in_span['freelist'] while next_free: if ptr >= next_free and ptr < next_free.reinterpret_cast(char_ptr) + object_size: free = True break next_free = next_free.reinterpret_cast(free_object_ptr).dereference() if free: msg += ', free' else: msg += ', live (0x%x +%d)' % (ptr - offset_in_object, offset_in_object) else: msg += ', large' # FIXME: handle debug-mode build segment_size = int(gdb.parse_and_eval('\'logalloc::segment\'::size')) index = gdb.parse_and_eval('(%d - \'logalloc::shard_segment_pool\'._segments_base) / \'logalloc::segment\'::size' % (ptr)) desc = gdb.parse_and_eval('\'logalloc::shard_segment_pool\'._segments._M_impl._M_start[%d]' % (index)) if desc['_lsa_managed']: msg += ', LSA-managed' gdb.write(msg + '\n')
def get_seastar_memory_start_and_size(): cpu_mem = gdb.parse_and_eval('\'seastar::memory::cpu_mem\'') page_size = int(gdb.parse_and_eval('\'seastar::memory::page_size\'')) total_mem = int(cpu_mem['nr_pages']) * page_size start = int(cpu_mem['memory']) return start, total_mem
def GET_RTX_NAME(code): val_rtx_name = gdb.parse_and_eval('rtx_name') return val_rtx_name[code].string()
def invoke(self, arg, from_tty): # Parse args, check number of args args = gdb.string_to_argv(arg) if len(args) >= 1 and args[0] == "/f": if len(args) == 1: print("Missing file argument") return filename = args[1] editor_mode = False base_arg = 2 else: editor = os.getenv("EDITOR", "") if editor == "": print("EDITOR environment variable not defined") return editor_mode = True base_arg = 0 if len(args) - base_arg > 2: print("Too many arguments") return # Set func if len(args) - base_arg >= 1: funcname = args[base_arg] printfuncname = "function %s" % funcname else: funcname = "cfun ? cfun->decl : current_function_decl" printfuncname = "current function" func = gdb.parse_and_eval(funcname) if func == 0: print("Could not find %s" % printfuncname) return func = "(tree)%u" % func # Set flags if len(args) - base_arg >= 2: flags = gdb.parse_and_eval(args[base_arg + 1]) else: flags = 0 # Get tempory file, if necessary if editor_mode: f = tempfile.NamedTemporaryFile(delete=False, suffix=".txt") filename = f.name f.close() # Open file fp = gdb.parse_and_eval("fopen (\"%s\", \"w\")" % filename) if fp == 0: print("Could not open file: %s" % filename) return fp = "(FILE *)%u" % fp # Dump function to file _ = gdb.parse_and_eval("dump_function_to_file (%s, %s, %u)" % (func, fp, flags)) # Close file ret = gdb.parse_and_eval("fclose (%s)" % fp) if ret != 0: print("Could not close file: %s" % filename) return # Open file in editor, if necessary if editor_mode: os.system("( %s \"%s\"; rm \"%s\" ) &" % (editor, filename, filename))
def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) typeobj = gdb.parse_and_eval(argv[0]).type print_type_tree(typeobj)
def stop(self): command = gdb.parse_and_eval("(const char*)$rdi").string() gdb.execute(command) return False
def parse_argv(args): return [gdb.parse_and_eval(arg) for arg in gdb.string_to_argv(args)]
def null_value(self): nullptr = gdb.parse_and_eval('(void *) 0') return nullptr.cast(self._val_type.pointer()).dereference()
#HXP CTF 2017 - dont_panic 100 pts #Writeup link : https://rce4fun.blogspot.com/2017/11/hxp-ctf-2017-dontpanic-reversing-100.html #Souhail Hammou import gdb CHAR_SUCCESS = 0x47B976 NOPE = 0x47BA23 gdb.execute("set pagination off") gdb.execute("b*0x47B976") #Success for a given character gdb.execute("b*0x47BA23") #Block displaying "Nope" charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-+*{}'" flag = list('A' * 42) #junk for i in range(0, len(flag)): for c in charset: flag[i] = c # the number of times we need to hit the # success bp for the previous correct characters success_hits = i gdb.execute("r " + '"' + "".join(flag) + '"') while success_hits > 0: gdb.execute('c') success_hits -= 1 #we break either on success or on fail rip = int(gdb.parse_and_eval("$rip")) if rip == CHAR_SUCCESS: break #right one. To the next character if rip == NOPE: #added for clarity continue print("".join(flag)) #flag : hxp{k3eP_C4lM_AnD_D0n't_P4n1c__G0_i5_S4F3}
def stop(self): enclave_addr = int(gdb.parse_and_eval("$rdi")) enclave = oe_debug_enclave_t(enclave_addr) unload_enclave_symbol(enclave.path, enclave.base_address) return False
def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) if len(argv) != 1: raise gdb.GdbError("lx-list-check takes one argument") list_check(gdb.parse_and_eval(argv[0]))
def stop(self): enclave_addr = int(gdb.parse_and_eval("$rdi")) enable_oeenclave_debug(enclave_addr) return False
def GET_RTX_LENGTH(code): val_rtx_length = gdb.parse_and_eval('rtx_length') return intptr(val_rtx_length[code])
report(isinstance(auxv, str), "Fetched auxv from inferior") report(auxv.find("sha1"), "Found test binary name in auxv") # # This runs as the script it sourced (via -x, via run-test.py) # try: inferior = gdb.selected_inferior() arch = inferior.architecture() print("ATTACHED: %s" % arch.name()) except (gdb.error, AttributeError): print("SKIPPING (not connected)", file=sys.stderr) exit(0) if gdb.parse_and_eval('$pc') == 0: print("SKIP: PC not set") exit(0) try: # These are not very useful in scripts gdb.execute("set pagination off") gdb.execute("set confirm off") # Run the actual tests run_test() except (gdb.error): print("GDB Exception: %s" % (sys.exc_info()[0])) failcount += 1 pass
def eval_on_val(val, eval_str): if val.type.code == gdb.TYPE_CODE_REF: val = val.referenced_value() address = val.address eval_str = "(*({}){}){}".format(address.type, address, eval_str) return gdb.parse_and_eval(eval_str)
def op_table(name): """Get the symbol `name' as an int8_t[].""" return gdb.parse_and_eval("&'" + name + "'").cast(T('int8_t').pointer())
def curproc(): return Proc(gdb.parse_and_eval("curproc"))
def si_addr(self): str(gdb.parse_and_eval("$_siginfo._sifields._sigfault.si_addr")) return gdb_uint( gdb.parse_and_eval("$_siginfo._sifields._sigfault.si_addr"))
def pc(self): return gdb_uint(gdb.parse_and_eval("$pc"))
def stack_pointer(self): return gdb_uint(gdb.parse_and_eval("$sp"))
def invoke(self, arg, from_tty): watch = gdb.lookup_global_symbol("mgb::imperative::debug::watch_value(mgb::imperative::ValueRef)").value() value = gdb.parse_and_eval(arg) watch(value) print("watching {}".format(str(value)))
def save_regs(self): result = {} for reg in self.jmpbuf_offsets.keys(): result[reg] = gdb.parse_and_eval('$%s' % reg).cast(self.ulong_type) return result
def migrator(self): static_migrators = gdb.parse_and_eval("&'::debug::static_migrators'") migrator = static_migrators['_M_impl']['_M_start'][self.value >> 1] return migrator
def has_reactor(): if gdb.parse_and_eval('\'seastar\'::local_engine'): return True return False
def sym_addr(sym): try: return gdb_uint(gdb.parse_and_eval(str(sym))) except gdb.error: return None
def find_db(shard): return gdb.parse_and_eval('::debug::db')['_instances']['_M_impl']['_M_start'][shard]['service']['_p']
def invoke(self, arg, from_tty): parser = argparse.ArgumentParser(description="scylla heapprof") parser.add_argument("-G", "--inverted", action="store_true", help="Compute caller-first profile instead of callee-first") parser.add_argument("-a", "--addresses", action="store_true", help="Show raw addresses before resolved symbol names") parser.add_argument("--no-symbols", action="store_true", help="Show only raw addresses") parser.add_argument("--flame", action="store_true", help="Write flamegraph data to heapprof.stacks instead of showing the profile") parser.add_argument("--min", action="store", type=int, default=0, help="Drop branches allocating less than given amount") try: args = parser.parse_args(arg.split()) except SystemExit: return root = ProfNode(None) cpu_mem = gdb.parse_and_eval('\'seastar::memory::cpu_mem\'') site = cpu_mem['alloc_site_list_head'] while site: size = int(site['size']) count = int(site['count']) if size: n = root n.size += size n.count += count addresses = list(map(int, std_vector(site['backtrace']))) addresses.pop(0) # drop memory::get_backtrace() if args.inverted: seq = reversed(addresses) else: seq = addresses for addr in seq: n = n.get_or_add(addr) n.size += size n.count += count site = site['next'] def resolver(addr): if args.no_symbols: return '0x%x' % addr if args.addresses: return '0x%x %s' % (addr, resolve(addr) or '') return resolve(addr) or ('0x%x' % addr) if args.flame: file_name = 'heapprof.stacks' with open(file_name, 'w') as out: trace = list() def print_node(n): if n.key: trace.append(n.key) trace.extend(n.tail) for c in n.children: print_node(c) if not n.has_children(): out.write("%s %d\n" % (';'.join(map(lambda x: '%s (#%d)' % (x, n.count), map(resolver, trace))), n.size)) if n.key: del trace[-1 - len(n.tail):] print_node(root) gdb.write('Wrote %s\n' % (file_name)) else: def node_formatter(n): if n.key is None: name = "All" else: name = resolver(n.key) return "%s (%d, #%d)\n%s" % (name, n.size, n.count, '\n'.join(map(resolver, n.tail))) def node_filter(n): return n.size >= args.min collapse_similar(root) print_tree(root, formatter=node_formatter, order_by=lambda n: -n.size, node_filter=node_filter, printer=gdb.write)
def cpus(): return int(gdb.parse_and_eval('::smp::count'))
def seastar_threads_on_current_shard(): return intrusive_list( gdb.parse_and_eval('\'seastar::thread_context::_all_threads\''))