def GetStrLitContents(ea): potential_len = ida_bytes.get_max_strlit_length(ea, ida_nalt.STRTYPE_C_16) if(potential_len > 0): # If we get a non zero length, this is likely our string return ida_bytes.get_strlit_contents(ea, potential_len, ida_nalt.STRTYPE_C_16) # If we didn't get a good length out of C_16, try 8 bit strings potential_len = ida_bytes.get_max_strlit_length(ea, ida_nalt.STRTYPE_C) if(potential_len > 0): return ida_bytes.get_strlit_contents(ea, potential_len, ida_nalt.STRTYPE_C) #print("Error! %lu not a string" % (ea)) return ""
def cstr(ea): try: return ida_bytes.get_strlit_contents(ea, -1, ida_nalt.STRTYPE_C).decode() except Exception as e: print('Unable to decode string at %s' % hex(ea)) raise e
def getProc_addr(idx, ctx): import ida_bytes obj = ctx.get_obj("fcnPtr") print "%x" % obj.addr name = ctx.get_obj("fcnName") name_str = ida_bytes.get_strlit_contents(name.addr, -1, -1) ida_name.set_name(obj.addr, name_str)
def getFormatString(addr): op_num = 1 # idc.get_operand_type Return value #define o_void 0 // No Operand ---------- #define o_reg 1 // General Register (al, ax, es, ds...) reg #define o_mem 2 // Direct Memory Reference (DATA) addr #define o_phrase 3 // Memory Ref [Base Reg + Index Reg] phrase #define o_displ 4 // Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr #define o_imm 5 // Immediate Value value #define o_far 6 // Immediate Far Address (CODE) addr #define o_near 7 // Immediate Near Address (CODE) addr #define o_idpspec0 8 // IDP specific type #define o_idpspec1 9 // IDP specific type #define o_idpspec2 10 // IDP specific type #define o_idpspec3 11 // IDP specific type #define o_idpspec4 12 // IDP specific type #define o_idpspec5 13 // IDP specific type # 如果第二个不是立即数则下一个 if (idc.get_operand_type(addr, op_num) != 5): op_num = op_num + 1 if idc.get_operand_type(addr, op_num) != 5: return "get fail" op_string = print_operand( addr, op_num).split(" ")[0].split("+")[0].split("-")[0].replace("(", "") string_addr = idc.get_name_ea_simple(op_string) if string_addr == BADADDR: return "get fail" string = str(get_strlit_contents(string_addr, -1, STRTYPE_TERMCHR)) return [string_addr, string]
def get_string(self, from_ea, string_idx): addr = self.idx_to_ea(from_ea, string_idx, Dex.DEXVAR_STRING_IDS) if addr == ida_idaapi.BADADDR: return None length = ida_bytes.get_max_strlit_length( addr, idc.STRTYPE_C, ida_bytes.ALOPT_IGNHEADS | ida_bytes.ALOPT_IGNPRINT) return ida_bytes.get_strlit_contents(addr, length, idc.STRTYPE_C)
def get_string(self, string_idx): addr = self.nn_strtab.altval(string_idx, Dex.STRTAB_TAB) if addr is 0: return None length = ida_bytes.get_max_strlit_length( addr, STRTYPE_C, ida_bytes.ALOPT_IGNHEADS | ida_bytes.ALOPT_IGNPRINT) return ida_bytes.get_strlit_contents(addr, length, STRTYPE_C)
def _toseq(self, as_unicode): strbytes = ida_bytes.get_strlit_contents(self.ea, self.length, self.strtype) if sys.version_info.major >= 3: return strbytes.decode("UTF-8", "replace") if as_unicode else strbytes else: return unicode(strbytes, "UTF-8", 'replace') if as_unicode else strbytes
def create_and_get_typec_string(ea): size = ida_bytes.get_max_strlit_length( ea, ida_nalt.STRTYPE_C, ida_bytes.ALOPT_IGNCLT | ida_bytes.ALOPT_IGNHEADS | ida_bytes.ALOPT_IGNPRINT) if size == 0: return "" ida_bytes.create_strlit(ea, size, ida_nalt.STRTYPE_C) string = str(ida_bytes.get_strlit_contents(ea, size, ida_nalt.STRTYPE_C), encoding="utf-8") return string
def get_delphi_string(self, pos=None): print("get_delphi_string: addr = 0x%08X" % (self.addr + (pos if pos else self.pos))) ida_bytes.del_items(self.addr + (pos if pos else self.pos), ida_bytes.DELIT_EXPAND, 1) s = ida_bytes.get_strlit_contents( self.addr + (pos if pos else self.pos), ida_idaapi.BADADDR, ida_nalt.STRTYPE_PASCAL) if pos is None: self.pos += (len(s) + 1) return s
def __init__(self, xref, addr): type_ = idc.get_str_type(addr) if type_ < 0 or type_ >= len(String.ASCSTR): raise StringParsingException() string = str(ida_bytes.get_strlit_contents(addr, 0xffff, type_)) self.xref = xref self.addr = addr self.type = type_ self.string = string
def on_BL(addr, reg): X0, X1, X3 = reg['X0'], reg['X1'], reg['X3'] if not (X0 and X1 and X3): return _log(5, 'Have call to {:#x}({:#x}, {:#x}, ?, {:#x})', addr, X0, X1, X3) # OSMetaClass::OSMetaClass(this, className, superclass, classSize) if not idc.get_segm_name(X1).endswith( "__TEXT.__cstring") or not idc.get_segm_name(X0): return found_metaclass(X0, ida_bytes.get_strlit_contents(X1), X3, reg['X2'] or None)
def parse_prelink_info(): """Find and parse the kernel __PRELINK_INFO dictionary.""" segments = _find_prelink_info_segments() for segment in segments: prelink_info_string = ida_bytes.get_strlit_contents( segment, idaapi.get_item_size(segment), idaapi.get_str_type(segment)) prelink_info = kplist.kplist_parse(prelink_info_string) if prelink_info: return prelink_info _log(0, 'Could not find __PRELINK_INFO') return None
def get_string(self, start_address, end_address) -> list: result = [] current_start = start_address while current_start < end_address: if ida_nalt.get_str_type(current_start) < 4294967295: result.append( ida_bytes.get_strlit_contents( current_start, -1, ida_nalt.get_str_type(current_start)).decode()) # https://github.com/idapython/src/blob/master/python/idautils.py#L202 current_start = ida_bytes.next_head(current_start, ida_ida.cvar.inf.max_ea) return result
def get_string(self, start_address, end_address) -> list: result = [] start = int(start_address, 16) end = int(end_address, 16) while start <= end: # https://github.com/idapython/src/blob/master/python/idautils.py#L202 next_start = ida_bytes.next_head(start, ida_ida.cvar.inf.max_ea) if ida_nalt.get_str_type(start) < 4294967295: result.append( ida_bytes.get_strlit_contents( start, -1, ida_nalt.get_str_type(start)).decode()) start = next_start return result
def activate(self, ctx): for idx in ctx.chooser_selection: if self.use_get_chooser_data: _, _, _, s = ida_kernwin.get_chooser_data( ctx.widget_title, idx) else: si = ida_strlist.string_info_t() if ida_strlist.get_strlist_item(si, idx): s = ida_bytes.get_strlit_contents(si.ea, si.length, si.type) print("Selected string (retrieved using %s) at index %d: \"%s\"" % ("get_chooser_data()" if self.use_get_chooser_data else "get_strlist_item()", idx, s)) return 0
def op_type_changed(self, ea, n): flags = ida_bytes.get_flags(ea) self.log("op_type_changed(ea=0x%08X, n=%d). Flags now: 0x%08X" % (ea, n, flags)) buf = ida_nalt.opinfo_t() opi = ida_bytes.get_opinfo(buf, ea, n, flags) if opi: if ida_bytes.is_struct(flags): self.log("New struct: 0x%08X (name=%s)" % ( opi.tid, ida_struct.get_struc_name(opi.tid))) elif ida_bytes.is_strlit(flags): encidx = ida_nalt.get_str_encoding_idx(opi.strtype) if encidx == ida_nalt.STRENC_DEFAULT: encidx = ida_nalt.get_default_encoding_idx(ida_nalt.get_strtype_bpu(opi.strtype)) encname = ida_nalt.get_encoding_name(encidx) strlen = ida_bytes.get_max_strlit_length( ea, opi.strtype, ida_bytes.ALOPT_IGNHEADS | ida_bytes.ALOPT_IGNCLT) raw = ida_bytes.get_strlit_contents(ea, strlen, opi.strtype) or b"" self.log("New strlit: 0x%08X, raw hex=%s (encoding=%s)" % ( opi.strtype, binascii.hexlify(raw), encname)) elif ida_bytes.is_off(flags, n): self.log("New offset: refinfo={target=0x%08X, base=0x%08X, tdelta=0x%08X, flags=0x%X}" % ( opi.ri.target, opi.ri.base, opi.ri.tdelta, opi.ri.flags)) elif ida_bytes.is_enum(flags, n): self.log("New enum: 0x%08X (enum=%s), serial=%d" % ( opi.ec.tid, ida_enum.get_enum_name(opi.ec.tid), opi.ec.serial)) pass elif ida_bytes.is_stroff(flags, n): parts = [] for i in range(opi.path.len): tid = opi.path.ids[i] parts.append("0x%08X (name=%s)" % (tid, ida_struct.get_struc_name(tid))) self.log("New stroff: path=[%s] (len=%d, delta=0x%08X)" % ( ", ".join(parts), opi.path.len, opi.path.delta)) elif ida_bytes.is_custom(flags) or ida_bytes.is_custfmt(flags, n): self.log("New custom data type") # unimplemented else: print("Cannot retrieve opinfo_t")
def display_argstr(f, idx): """execute function f and print results. arguments: f: function that is expected to return a list of citem_t/cexpr_t objects idx: index into the argument list of a cexpr_t """ try: display(f, fmt=lambda x:"%x: %s" % (x.ea, ida_bytes.get_strlit_contents(x.a[idx].obj_ea, -1, 0, ida_bytes.STRCONV_ESCAPE).decode("utf-8"))) except Exception as exc: print("<display_argstr> error:", exc) return
def rename16(beg, ptr, make_funcs=True): base = beg first_entry = ptr.ptr(base + ptr.size * 6 + 8) + base cnt = ptr.ptr(base + 8) funcname_start = base + 8 + ptr.size * 7 for i in range(cnt): struct_ptr = ptr.ptr(first_entry + i * ptr.size * 2 + 8) + first_entry # print(f"{struct_ptr:x}") func_addr = ptr.ptr(first_entry + i * ptr.size * 2) str_val = ida_bytes.get_dword(struct_ptr + 8) + funcname_start name = ida_bytes.get_strlit_contents(str_val, -1, -1) print(f"{func_addr:x} {name}") if make_funcs == True: ida_bytes.del_items(func_addr, 1, ida_bytes.DELIT_SIMPLE) ida_funcs.add_func(func_addr) # print(type(name)) name = Utils.relaxName(name.decode()) Utils.rename(func_addr, name)
def is_valid_lua_function_array_entry(ea): str_ea = ida_bytes.get_64bit(ea) func_name = ida_bytes.get_strlit_contents(str_ea, -1, 0) if func_name is None or len(func_name) == 0: return False func_ea = ida_bytes.get_64bit(ea+8) # If this points to somewhere other than the .text segment, it cant be valid if get_segment_name(func_ea) != '.text': return False f2 = find_func_containing(func_ea) # If no function is found, create one if f2 is None: ida_funcs.add_func(func_ea) print('Created function for Script_%s at 0x%08x' % (func_name, func_ea)) f2 = func_ea elif f2 != func_ea: return False return find_func_containing(func_ea) == func_ea
def main(): print('\n\n') game_init = find_game_init() framescript_register = find_framescript_register(game_init) register_calls = find_register_calls(framescript_register) for c in register_calls: func_array = find_lua_function_array(c-0x20, c) if not is_valid_lua_function_array(func_array): print('WARNING: Invalid function array at 0x%08x (xref: 0x%08x)' % (func_array, c)) continue curr_ea = func_array while is_valid_lua_function_array_entry(curr_ea): str_ea = ida_bytes.get_64bit(curr_ea) func_ea = ida_bytes.get_64bit(curr_ea+8) func_name = ida_bytes.get_strlit_contents(str_ea, -1, 0) new_name = 'Script_' + func_name if idc.get_func_name(func_ea) != new_name: idc.set_name(func_ea, new_name) print('%s -> 0x%08x' % (new_name, func_ea)) curr_ea += 16
def enum_string_refs_in_function(fva): ''' yield the string references in the given function. Args: fva (int): the starting address of a function Returns: sequence[tuple[int, int, str]]: tuples of metadata, including: - the address of the instruction referencing a string - the address of the string - the string ''' for ea in enum_function_addrs(fva): for ref in idautils.DataRefsFrom(ea): stype = ida_nalt.get_str_type(ref) if stype < 0 or stype > 7: continue CALC_MAX_LEN = -1 s = str(ida_bytes.get_strlit_contents(ref, CALC_MAX_LEN, stype)) yield ea, ref, s
def get_string_repr(obj, ctx): if obj.opname == "cast": obj = obj.x else: pass if obj.opname == "obj": if obj.type.dstr() == "char *": return repr(ida_bytes.get_strlit_contents(obj.obj_ea, 256, -1)) else: name = ida_name.get_name(obj.obj_ea).split("@@")[0] print name if name[0] == ".": name = name[1:] if "endl" in name: return "std::endl" return ida_name.demangle_name(name, 0) elif obj.opname == "ref": return "&" + get_string_repr(obj.x, ctx) elif obj.opname == "var": return ctx.get_var_name(obj.v.idx) # elif else: print obj.opname return ""
def get_string(self, from_ea, string_idx): addr = self.idx_to_ea(from_ea, string_idx, Dex.DEXVAR_STRING_IDS) if addr == ida_idaapi.BADADDR: return None length = ida_bytes.get_max_strlit_length(addr, idc.STRTYPE_C, ida_bytes.ALOPT_IGNHEADS|ida_bytes.ALOPT_IGNPRINT) return ida_bytes.get_strlit_contents(addr, length, idc.STRTYPE_C)
def activate(self, ctx): selection = idaapi.read_selection() if not selection[0]: return 0 start = selection[1] - 1 stop = selection[2] + 1 print('Parsing selection between %X -> %X' % (start, stop)) prefix = ida_kernwin.ask_str('', 0, 'Prefix') if prefix is not None: prefix = prefix.replace('/', '::') while True: name_address = ida_bytes.next_head(start, stop) if name_address == idaapi.BADADDR: break name_offset = ida_bytes.get_dword(name_address) name = ida_bytes.get_strlit_contents(name_offset, -1, 0) if prefix is not None: name = prefix + '::' + name signature_address = ida_bytes.next_head(name_address, stop) if signature_address == idaapi.BADADDR: break signature_offset = ida_bytes.get_dword(signature_address) signature = ida_bytes.get_strlit_contents(signature_offset, -1, 0) function_address = ida_bytes.next_head(signature_address, stop) if function_address == idaapi.BADADDR: break function_offset = ida_bytes.get_dword(function_address) if function_offset % 2 != 0: function_offset -= 1 try: c_signature = JNINativeMethodSignature(name, signature).c except JNINativeMethodError: break start = function_address parsed_decl = ida_typeinf.idc_parse_decl(None, c_signature, ida_typeinf.PT_SIL) if parsed_decl is None: return 0 ida_typeinf.apply_type(None, parsed_decl[1], parsed_decl[2], function_offset, 1) ida_name.set_name(function_offset, name, ida_name.SN_FORCE) return 1
def _toseq(self, as_unicode): strbytes = ida_bytes.get_strlit_contents(self.ea, self.length, self.strtype) return unicode(strbytes, "UTF-8", 'replace') if as_unicode else strbytes
def read_cstring(ea): len = ida_bytes.get_max_strlit_length(ea, ida_nalt.STRTYPE_C) return ida_bytes.get_strlit_contents(ea, len, ida_nalt.STRTYPE_C)
def get_str_literal(addr): type = ida_nalt.get_str_type(addr) length = ida_bytes.get_max_strlit_length(addr, type, ida_bytes.ALOPT_IGNHEADS) return ida_bytes.get_strlit_contents(addr, length, type).decode('ascii')
def get_string_type(self, addr): try: type_s = idc.get_str_type(addr) return str(ida_bytes.get_strlit_contents(addr, -1, type_s)) except TypeError: raise StringException()
def parse_borland_class_rtti(addr): class_name = ida_bytes.get_strlit_contents( ida_bytes.get_wide_dword(addr + vmtClassName), ida_idaapi.BADADDR, ida_nalt.STRTYPE_PASCAL) print("Class name: %s" % class_name.decode()) ft = FieldTable().parse(get_field_table_addr(addr))
def get_class_name(cls_addr): class_name = ida_bytes.get_strlit_contents( ida_bytes.get_wide_dword(cls_addr + vmtClassName), ida_idaapi.BADADDR, ida_nalt.STRTYPE_PASCAL) return class_name
def get_cstring(ea): res = ida_bytes.get_strlit_contents(ea, -1, ida_nalt.STRTYPE_C) or b'' seen_strings.add(res) return res