Beispiel #1
0
    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"))
Beispiel #2
0
 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 = SysUtils.extract_address(
                 gdb.execute("p/x " + register_expression,
                             from_tty,
                             to_string=True))
         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):
        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"))
Beispiel #4
0
 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")
Beispiel #5
0
 def data(self, QModelIndex, int_role=None):
     if not QModelIndex.isValid():
         return QVariant()
     if int_role == Qt.BackgroundColorRole:
         address = self.current_address + QModelIndex.row() * self.column_count + QModelIndex.column()
         if SysUtils.modulo_address(address, GDB_Engine.inferior_arch) in self.breakpoint_list:
             return QVariant(QColor(Qt.red))
     elif int_role != Qt.DisplayRole:
         return QVariant()
     if self.data_array is None:
         return QVariant()
     return QVariant(
         SysUtils.aob_to_str(self.data_array[QModelIndex.row() * self.column_count + QModelIndex.column()]))
Beispiel #6
0
 def refresh(self, int_address, offset, data_array=None, breakpoint_info=None):
     int_address = SysUtils.modulo_address(int_address, GDB_Engine.inferior_arch)
     self.breakpoint_list.clear()
     if data_array is None:
         self.data_array = GDB_Engine.hex_dump(int_address, offset)
     else:
         self.data_array = data_array
     if breakpoint_info is None:
         breakpoint_info = GDB_Engine.get_breakpoint_info()
     for breakpoint in breakpoint_info:
         breakpoint_address = int(breakpoint.address, 16)
         for i in range(breakpoint.size):
             self.breakpoint_list.add(SysUtils.modulo_address(breakpoint_address + i, GDB_Engine.inferior_arch))
     self.current_address = int_address
     self.layoutChanged.emit()
 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)
Beispiel #8
0
def write_address(address, value_index, value):
    if not type(address) == int:
        try:
            address = int(address, 16)
        except:
            print(str(address) + " is not a valid address")
            return
    write_data = SysUtils.parse_string(value, value_index)
    if write_data is None:
        return
    encoding, option = type_defs.string_index_to_encoding_dict.get(
        value_index, (None, None))
    if encoding is None:
        if value_index is type_defs.VALUE_INDEX.INDEX_AOB:
            write_data = bytearray(write_data)
        else:
            data_type = type_defs.index_to_struct_pack_dict.get(
                value_index, -1)
            write_data = struct.pack(data_type, write_data)
    else:
        write_data = write_data.encode(encoding, option)
    FILE = open(mem_file, "rb+")
    try:
        FILE.seek(address)
        FILE.write(write_data)
        FILE.close()
    except (OSError, ValueError):
        print("Can't access the memory at address " + hex(address) +
              " or offset " + hex(address + len(write_data)))
Beispiel #9
0
def set_single_address(address, value_index, value):
    if not type(address) == int:
        try:
            address = int(address, 16)
        except:
            print(str(address) + " is not a valid address")
            return
    write_data = SysUtils.parse_string(value, value_index)
    if write_data is None:
        return
    encoding, option = type_defs.string_index_to_encoding_dict.get(
        value_index, (None, None))
    if encoding is None:
        if value_index is type_defs.VALUE_INDEX.INDEX_AOB:
            write_data = bytearray(write_data)
        else:
            data_type = type_defs.index_to_struct_pack_dict.get(
                value_index, -1)
            write_data = struct.pack(data_type, write_data)
    else:
        write_data = bytearray(write_data, encoding, option)
    FILE = open(mem_file, "rb+")

    # Check SetMultipleAddresses class in GDBCommandExtensions.py to see why we moved away the try/except block
    FILE.seek(address)
    FILE.write(write_data)
    FILE.close()
Beispiel #10
0
 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)
Beispiel #11
0
 def data(self, QModelIndex, int_role=None):
     if not QModelIndex.isValid():
         return QVariant()
     elif int_role != Qt.DisplayRole:
         return QVariant()
     if self.data_array is None:
         return QVariant()
     return QVariant(
         SysUtils.aob_to_ascii(
             self.data_array[QModelIndex.row() * self.column_count +
                             QModelIndex.column()]))
