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) regex_ret = re.compile(r":\s+ret") # 0x7f71a4dc5ff8 <poll+72>: ret regex_call = re.compile( r":\s+call") # 0x7f71a4dc5fe4 <poll+52>: call 0x7f71a4de1100 contents_send = type_defs.TraceInstructionsTree() for x in range(max_trace_count): 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()) contents_send.add_child( type_defs.TraceInstructionsTree(line_info, collect_dict)) status_info = (type_defs.TRACE_STATUS.STATUS_TRACING, line_info + " (" + str(x + 1) + "/" + str(max_trace_count) + ")") trace_status_file = SysUtils.get_trace_instructions_status_file( pid, breakpoint) pickle.dump(status_info, open(trace_status_file, "wb")) if regex_ret.search(line_info): if contents_send.parent is None: new_parent = type_defs.TraceInstructionsTree() contents_send.set_parent(new_parent) new_parent.add_child(contents_send) contents_send = contents_send.parent elif step_mode == type_defs.STEP_MODE.SINGLE_STEP: if regex_call.search(line_info): contents_send = contents_send.children[-1] 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) trace_instructions_file = SysUtils.get_trace_instructions_file( pid, breakpoint) pickle.dump(contents_send.get_root(), open(trace_instructions_file, "wb")) status_info = (type_defs.TRACE_STATUS.STATUS_FINISHED, "Tracing has been completed") trace_status_file = SysUtils.get_trace_instructions_status_file( pid, breakpoint) pickle.dump(status_info, open(trace_status_file, "wb")) if not stop_after_trace: gdb.execute("c")
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): 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) regex_ret = re.compile(r":\s+ret") # 0x7f71a4dc5ff8 <poll+72>: ret regex_call = re.compile( r":\s+call") # 0x7f71a4dc5fe4 <poll+52>: call 0x7f71a4de1100 tree_root = last_node = current_node = [("", 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_node[2].append( ((line_info, collect_dict), current_node, [])) 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 regex_ret.search(line_info): if current_node == tree_root: tree_root = (("", None), [], [tree_root]) current_node = last_node elif step_mode == type_defs.STEP_MODE.SINGLE_STEP: if regex_call.search(line_info): last_node = current_node current_node = current_node[2][-1] 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) pickle.dump(tree_root, open(trace_instructions_file, "wb")) 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): (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")