def invoke(self, arg, from_tty): searched_str, case_sensitive, enable_regex = eval(arg) if enable_regex: try: if case_sensitive: regex = re.compile(searched_str) else: regex = re.compile(searched_str, re.IGNORECASE) except Exception as e: print( "An exception occurred while trying to compile the given regex\n", str(e)) return str_dict = shelve.open(SysUtils.get_referenced_calls_file(pid), "r") returned_list = [] for index, item in enumerate(str_dict): symbol = ScriptUtils.examine_expression(item).all if not symbol: continue if enable_regex: if not regex.search(symbol): continue else: if case_sensitive: if symbol.find(searched_str) == -1: continue else: if symbol.lower().find(searched_str.lower()) == -1: continue returned_list.append((symbol, len(str_dict[item]))) str_dict.close() send_to_pince(returned_list)
def invoke(self, arg, from_tty): searched_str, case_sensitive, enable_regex = eval(arg) if enable_regex: try: if case_sensitive: regex = re.compile(searched_str) else: regex = re.compile(searched_str, re.IGNORECASE) except Exception as e: print("An exception occurred while trying to compile the given regex\n", str(e)) return str_dict = shelve.open(SysUtils.get_referenced_calls_file(pid), "r") returned_list = [] for index, item in enumerate(str_dict): symbol = ScriptUtils.examine_expression(item).all if not symbol: continue if enable_regex: if not regex.search(symbol): continue else: if case_sensitive: if symbol.find(searched_str) == -1: continue else: if symbol.lower().find(searched_str.lower()) == -1: continue returned_list.append((symbol, len(str_dict[item]))) str_dict.close() send_to_pince(returned_list)
def invoke(self, arg, from_tty): 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): 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()