Exemple #1
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()
 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()
 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):
     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()