def invoke(self, arg, from_tty): stacktrace_info_list = [] if ScriptUtils.current_arch == type_defs.INFERIOR_ARCH.ARCH_64: sp_register = "rsp" else: sp_register = "esp" stack_pointer_int = int( ScriptUtils.examine_expression("$" + sp_register).address, 16) result = gdb.execute("bt", from_tty, to_string=True) max_frame = common_regexes.max_frame_count.findall(result)[-1] # +1 because frame numbers start from 0 for item in range(int(max_frame) + 1): result = gdb.execute("info frame " + str(item), from_tty, to_string=True) frame_address = common_regexes.frame_address.search(result).group( 1) difference = hex(int(frame_address, 16) - stack_pointer_int) frame_address_with_difference = frame_address + "(" + sp_register + "+" + difference + ")" return_address = common_regexes.return_address.search(result) if return_address: return_address_with_info = ScriptUtils.examine_expression( return_address.group(1)).all else: return_address_with_info = "<unavailable>" stacktrace_info_list.append( [return_address_with_info, frame_address_with_difference]) send_to_pince(stacktrace_info_list)
def invoke(self, arg, from_tty): breakpoints = arg current_pc_int = int( SysUtils.extract_address(str(gdb.parse_and_eval("$pc"))), 16) try: disas_output = gdb.execute("disas $pc-30,$pc", to_string=True) # Just before the line "End of assembler dump" last_instruction = disas_output.splitlines()[-2] previous_pc_address = SysUtils.extract_address(last_instruction) except: previous_pc_address = hex(current_pc_int) global track_watchpoint_dict try: count = track_watchpoint_dict[breakpoints][current_pc_int][0] + 1 except KeyError: if breakpoints not in track_watchpoint_dict: track_watchpoint_dict[breakpoints] = OrderedDict() count = 1 register_info = ScriptUtils.get_general_registers() register_info.update(ScriptUtils.get_flag_registers()) register_info.update(ScriptUtils.get_segment_registers()) float_info = ScriptUtils.get_float_registers() disas_info = gdb.execute("disas " + previous_pc_address + ",+40", to_string=True).replace("=>", " ") track_watchpoint_dict[breakpoints][current_pc_int] = [ count, previous_pc_address, register_info, float_info, disas_info ] track_watchpoint_file = SysUtils.get_track_watchpoint_file( pid, breakpoints) pickle.dump(track_watchpoint_dict[breakpoints], open(track_watchpoint_file, "wb"))
def invoke(self, arg, from_tty): stack_info_list = [] if ScriptUtils.current_arch == type_defs.INFERIOR_ARCH.ARCH_64: chunk_size = 8 int_format = "Q" sp_register = "rsp" else: chunk_size = 4 int_format = "I" sp_register = "esp" sp_address = int( ScriptUtils.examine_expression("$" + sp_register).address, 16) with open(ScriptUtils.mem_file, "rb") as FILE: try: old_position = FILE.seek(sp_address) except (OSError, ValueError): send_to_pince(stack_info_list) return for index in range(int(4096 / chunk_size)): current_offset = chunk_size * index stack_indicator = hex(sp_address + current_offset ) + "(" + sp_register + "+" + hex( current_offset) + ")" try: FILE.seek(old_position) read = FILE.read(chunk_size) except (OSError, ValueError): print("Can't access the stack after address " + stack_indicator) break old_position = FILE.tell() int_addr = struct.unpack_from(int_format, read)[0] hex_repr = hex(int_addr) try: FILE.seek(int_addr) read_pointer = FILE.read(20) except (OSError, ValueError): pointer_data = "" else: symbol = ScriptUtils.examine_expression(hex_repr).symbol if not symbol: pointer_data = "(str)" + read_pointer.decode( "utf-8", "ignore") else: pointer_data = "(ptr)" + symbol stack_info_list.append( [stack_indicator, hex_repr, pointer_data]) send_to_pince(stack_info_list)
def invoke(self, arg, from_tty): searched_str, case_sensitive, enable_regex = eval(arg) if enable_regex: try: if case_sensitive: regex = re.compile(searched_str) else: regex = re.compile(searched_str, re.IGNORECASE) except Exception as e: print( "An exception occurred while trying to compile the given regex\n", str(e)) return str_dict = shelve.open(SysUtils.get_referenced_calls_file(pid), "r") returned_list = [] for index, item in enumerate(str_dict): symbol = ScriptUtils.examine_expression(item).all if not symbol: continue if enable_regex: if not regex.search(symbol): continue else: if case_sensitive: if symbol.find(searched_str) == -1: continue else: if symbol.lower().find(searched_str.lower()) == -1: continue returned_list.append((symbol, len(str_dict[item]))) str_dict.close() send_to_pince(returned_list)
def invoke(self, arg, from_tty): arg_list = arg.split(",") breakpoint_number = arg_list.pop() register_expressions = arg_list global track_breakpoint_dict if not breakpoint_number in track_breakpoint_dict: track_breakpoint_dict[breakpoint_number] = OrderedDict() for register_expression in register_expressions: if not register_expression: continue if not register_expression in track_breakpoint_dict[ breakpoint_number]: track_breakpoint_dict[breakpoint_number][ register_expression] = OrderedDict() try: address = ScriptUtils.examine_expression( register_expression).address except: address = None if address: if address not in track_breakpoint_dict[breakpoint_number][ register_expression]: track_breakpoint_dict[breakpoint_number][ register_expression][address] = 1 else: track_breakpoint_dict[breakpoint_number][ register_expression][address] += 1 track_breakpoint_file = SysUtils.get_track_breakpoint_file( pid, breakpoint_number) pickle.dump(track_breakpoint_dict[breakpoint_number], open(track_breakpoint_file, "wb"))
def invoke(self, arg, from_tty): data_read_list = [] contents_recv = receive_from_pince() # contents_recv format: [expression1, expression2, ...] for expression in contents_recv: result_tuple = ScriptUtils.examine_expression(expression) data_read_list.append(result_tuple) send_to_pince(data_read_list)
def invoke(self, arg, from_tty): return_address_list = [] result = gdb.execute("bt", from_tty, to_string=True) max_frame = common_regexes.max_frame_count.findall(result)[-1] # +1 because frame numbers start from 0 for item in range(int(max_frame) + 1): result = gdb.execute("info frame " + str(item), from_tty, to_string=True) return_address = common_regexes.return_address.search(result) if return_address: return_address_with_info = ScriptUtils.examine_expression( return_address.group(1)).all else: return_address_with_info = "<unavailable>" return_address_list.append(return_address_with_info) send_to_pince(return_address_list)
def invoke(self, arg, from_tty): (breakpoint, max_trace_count, stop_condition, step_mode, stop_after_trace, collect_general_registers, collect_flag_registers, collect_segment_registers, collect_float_registers) = eval(arg) gdb.execute("delete " + breakpoint) trace_status_file = SysUtils.get_trace_instructions_status_file( pid, breakpoint) # The reason we don't use a tree class is to make the tree json-compatible # tree format-->[node1, node2, node3, ...] # node-->[(line_info, register_dict), parent_index, child_index_list] tree = [] current_index = 0 # Avoid calling len() current_root_index = 0 root_index = 0 # Root always be an empty node, it's up to you to use or delete it tree.append([("", None), None, []]) for x in range(max_trace_count): try: output = pickle.load(open(trace_status_file, "rb")) if output[0] == type_defs.TRACE_STATUS.STATUS_CANCELED: break except: pass line_info = gdb.execute("x/i $pc", to_string=True).split(maxsplit=1)[1] collect_dict = OrderedDict() if collect_general_registers: collect_dict.update(ScriptUtils.get_general_registers()) if collect_flag_registers: collect_dict.update(ScriptUtils.get_flag_registers()) if collect_segment_registers: collect_dict.update(ScriptUtils.get_segment_registers()) if collect_float_registers: collect_dict.update(ScriptUtils.get_float_registers()) current_index += 1 tree.append([(line_info, collect_dict), current_root_index, []]) tree[current_root_index][2].append(current_index) # Add a child status_info = (type_defs.TRACE_STATUS.STATUS_TRACING, line_info + " (" + str(x + 1) + "/" + str(max_trace_count) + ")") pickle.dump(status_info, open(trace_status_file, "wb")) if common_regexes.trace_instructions_ret.search(line_info): if tree[current_root_index][1] is None: # If no parents exist current_index += 1 tree.append([("", None), None, [current_root_index]]) tree[current_root_index][ 1] = current_index # Set new parent current_root_index = current_index # current_node=current_node.parent root_index = current_root_index # set new root else: current_root_index = tree[current_root_index][ 1] # current_node=current_node.parent elif step_mode == type_defs.STEP_MODE.SINGLE_STEP: if common_regexes.trace_instructions_call.search(line_info): current_root_index = current_index if stop_condition: try: if str(gdb.parse_and_eval(stop_condition)) == "1": break except: pass if step_mode == type_defs.STEP_MODE.SINGLE_STEP: gdb.execute("stepi", to_string=True) elif step_mode == type_defs.STEP_MODE.STEP_OVER: gdb.execute("nexti", to_string=True) status_info = (type_defs.TRACE_STATUS.STATUS_PROCESSING, "Processing the collected data") pickle.dump(status_info, open(trace_status_file, "wb")) trace_instructions_file = SysUtils.get_trace_instructions_file( pid, breakpoint) json.dump((tree, root_index), open(trace_instructions_file, "w")) status_info = (type_defs.TRACE_STATUS.STATUS_FINISHED, "Tracing has been completed") pickle.dump(status_info, open(trace_status_file, "wb")) if not stop_after_trace: gdb.execute("c")
def invoke(self, arg, from_tty): send_to_pince(ScriptUtils.get_float_registers())
def invoke(self, arg, from_tty): registers = ScriptUtils.get_general_registers() registers.update(ScriptUtils.get_flag_registers()) registers.update(ScriptUtils.get_segment_registers()) send_to_pince(registers)
# Format of expression_info_dict: {value1:count1, value2:count2, ...} # Format of register_expression_dict: {expression1:expression_info_dict1, expression2:expression_info_dict2, ...} # Format: {breakpoint_number1:register_expression_dict1, breakpoint_number2:register_expression_dict2, ...} track_breakpoint_dict = {} def receive_from_pince(): return pickle.load(open(recv_file, "rb")) def send_to_pince(contents_send): pickle.dump(contents_send, open(send_file, "wb")) ScriptUtils.gdbinit() class IgnoreErrors(gdb.Command): def __init__(self): super(IgnoreErrors, self).__init__("ignore-errors", gdb.COMMAND_USER) def invoke(self, arg, from_tty): try: gdb.execute(arg, from_tty) except: pass class CLIOutput(gdb.Command): def __init__(self):