Beispiel #12
0
 def refresh(self,
             int_address,
             offset,
             data_array=None,
             breakpoint_info=None):
     int_address = SysUtils.modulo_address(int_address,
                                           GDB_Engine.inferior_arch)
     self.breakpoint_list.clear()
     if data_array is None:
         self.data_array = GDB_Engine.hex_dump(int_address, offset)
     else:
         self.data_array = data_array
     if breakpoint_info is None:
         breakpoint_info = GDB_Engine.get_breakpoint_info()
     for breakpoint in breakpoint_info:
         breakpoint_address = int(breakpoint.address, 16)
         for i in range(breakpoint.size):
             self.breakpoint_list.add(
                 SysUtils.modulo_address(breakpoint_address + i,
                                         GDB_Engine.inferior_arch))
     self.current_address = int_address
     self.layoutChanged.emit()
 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"
         stack_register = "rsp"
         result = gdb.execute("p/x $rsp", from_tty, to_string=True)
     else:
         chunk_size = 4
         int_format = "I"
         stack_register = "esp"
         result = gdb.execute("p/x $esp", from_tty, to_string=True)
     stack_address = int(SysUtils.extract_address(result),
                         16)  # $6 = 0x7f0bc0b6bb40
     with open(ScriptUtils.mem_file, "rb") as FILE:
         try:
             old_position = FILE.seek(stack_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(stack_address + current_offset
                                   ) + "(" + stack_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:
                 result = gdb.execute("x/b " + hex_repr, to_string=True)
                 result = common_regexes.plain_symbol.search(result)
                 if not result:
                     pointer_data = "(str)" + read_pointer.decode(
                         "utf-8", "ignore")
                 else:
                     pointer_data = "(ptr)" + result.group(0)
             stack_info_list.append(
                 [stack_indicator, hex_repr, pointer_data])
     send_to_pince(stack_info_list)
Beispiel #14
0
 def data(self, QModelIndex, int_role=None):
     if not QModelIndex.isValid():
         return QVariant()
     if int_role == Qt.BackgroundColorRole:
         if QModelIndex.row() * self.column_count + QModelIndex.column(
         ) in self.breakpoint_list:
             return QVariant(QColor(Qt.red))
     elif int_role != Qt.DisplayRole:
         return QVariant()
     if self.data_array is None:
         return QVariant()
     return QVariant(
         SysUtils.aob_to_str(
             self.data_array[QModelIndex.row() * self.column_count +
                             QModelIndex.column()]))
Beispiel #15
0
def set_single_address(address, value_index, value):
    try:
        address = int(address, 16)
    except:
        print(str(address) + " is not a valid address")
        return
    write_data = SysUtils.parse_string(value, value_index)
    if write_data is None:
        return
    if value_index is INDEX_STRING:
        write_data = bytearray(write_data, "utf-8", "replace")
    elif value_index is INDEX_AOB:
        write_data = bytearray(write_data)
    else:
        data_type = index_to_struct_pack_dict.get(value_index, -1)
        write_data = struct.pack(data_type, write_data)
    FILE = open(mem_file, "rb+")

    # Check SetMultipleAddresses class in GDBCommandExtensions.py to see why we moved away the try/except block
    FILE.seek(address)
    FILE.write(write_data)
    FILE.close()
 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"))
Beispiel #17
0
    def invoke(self, arg, from_tty):
        stacktrace_info_list = []
        if ScriptUtils.current_arch == type_defs.INFERIOR_ARCH.ARCH_64:
            sp_register = "rsp"
            result = gdb.execute("p/x $rsp", from_tty, to_string=True)
        else:
            sp_register = "esp"
            result = gdb.execute("p/x $esp", from_tty, to_string=True)
        stack_pointer_int = int(SysUtils.extract_address(result),
                                16)  # $6 = 0x7f0bc0b6bb40
        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:
                try:
                    result = gdb.execute("x/b " + return_address.group(1),
                                         from_tty,
                                         to_string=True)
                except:
                    break
                return_address_with_info = common_regexes.return_address_with_info.search(
                    result).group(1)
            else:
                return_address_with_info = "<unavailable>"
            stacktrace_info_list.append(
                [return_address_with_info, frame_address_with_difference])
        send_to_pince(stacktrace_info_list)
Beispiel #18
0
 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")
Beispiel #19
0
 def invoke(self, arg, from_tty):
     if ScriptUtils.current_arch == type_defs.INFERIOR_ARCH.ARCH_64:
         disas_option = distorm3.Decode64Bits
     else:
         disas_option = distorm3.Decode32Bits
     referenced_strings_dict = shelve.open(
         SysUtils.get_referenced_strings_file(pid), writeback=True)
     referenced_jumps_dict = shelve.open(
         SysUtils.get_referenced_jumps_file(pid), writeback=True)
     referenced_calls_dict = shelve.open(
         SysUtils.get_referenced_calls_file(pid), writeback=True)
     region_list, discard_invalid_strings = receive_from_pince()
     dissect_code_status_file = SysUtils.get_dissect_code_status_file(pid)
     region_count = len(region_list)
     self.memory = open(ScriptUtils.mem_file, "rb")
     buffer = 0x130000  # Has the best record of 13.6 sec. Tested on 0ad with Intel i7-4702MQ CPU and 8GB RAM
     ref_str_count = len(referenced_strings_dict)
     ref_jmp_count = len(referenced_jumps_dict)
     ref_call_count = len(referenced_calls_dict)
     for region_index, region in enumerate(region_list):
         region_info = region.addr, "Region " + str(
             region_index + 1) + " of " + str(region_count)
         start_addr, end_addr = region.addr.split("-")
         start_addr = int(
             start_addr, 16
         )  # Becomes address of the last disassembled instruction later on
         end_addr = int(end_addr, 16)
         region_finished = False
         while not region_finished:
             remaining_space = end_addr - start_addr
             if remaining_space < buffer:
                 offset = remaining_space
                 region_finished = True
             else:
                 offset = buffer
             status_info = region_info + (
                 hex(start_addr) + "-" + hex(start_addr + offset),
                 ref_str_count, ref_jmp_count, ref_call_count)
             pickle.dump(status_info, open(dissect_code_status_file, "wb"))
             try:
                 self.memory.seek(start_addr)
             except (OSError, ValueError):
                 break
             code = self.memory.read(offset)
             disas_data = distorm3.Decode(start_addr, code, disas_option)
             if not region_finished:
                 last_disas_addr = disas_data[-4][0]
                 for index in range(4):
                     del disas_data[
                         -1]  # Get rid of last 4 instructions to ensure correct bytecode translation
             else:
                 last_disas_addr = 0
             for (instruction_offset, size, instruction,
                  hexdump) in disas_data:
                 if isinstance(instruction, bytes):
                     instruction = instruction.decode()
                 if instruction.startswith("J") or instruction.startswith(
                         "LOOP"):
                     found = common_regexes.dissect_code_valid_address.search(
                         instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             instruction_only = common_regexes.alphanumerics.search(
                                 instruction).group(0).casefold()
                             try:
                                 referenced_jumps_dict[
                                     referenced_address_str][
                                         instruction_offset] = instruction_only
                             except KeyError:
                                 referenced_jumps_dict[
                                     referenced_address_str] = {}
                                 referenced_jumps_dict[
                                     referenced_address_str][
                                         instruction_offset] = instruction_only
                                 ref_jmp_count += 1
                 elif instruction.startswith("CALL"):
                     found = common_regexes.dissect_code_valid_address.search(
                         instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             try:
                                 referenced_calls_dict[
                                     referenced_address_str].add(
                                         instruction_offset)
                             except KeyError:
                                 referenced_calls_dict[
                                     referenced_address_str] = set()
                                 referenced_calls_dict[
                                     referenced_address_str].add(
                                         instruction_offset)
                                 ref_call_count += 1
                 else:
                     found = common_regexes.dissect_code_valid_address.search(
                         instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int,
                                                 discard_invalid_strings):
                             try:
                                 referenced_strings_dict[
                                     referenced_address_str].add(
                                         instruction_offset)
                             except KeyError:
                                 referenced_strings_dict[
                                     referenced_address_str] = set()
                                 referenced_strings_dict[
                                     referenced_address_str].add(
                                         instruction_offset)
                                 ref_str_count += 1
             start_addr = last_disas_addr
     self.memory.close()
Beispiel #20
0
    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")
Beispiel #21
0
 def test_split_symbol(self):
     self.assertListEqual(SysUtils.split_symbol("func(param)@plt"), ["func", "func(param)", "func(param)@plt"])
Beispiel #22
0
import gdb, pickle, json, sys, re, struct, io, ctypes, os, shelve, distorm3
from collections import OrderedDict

# This is some retarded hack
gdbvalue = gdb.parse_and_eval("$PINCE_PATH")
PINCE_PATH = gdbvalue.string()
sys.path.append(
    PINCE_PATH
)  # Adds the PINCE directory to PYTHONPATH to import libraries from PINCE

from libPINCE.gdb_python_scripts import ScriptUtils
from libPINCE import SysUtils, type_defs, common_regexes

inferior = gdb.selected_inferior()
pid = inferior.pid
recv_file = SysUtils.get_IPC_from_PINCE_file(pid)
send_file = SysUtils.get_IPC_to_PINCE_file(pid)

lib = None

# Format of info_list: [count, previous_pc_address, register_info, float_info, disas_info]
# Format of watchpoint_dict: {address1:info_list1, address2:info_list2, ...}
# Format of watchpoint_numbers: str([1,2,3,4,..])
# Format: {watchpoint_numbers1:watchpoint_dict1, watchpoint_numbers2:track_watchpoint_dict2, ...}
track_watchpoint_dict = {}

# 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 = {}
Beispiel #23
0
 def get_selected_address(self):
     ci = self.currentIndex()
     current_address = self.model().current_address + ci.row() * self.model().columnCount() + ci.column()
     return SysUtils.modulo_address(current_address, GDB_Engine.inferior_arch)
Beispiel #24
0
desc = 'Runs all unit tests by creating or attaching to a process'
ex = 'Example of Usage:' \
     + '\n\tsudo python3 run_tests.py -a kmines' \
     + '\n\tsudo python3 run_tests.py -c /usr/games/kmines -o="-v"'

parser = argparse.ArgumentParser(description=desc, epilog=ex, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("-a", metavar="process_name", type=str, help="Attaches to the process with given name")
parser.add_argument("-c", metavar="file_path", type=str, help="Creates a new process with given path")
parser.add_argument("-o", metavar="options", type=str, default="",
                    help="Arguments that'll be passed to the inferior, only can be used with -c, optional")
parser.add_argument("-l", metavar="ld_preload_path", type=str, default="",
                    help="Path of the preloaded .so file, only can be used with -c, optional")

args = parser.parse_args()
if args.a:
    process_list = SysUtils.search_in_processes_by_name(args.a)
    if not process_list:
        parser.error("There's no process with the name " + args.a)
    if len(process_list) > 1:
        for p in process_list:
            try:
                name = p.name()
            except psutil.NoSuchProcess:
                print("Process with pid", p.pid, "does not exist anymore")
                continue
            print(name)
        print("There are more than one process with the name " + args.a)
        exit()
    pid = process_list[0].pid
    if not GDB_Engine.can_attach(pid):
        parser.error("Failed to attach to the process with pid " + str(pid))
Beispiel #25
0
 def get_selected_address(self):
     ci = self.currentIndex()
     current_address = self.model().current_address + ci.row() * self.model(
     ).columnCount() + ci.column()
     return SysUtils.modulo_address(current_address,
                                    GDB_Engine.inferior_arch)
Beispiel #26
0
 def test_split_symbol(self):
     self.assertListEqual(SysUtils.split_symbol("func(param)@plt"),
                          ["func", "func(param)", "func(param)@plt"])
Beispiel #27
0
from collections import OrderedDict

# This is some retarded hack
gdbvalue = gdb.parse_and_eval("$PINCE_PATH")
PINCE_PATH = gdbvalue.string()
sys.path.append(
    PINCE_PATH
)  # Adds the PINCE directory to PYTHONPATH to import libraries from PINCE

from libPINCE.gdb_python_scripts import ScriptUtils
from libPINCE import SysUtils
from libPINCE import type_defs

inferior = gdb.selected_inferior()
pid = inferior.pid
recv_file = SysUtils.get_ipc_from_PINCE_file(pid)
send_file = SysUtils.get_ipc_to_PINCE_file(pid)

lib = None

# Format of info_list: [count, previous_pc_address, register_info, float_info, disas_info]
# Format of watchpoint_dict: {address1:info_list1, address2:info_list2, ...}
# Format of watchpoint_numbers: str([1,2,3,4,..])
# Format: {watchpoint_numbers1:watchpoint_dict1, watchpoint_numbers2:track_watchpoint_dict2, ...}
track_watchpoint_dict = {}

# 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 invoke(self, arg, from_tty):
     if ScriptUtils.current_arch == type_defs.INFERIOR_ARCH.ARCH_64:
         disas_option = distorm3.Decode64Bits
     else:
         disas_option = distorm3.Decode32Bits
     referenced_strings_dict = shelve.open(SysUtils.get_referenced_strings_file(pid), writeback=True)
     referenced_jumps_dict = shelve.open(SysUtils.get_referenced_jumps_file(pid), writeback=True)
     referenced_calls_dict = shelve.open(SysUtils.get_referenced_calls_file(pid), writeback=True)
     region_list, discard_invalid_strings = receive_from_pince()
     dissect_code_status_file = SysUtils.get_dissect_code_status_file(pid)
     region_count = len(region_list)
     self.memory = open(ScriptUtils.mem_file, "rb")
     buffer = 0x130000  # Has the best record of 13.6 sec. Tested on 0ad with Intel i7-4702MQ CPU and 8GB RAM
     ref_str_count = len(referenced_strings_dict)
     ref_jmp_count = len(referenced_jumps_dict)
     ref_call_count = len(referenced_calls_dict)
     for region_index, region in enumerate(region_list):
         region_info = region.addr, "Region " + str(region_index + 1) + " of " + str(region_count)
         start_addr, end_addr = region.addr.split("-")
         start_addr = int(start_addr, 16)  # Becomes address of the last disassembled instruction later on
         end_addr = int(end_addr, 16)
         region_finished = False
         while not region_finished:
             remaining_space = end_addr - start_addr
             if remaining_space < buffer:
                 offset = remaining_space
                 region_finished = True
             else:
                 offset = buffer
             status_info = region_info + (hex(start_addr) + "-" + hex(start_addr + offset),
                                          ref_str_count, ref_jmp_count, ref_call_count)
             pickle.dump(status_info, open(dissect_code_status_file, "wb"))
             try:
                 self.memory.seek(start_addr)
             except (OSError, ValueError):
                 break
             code = self.memory.read(offset)
             disas_data = distorm3.Decode(start_addr, code, disas_option)
             if not region_finished:
                 last_disas_addr = disas_data[-4][0]
                 for index in range(4):
                     del disas_data[-1]  # Get rid of last 4 instructions to ensure correct bytecode translation
             else:
                 last_disas_addr = 0
             for (instruction_offset, size, instruction, hexdump) in disas_data:
                 if isinstance(instruction, bytes):
                     instruction = instruction.decode()
                 if instruction.startswith("J") or instruction.startswith("LOOP"):
                     found = common_regexes.dissect_code_valid_address.search(instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(found.group(0)).group(0)
                         referenced_address_int = int(referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             instruction_only = common_regexes.alphanumerics.search(instruction).group(0).casefold()
                             try:
                                 referenced_jumps_dict[referenced_address_str][instruction_offset] = instruction_only
                             except KeyError:
                                 referenced_jumps_dict[referenced_address_str] = {}
                                 referenced_jumps_dict[referenced_address_str][instruction_offset] = instruction_only
                                 ref_jmp_count += 1
                 elif instruction.startswith("CALL"):
                     found = common_regexes.dissect_code_valid_address.search(instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(found.group(0)).group(0)
                         referenced_address_int = int(referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             try:
                                 referenced_calls_dict[referenced_address_str].add(instruction_offset)
                             except KeyError:
                                 referenced_calls_dict[referenced_address_str] = set()
                                 referenced_calls_dict[referenced_address_str].add(instruction_offset)
                                 ref_call_count += 1
                 else:
                     found = common_regexes.dissect_code_valid_address.search(instruction)
                     if found:
                         referenced_address_str = common_regexes.hex_number.search(found.group(0)).group(0)
                         referenced_address_int = int(referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int, discard_invalid_strings):
                             try:
                                 referenced_strings_dict[referenced_address_str].add(instruction_offset)
                             except KeyError:
                                 referenced_strings_dict[referenced_address_str] = set()
                                 referenced_strings_dict[referenced_address_str].add(instruction_offset)
                                 ref_str_count += 1
             start_addr = last_disas_addr
     self.memory.close()
    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")
Beispiel #30
0
 def invoke(self, arg, from_tty):
     global referenced_jumps_dict
     global referenced_calls_dict
     global referenced_strings_dict
     regex_valid_address = re.compile(
         r"(\s+|\[|,)0x[0-9a-fA-F]+(\s+|\]|,|$)")
     regex_hex = re.compile(r"0x[0-9a-fA-F]+")
     regex_instruction = re.compile(r"\w+")
     region_list = receive_from_pince()
     dissect_code_status_file = SysUtils.get_dissect_code_status_file(pid)
     region_count = len(region_list)
     self.memory = open(ScriptUtils.mem_file, "rb")
     for region_index, region in enumerate(region_list):
         status_info = region.addr, "Region " + str(region_index + 1) + " of " + str(region_count), \
                       len(referenced_strings_dict), len(referenced_jumps_dict), len(referenced_calls_dict)
         pickle.dump(status_info, open(dissect_code_status_file, "wb"))
         start_addr, end_addr = region.addr.split("-")
         start_addr = "0x" + start_addr
         end_addr = "0x" + end_addr
         disas_data = gdb.execute("disas " + start_addr + "," + end_addr,
                                  to_string=True)
         lines = disas_data.splitlines()
         del lines[0], lines[
             -1]  # Get rid of "End of assembler dump" and "Dump of assembler code..." texts
         for line in lines:
             referrer_address, opcode = line.split(":", maxsplit=1)
             opcode = opcode.strip()
             opcode = ScriptUtils.remove_disas_comment(opcode)
             if opcode.startswith("j") or opcode.startswith("loop"):
                 found = regex_valid_address.search(opcode)
                 if found:
                     referenced_int_address = int(
                         regex_hex.search(found.group(0)).group(0), 16)
                     if self.is_memory_valid(referenced_int_address):
                         instruction = regex_instruction.search(
                             opcode).group(0)
                         referrer_int_address = int(
                             regex_hex.search(referrer_address).group(0),
                             16)
                         if not referenced_int_address in referenced_jumps_dict:
                             referenced_jumps_dict[
                                 referenced_int_address] = {}
                         referenced_jumps_dict[referenced_int_address][
                             referrer_int_address] = instruction
             if opcode.startswith("call"):
                 found = regex_valid_address.search(opcode)
                 if found:
                     referenced_int_address = int(
                         regex_hex.search(found.group(0)).group(0), 16)
                     if self.is_memory_valid(referenced_int_address):
                         referrer_int_address = int(
                             regex_hex.search(referrer_address).group(0),
                             16)
                         if not referenced_int_address in referenced_calls_dict:
                             referenced_calls_dict[
                                 referenced_int_address] = set()
                         referenced_calls_dict[referenced_int_address].add(
                             referrer_int_address)
             else:
                 found = regex_valid_address.search(opcode)
                 if found:
                     referenced_int_address = int(
                         regex_hex.search(found.group(0)).group(0), 16)
                     if self.is_memory_valid(referenced_int_address):
                         referrer_int_address = int(
                             regex_hex.search(referrer_address).group(0),
                             16)
                         if not referenced_int_address in referenced_strings_dict:
                             referenced_strings_dict[
                                 referenced_int_address] = set()
                         referenced_strings_dict[
                             referenced_int_address].add(
                                 referrer_int_address)
     self.memory.close()
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import gdb, pickle, json, sys, re, struct, io, ctypes, os, shelve, distorm3
from collections import OrderedDict

# This is some retarded hack
gdbvalue = gdb.parse_and_eval("$PINCE_PATH")
PINCE_PATH = gdbvalue.string()
sys.path.append(PINCE_PATH)  # Adds the PINCE directory to PYTHONPATH to import libraries from PINCE

from libPINCE.gdb_python_scripts import ScriptUtils
from libPINCE import SysUtils, type_defs, common_regexes

inferior = gdb.selected_inferior()
pid = inferior.pid
recv_file = SysUtils.get_IPC_from_PINCE_file(pid)
send_file = SysUtils.get_IPC_to_PINCE_file(pid)

lib = None

# Format of info_list: [count, previous_pc_address, register_info, float_info, disas_info]
# Format of watchpoint_dict: {address1:info_list1, address2:info_list2, ...}
# Format of watchpoint_numbers: str([1,2,3,4,..])
# Format: {watchpoint_numbers1:watchpoint_dict1, watchpoint_numbers2:track_watchpoint_dict2, ...}
track_watchpoint_dict = {}

# 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 = {}
Beispiel #32
0
    metavar="options",
    type=str,
    default="",
    help=
    "Arguments that'll be passed to the inferior, only can be used with -c, optional"
)
parser.add_argument(
    "-l",
    metavar="ld_preload_path",
    type=str,
    default="",
    help="Path of the preloaded .so file, only can be used with -c, optional")

args = parser.parse_args()
if args.a:
    process_list = SysUtils.search_in_processes_by_name(args.a)
    if not process_list:
        parser.error("There's no process with the name " + args.a)
    if len(process_list) > 1:
        for item in process_list:
            print(item.name())
        print("There are more than one process with the name " + args.a)
        exit()
    pid = process_list[0].pid
    if not GDB_Engine.can_attach(pid):
        parser.error("Failed to attach to the process with pid " + str(pid))
    GDB_Engine.attach(pid)
elif args.c:
    if not GDB_Engine.create_process(args.c, args.o, args.l):
        parser.error("Couldn't create the process with current args")
else:
Beispiel #33
0
 def invoke(self, arg, from_tty):
     referenced_strings_dict = shelve.open(
         SysUtils.get_referenced_strings_file(pid), writeback=True)
     referenced_jumps_dict = shelve.open(
         SysUtils.get_referenced_jumps_file(pid), writeback=True)
     referenced_calls_dict = shelve.open(
         SysUtils.get_referenced_calls_file(pid), writeback=True)
     regex_valid_address = re.compile(
         r"(\s+|\[|,)0x[0-9a-fA-F]+(\s+|\]|,|$)")
     regex_hex = re.compile(r"0x[0-9a-fA-F]+")
     regex_instruction = re.compile(r"\w+")
     region_list = receive_from_pince()
     dissect_code_status_file = SysUtils.get_dissect_code_status_file(pid)
     region_count = len(region_list)
     self.memory = open(ScriptUtils.mem_file, "rb")
     buffer = 0x10000
     for region_index, region in enumerate(region_list):
         region_info = region.addr, "Region " + str(
             region_index + 1) + " of " + str(region_count)
         start_addr, end_addr = region.addr.split("-")
         start_addr = int(start_addr, 16)
         end_addr = int(end_addr, 16)
         remaining_space = end_addr - start_addr
         while remaining_space > 0:
             if remaining_space < buffer:
                 offset = start_addr + remaining_space
             else:
                 offset = start_addr + buffer
             start_addr_str = hex(start_addr)
             offset_str = hex(offset)
             status_info = region_info + (start_addr_str + "-" + offset_str,
                                          len(referenced_strings_dict),
                                          len(referenced_jumps_dict),
                                          len(referenced_calls_dict))
             pickle.dump(status_info, open(dissect_code_status_file, "wb"))
             disas_data = gdb.execute("disas " + start_addr_str + "," +
                                      offset_str,
                                      to_string=True)
             start_addr = offset
             remaining_space -= buffer
             lines = disas_data.splitlines()
             del lines[0], lines[
                 -1]  # Get rid of "End of assembler dump" and "Dump of assembler code..." texts
             for line in lines:
                 referrer_address, opcode = line.split(":", maxsplit=1)
                 opcode = opcode.strip()
                 opcode = ScriptUtils.remove_disas_comment(opcode)
                 if opcode.startswith("j") or opcode.startswith("loop"):
                     found = regex_valid_address.search(opcode)
                     if found:
                         referenced_address_str = regex_hex.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             instruction = regex_instruction.search(
                                 opcode).group(0)
                             referrer_address = regex_hex.search(
                                 referrer_address).group(0)
                             try:
                                 referenced_jumps_dict[
                                     referenced_address_str][
                                         referrer_address] = instruction
                             except KeyError:
                                 referenced_jumps_dict[
                                     referenced_address_str] = {}
                 if opcode.startswith("call"):
                     found = regex_valid_address.search(opcode)
                     if found:
                         referenced_address_str = regex_hex.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             referrer_address = regex_hex.search(
                                 referrer_address).group(0)
                             try:
                                 referenced_calls_dict[
                                     referenced_address_str].add(
                                         referrer_address)
                             except KeyError:
                                 referenced_calls_dict[
                                     referenced_address_str] = set()
                 else:
                     found = regex_valid_address.search(opcode)
                     if found:
                         referenced_address_str = regex_hex.search(
                             found.group(0)).group(0)
                         referenced_address_int = int(
                             referenced_address_str, 16)
                         if self.is_memory_valid(referenced_address_int):
                             referrer_address = regex_hex.search(
                                 referrer_address).group(0)
                             try:
                                 referenced_strings_dict[
                                     referenced_address_str].add(
                                         referrer_address)
                             except KeyError:
                                 referenced_strings_dict[
                                     referenced_address_str] = set()
     self.memory.close()