def parse(self): pkgpath_off = read_mem(self.uncomm_type_addr, forced_addr_sz=4) & 0xFFFFFFFF if pkgpath_off != 0: self.pkgpath_addr = self.types_addr + pkgpath_off pkg_path_obj = Name(self.pkgpath_addr, self.type_parser.moddata) pkg_path_obj.parse(False) self.pkg_path = pkg_path_obj.name_str self.meth_cnt = read_mem(self.uncomm_type_addr + 4, forced_addr_sz=2) & 0xFFFF self.xmeth_cnt = read_mem(self.uncomm_type_addr + 6, forced_addr_sz=2) & 0xFFFF self.meth_off = read_mem(self.uncomm_type_addr + 8, forced_addr_sz=4) & 0xFFFFFFFF self.unused = read_mem(self.uncomm_type_addr + 12, forced_addr_sz=4) & 0xFFFFFFFF # parse methods methods_start_addr = (self.uncomm_type_addr + self.meth_off) & 0xFFFFFFFF for i in xrange(self.meth_cnt): #meth_addr = self.uncomm_type_addr + i * self.size meth = MethodType(methods_start_addr, self.type_parser) meth.parse() self.methods.append(meth) methods_start_addr += meth.size idc.MakeComm(self.uncomm_type_addr, "pkg path%s" % \ (("(@ 0x%x): %s" % (self.pkgpath_addr, self.pkg_path)) if (pkgpath_off>0 and len(self.pkg_path)>0) else "")) idc.MakeComm(self.uncomm_type_addr + 4, "methods number: %d" % self.meth_cnt) idc.MakeComm(self.uncomm_type_addr + 6, "exported methods number: %d" % self.xmeth_cnt) if self.meth_cnt > 0: idc.MakeComm(self.uncomm_type_addr + 8, "methods addr: 0x%x" % ((self.uncomm_type_addr + self.meth_off) & 0xFFFFFFFF)) else: idc.MakeComm(self.uncomm_type_addr + 8, "methods offset") idc.MakeComm(self.uncomm_type_addr + 12, "unused field: 0x%x" % self.unused) idaapi.autoWait()
def parse(self): _debug("Interface @ 0x%x" % self.addr) # parse pkg path self.pkg_path_addr = read_mem(self.addr + self.rtype.self_size) if self.pkg_path_addr > 0 and self.pkg_path_addr != idc.BADADDR: self.pkg_path_obj = Name(self.pkg_path_addr, self.type_parser.moddata) self.pkg_path_obj.parse(False) self.pkg_path = self.pkg_path_obj.name_str # parse fields methods_start_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ) methods_cnt = read_mem(self.addr + self.rtype.self_size + 2*ADDR_SZ) methods_cap = read_mem(self.addr + self.rtype.self_size + 3*ADDR_SZ) for idx in xrange(methods_cnt): imeth = IMethodType(methods_start_addr + idx*2*4, self.type_parser) imeth.parse() self.methods.append(imeth) idc.MakeComm(self.addr + self.rtype.self_size, "pkg path%s" % \ (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else "")) idc.MakeComm(self.addr + self.rtype.self_size + 2*ADDR_SZ, "methods count: 0x%x" % methods_cnt) idc.MakeComm(self.addr + self.rtype.self_size + 3*ADDR_SZ, "methods capacity: 0x%x" % methods_cap) idaapi.autoWait() _debug("Interface pkg path%s" % \ (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else "")) _debug("Interface methods count: 0x%x" % methods_cnt) if len(self.rtype.name) > 0: idc.MakeNameEx(methods_start_addr, "%s_methods" % self.rtype.name, flags=idaapi.SN_FORCE) idaapi.autoWait()
def parse(self): _debug("Struct Type @ 0x%x" % self.addr) # parse pkg path self.pkg_path_addr = read_mem(self.addr + self.rtype.self_size) if self.pkg_path_addr > 0 and self.pkg_path_addr != idc.BADADDR: self.pkg_path_obj = Name(self.pkg_path_addr, self.type_parser.moddata) self.pkg_path_obj.parse(False) self.pkg_path = self.pkg_path_obj.simple_name # parse fields fields_start_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ) fields_cnt = read_mem(self.addr + self.rtype.self_size + 2*ADDR_SZ) fields_cap = read_mem(self.addr + self.rtype.self_size + 3*ADDR_SZ) for idx in xrange(fields_cnt): field = StructFiled(fields_start_addr + idx*3*ADDR_SZ, self.type_parser) field.parse() self.fields.append(field) idc.MakeComm(self.addr + self.rtype.self_size, "pkg path%s" % \ (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else "")) idc.MakeComm(self.addr + self.rtype.self_size + 2*ADDR_SZ, "fields count: 0x%x" % fields_cnt) idc.MakeComm(self.addr + self.rtype.self_size + 3*ADDR_SZ, "fileds capacity: 0x%x" % fields_cap) idaapi.autoWait() _debug("Struct pkg path: %s" % (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) \ if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else "")) _debug("Struct fields num: 0x%x" % fields_cnt) if len(self.rtype.name) > 0 and fields_cnt > 0: idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "fields start address") idc.MakeNameEx(fields_start_addr, "%s_fields" % self.rtype.name, flags=idaapi.SN_FORCE) idaapi.autoWait() _debug("Struct fields start addr: 0x%x" % fields_start_addr)
def parse(self): self.name_obj_addr = read_mem(self.addr) if self.name_obj_addr == 0 or self.name_obj_addr == idc.BADADDR: raise Exception("Invalid name address when parsing struct field @ 0x%x" % self.addr) self.name_obj = Name(self.name_obj_addr, self.type_parser.moddata) self.name_obj.parse(False) self.name = self.name_obj.simple_name self.rtype_addr = read_mem(self.addr + ADDR_SZ) if self.rtype_addr == 0 or self.rtype_addr == idc.BADADDR: raise Exception("Invalid rtype address when parsing struct field @ 0x%x" % self.addr) if self.type_parser.has_been_parsed(self.rtype_addr): self.rtype = self.type_parser.parsed_types[self.rtype_addr] else: self.rtype = self.type_parser.parse_type(type_addr=self.rtype_addr) off_embeded = read_mem(self.addr + 2*ADDR_SZ) self.offset = off_embeded >> 1 self.is_embeded = (off_embeded & 1) != 0 idc.MakeComm(self.addr, "field name: %s" % self.name_obj.name_str) idaapi.autoWait() idc.MakeComm(self.addr + ADDR_SZ, "field rtype: %s" % self.rtype.name) idaapi.autoWait() _debug("Struct field name: %s" % self.name_obj.name_str) _debug("Struct field rtype: %s" % self.rtype.name)
def parse_funcs(self): ''' Parse function struct and rename function ''' self.func_num = common.read_mem(self.start_addr + 8, forced_addr_sz=self.ptr_sz) common._info("Total functions number: %d\n" % self.func_num) self.func_tbl_sz = self.func_num * 2 * self.ptr_sz funcs_entry = self.start_addr + 8 self.func_tbl_addr = funcs_entry + self.ptr_sz idc.MakeNameEx(funcs_entry, "funcs_entry", flags=idaapi.SN_FORCE) idaapi.autoWait() idc.MakeNameEx(self.func_tbl_addr, "pc0", flags=idaapi.SN_FORCE) idaapi.autoWait() for func_idx in xrange(self.func_num): curr_addr = self.func_tbl_addr + func_idx * 2 * self.ptr_sz func_addr = common.read_mem(curr_addr, forced_addr_sz=self.ptr_sz) name_off = common.read_mem(curr_addr + self.ptr_sz, forced_addr_sz=self.ptr_sz) name_addr = self.start_addr + self.ptr_sz + name_off func_st_addr = name_addr - self.ptr_sz func_st = FuncStruct(func_st_addr, self) func_st.parse() # Make comment for name offset idc.MakeComm(curr_addr + self.ptr_sz, "Func Struct: 0x%x" % func_st_addr) idaapi.autoWait()
def parse(self): _debug("Imethod Type @ 0x%x" % self.addr) name_off = read_mem(self.addr, forced_addr_sz=4) & 0xFFFFFFFF name_addr = (self.types_addr + name_off) & 0xFFFFFFFF self.name_obj = Name(name_addr, self.type_parser.moddata) self.name_obj.parse(False) self.name = self.name_obj.simple_name type_off = read_mem(self.addr+4, forced_addr_sz=4) & 0xFFFFFFFF type_addr = (self.types_addr + type_off) & 0xFFFFFFFF if type_off > 0 and type_addr != idc.BADADDR: if self.type_parser.has_been_parsed(type_addr): self.type = self.type_parser.parsed_types[type_addr].rtype else: self.type = self.type_parser.parse_type(type_addr=type_addr) if name_off > 0 and name_off != idc.BADADDR: idc.MakeComm(self.addr, "imethod name(@ 0x%x): %s" % (name_addr, self.name)) idaapi.autoWait() _debug("Interface imethod name(@ 0x%x): %s" % (name_addr, self.name)) if type_off > 0 and type_addr != idc.BADADDR: idc.MakeComm(self.addr + 4, "imethod type(@ 0x%x): %s" % (type_addr, self.type.name_obj.name_str)) idaapi.autoWait() _debug("Interface imethod type(@ 0x%x): %s" % (type_addr, self.type.name_obj.name_str))
def parse(self): itype_addr = common.read_mem(self.addr) & 0xFFFFFFFFFFFFFFFF self.itype = self.type_parser.parse_type(type_addr=itype_addr) rtype_addr = common.read_mem(self.addr+common.ADDR_SZ) & 0xFFFFFFFFFFFFFFFF self.rtype = self.type_parser.parse_type(type_addr=rtype_addr) self.hash = common.read_mem(self.addr + 2*common.ADDR_SZ, forced_addr_sz=4) & 0xFFFFFFFF # methods start addr(if has method) curr_addr = self.addr + 3*common.ADDR_SZ while True: if len(idaapi.get_ea_name(curr_addr)) > 0: # stop at next itab_elem addr # next itab elem is labeled a head name by ida pro break meth_addr = common.read_mem(curr_addr) if idaapi.get_func(meth_addr): meth_name = idaapi.get_ea_name(meth_addr) self.methods.append(meth_name) self.meth_num += 1 curr_addr += common.ADDR_SZ idc.MakeComm(self.addr, "interface: %s" % self.itype.name) idc.MakeComm(self.addr+common.ADDR_SZ, "rtype: %s" % self.rtype.name) idc.MakeComm(self.addr+2*common.ADDR_SZ, "rtype hash") idaapi.autoWait() itab_elem_name = "go_itab__%s_%s" % (self.rtype.name_obj.name_str, self.itype.name) idc.MakeNameEx(self.addr, itab_elem_name,flags=idaapi.SN_FORCE) common._debug("Go itab %s(@ 0x%x) parsed." % (itab_elem_name, self.addr)) idaapi.autoWait()
def parse_srcfile(self): ''' Parse and extract source all file names ''' srcfile_tbl_off = common.read_mem( self.func_tbl_addr + self.func_tbl_sz + self.ptr_sz, forced_addr_sz=4) & 0xFFFFFFFF self.srcfile_tbl_addr = self.start_addr + srcfile_tbl_off idc.MakeComm(self.func_tbl_addr + self.func_tbl_sz + self.ptr_sz, \ "Source file table addr: 0x%x" % self.srcfile_tbl_addr) idc.MakeNameEx(self.srcfile_tbl_addr, "runtime_filetab", flags=idaapi.SN_FORCE) idaapi.autoWait() self.srcfile_num = (common.read_mem(self.srcfile_tbl_addr, forced_addr_sz=4) & 0xFFFFFFFF) - 1 common._info( "--------------------------------------------------------------------------------------" ) common._info( "Source File paths(Total number: %d, default print results are user-defind files):\n" % self.srcfile_num) for idx in xrange(self.srcfile_num): srcfile_off = common.read_mem( (idx + 1) * 4 + self.srcfile_tbl_addr, forced_addr_sz=4) & 0xFFFFFFFF srcfile_addr = self.start_addr + srcfile_off srcfile_path = idc.GetString(srcfile_addr) if srcfile_path is None or len(srcfile_path) == 0: common._error("Failed to parse the [%d] src file(off: 0x%x, addr: @ 0x%x)" %\ (idx+1, srcfile_off, srcfile_addr)) continue if len(self.goroot) > 0 and (srcfile_path.startswith(self.goroot) or "/pkg/" in srcfile_path or\ srcfile_path == "<autogenerated>" or srcfile_path.startswith("_cgo_")): # ignore golang std libs and 3rd pkgs common._debug(srcfile_path) else: # User defined function self.srcfiles.append(srcfile_path) common._info(srcfile_path) idc.MakeStr(srcfile_addr, srcfile_addr + len(srcfile_path) + 1) idaapi.autoWait() idc.MakeComm((idx + 1) * 4 + self.srcfile_tbl_addr, "") idaapi.add_dref((idx + 1) * 4 + self.srcfile_tbl_addr, srcfile_addr, idaapi.dr_O) idaapi.autoWait() common._info( "--------------------------------------------------------------------------------------" )
def parse(self): name_off = read_mem(self.addr, forced_addr_sz=4) & 0xFFFFFFFF if name_off > 0: self.name_addr = self.types_addr + name_off self.name_obj = Name(self.name_addr, self.type_parser.moddata) self.name_obj.parse(False) self.name = self.name_obj.simple_name # note: some methods are actually not present in the binary # for those, typeOff, ifn, tfn are 0 type_off = read_mem(self.addr + 4, forced_addr_sz=4) & 0xFFFFFFFF if type_off > 0: self.mtype_addr = self.types_addr + type_off if self.type_parser.has_been_parsed(self.mtype_addr): self.mtype = self.type_parser.parsed_types[self.mtype_addr].rtype else: self.mtype = self.type_parser.parse_type(type_addr=self.mtype_addr) self.ifn_off = read_mem(self.addr + 8, forced_addr_sz=4) & 0xFFFFFFFF self.tfn_off = read_mem(self.addr + 12, forced_addr_sz=4) & 0xFFFFFFFF idc.MakeComm(self.addr, "Method Name%s" % \ (("(@ 0x%x): %s" % (self.name_addr, self.name)) if (name_off>0 and len(self.name)>0) else "")) _debug("Ucommon type Method Name%s" % \ (("(@ 0x%x): %s" % (self.name_addr, self.name)) if (name_off>0 and len(self.name)>0) else "")) idc.MakeComm(self.addr + 4, "Method Type%s" % \ (("(@ 0x%x): %s" % (self.mtype_addr, self.mtype.name_obj.name_str)) if (type_off>0 and self.mtype is not None) else "")) _debug("Uncommon type Method Type%s" % \ (("(@ 0x%x): %s" % (self.mtype_addr, self.mtype.name_obj.name_str)) if (type_off>0 and self.mtype is not None) else "")) self.ifn_addr = (self.text_addr + self.ifn_off) & 0xFFFFFFFF ifn_name = idc.get_func_name(self.ifn_addr) if ifn_name is None or len(ifn_name) == 0: if self.mtype is not None: ifn_name = self.mtype.name else: ifn_name == "_func_" idc.MakeComm(self.addr + 8, "ifn%s" % \ (("(@ 0x%x): %s" % (self.ifn_addr, ifn_name)) if self.ifn_off>0 else "")) self.tfn_addr = (self.text_addr + self.tfn_off) & 0xFFFFFFFF tfn_name = idc.get_func_name(self.tfn_addr) if tfn_name is None or len(tfn_name) == 0: if self.mtype is not None: tfn_name = self.mtype.name else: tfn_name = "_func_" idc.MakeComm(self.addr + 12, "tfn%s" % \ (("(@ 0x%x): %s" % (self.tfn_addr, tfn_name)) if self.tfn_off>0 else "")) idaapi.autoWait()
def parse(self): self.para_cnt = read_mem(self.addr + self.rtype.self_size, forced_addr_sz=2) & 0xFFFF self.ret_cnt = read_mem(self.addr + self.rtype.self_size + 2, forced_addr_sz=2) & 0xFFFF if self.ret_cnt & FuncType.VARIADIC_FLAG: self.is_variadic = True self.ret_cnt = self.ret_cnt & 0x7FFF self.padding = read_mem(self.addr + self.rtype.self_size + 4, forced_addr_sz=4) & 0xFFFFFFFF if self.padding == 0: # skip padding if present self.size += 4 curr_addr = self.addr + self.size if self.rtype.is_uncomm(): curr_addr += UncommonType.SIZE for in_idx in xrange(self.para_cnt): curr_para_type = None curr_para_type_off = curr_addr + in_idx * ADDR_SZ para_type_addr = read_mem(curr_para_type_off) self.para_type_addrs.append(para_type_addr) if self.type_parser.has_been_parsed(para_type_addr): curr_para_type = self.type_parser.parsed_types[para_type_addr] else: curr_para_type = self.type_parser.parse_type( type_addr=para_type_addr) self.para_types.append(curr_para_type) idaapi.autoWait() curr_addr += self.para_cnt * ADDR_SZ for out_idx in xrange(self.ret_cnt): curr_ret_type = None curr_ret_type_off = curr_addr + out_idx * ADDR_SZ ret_type_addr = read_mem(curr_ret_type_off) self.ret_type_addrs.append(ret_type_addr) if self.type_parser.has_been_parsed(ret_type_addr): curr_ret_type = self.type_parser.parsed_types[ret_type_addr] else: curr_ret_type = self.type_parser.parse_type( type_addr=ret_type_addr) self.ret_types.append(curr_ret_type) idaapi.autoWait() idc.MakeComm(self.addr + self.rtype.self_size, "Parameter count: %d" % self.para_cnt) idc.MakeComm(self.addr + self.rtype.self_size + 2, "%s%s" % ("Flag: Varidic;" \ if self.ret_cnt & FuncType.VARIADIC_FLAG else "", "Return value count: %d" % self.ret_cnt)) idaapi.autoWait()
def parse(self): elem_type_addr = read_mem(self.addr + self.rtype.self_size) if self.type_parser.has_been_parsed(elem_type_addr): self.elem_type = self.type_parser.parsed_types[elem_type_addr] else: self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr) self.elem_type.parse() dir_code = read_mem(self.addr + self.rtype.self_size + ADDR_SZ) self.direction = self.get_direction(dir_code) self.name = "channel %s (direction: %s)" % (self.rtype.name, self.direction) idc.MakeComm(self.addr + self.rtype.self_size, "elem type: %s" % self.elem_type.name) idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "chan direction: %s" % self.direction) idaapi.autoWait()
def find_first_moduledata_addr(): first_moduledata_addr = idc.BADADDR if not is_stripped(): # not stripped, find firstmoduledata by symbol name common._debug("Binary file is not stripped") for addr, name in idautils.Names(): if name == "runtime.firstmoduledata": first_moduledata_addr = addr break else: # is stripped, find firstmodule data by bruteforce searching common._debug("Binary file is stripped") magic_num = pclntbl.Pclntbl.MAGIC # firstmoduledata is contained in segment [.noptrdata] mdata_seg_addr = get_mdata_seg_addr() if mdata_seg_addr == None: raise Exception("Invalid address of segment [.noptrdata]") if mdata_seg_addr == 0: common._error("Failed to find valid segment [.noptrdata]") curr_addr = mdata_seg_addr while curr_addr <= idc.BADADDR: if idc.Dword(read_mem(curr_addr, read_only=True)) & 0xFFFFFFFF == magic_num: # possible firstmoduledata if test_firstmoduledata(curr_addr): break curr_addr += ADDR_SZ if curr_addr >= idc.BADADDR: raise Exception("Failed to find firstmoduledata address!") first_moduledata_addr = curr_addr return first_moduledata_addr
def parse_itab(moddata, type_parser): common._info("Start to parse Itab") itab_addr = idc.BADADDR itab_end_addr = idc.BADADDR itab_num = 0 # comfirm Itab's start_addr and end_addr if moddata == None: itab_seg = common.get_seg([".itablink", "__itablink"]) if itab_seg: itab_addr = itab_seg.start_ea itab_end_addr = itab_seg.end_ea itab_num = (itab_end_addr - itab_addr) / common.ADDR_SZ else: itab_addr = moddata.itablink_addr itab_num = moddata.itab_num itab_end_addr = itab_addr + itab_num * common.ADDR_SZ curr_addr = itab_addr while curr_addr < itab_end_addr: curr_itabelem_addr = common.read_mem(curr_addr, read_only=True) itab_elem = ItabElem(curr_itabelem_addr, type_parser) itab_elem.parse() itab_num += 1 curr_addr += common.ADDR_SZ common._info("Itab parsing done, total number: %d" % itab_num)
def parse(self): _debug("Map Type @ 0x%x" % self.addr) map_attr_addr = self.addr + self.rtype.self_size key_type_addr = read_mem(map_attr_addr) if self.type_parser.has_been_parsed(key_type_addr): self.key_type = self.type_parser.parsed_types[key_type_addr] else: self.key_type = self.type_parser.parse_type(type_addr=key_type_addr) elem_type_addr = read_mem(map_attr_addr + ADDR_SZ) if self.type_parser.has_been_parsed(elem_type_addr): self.elem_type = self.type_parser.parsed_types[elem_type_addr] else: self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr) buck_type_addr = read_mem(map_attr_addr + 2*ADDR_SZ) if self.type_parser.has_been_parsed(buck_type_addr): self.buck_type = self.type_parser.parsed_types[buck_type_addr] else: self.buck_type = self.type_parser.parse_type(type_addr=buck_type_addr) if self.go_subver < 14: self.key_size = idc.Byte(map_attr_addr + 3*ADDR_SZ) & 0xFF self.val_size = idc.Byte(map_attr_addr + 3*ADDR_SZ + 1) & 0xFF self.buck_size = read_mem(map_attr_addr + 3*ADDR_SZ + 2, forced_addr_sz=2) & 0xFFFF self.flags = read_mem(map_attr_addr + 3*ADDR_SZ + 4, forced_addr_sz=4) & 0xFFFFFFFF else: self.hasher_func_addr = read_mem(map_attr_addr + 3*ADDR_SZ) self.key_size = idc.Byte(map_attr_addr + 4*ADDR_SZ) & 0xFF self.val_size = idc.Byte(map_attr_addr + 4*ADDR_SZ + 1) & 0xFF self.buck_size = read_mem(map_attr_addr + 4*ADDR_SZ + 2, forced_addr_sz=2) & 0xFFFF self.flags = read_mem(map_attr_addr + 4*ADDR_SZ + 4, forced_addr_sz=4) & 0xFFFFFFFF self.name = "map [%s]%s" % (self.key_type.name, self.elem_type.name) idc.MakeComm(map_attr_addr, "Key type: %s" % self.key_type.name) idc.MakeComm(map_attr_addr + ADDR_SZ, "Elem type: %s " % self.elem_type.name) idc.MakeComm(map_attr_addr + 2*ADDR_SZ, "Bucket type: %s" % self.buck_type.name) if self.go_subver < 14: idc.MakeComm(map_attr_addr + 3*ADDR_SZ, "Key size: 0x%x" % self.key_size) idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 1, "Value size: 0x%x" % self.val_size) idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 2, "Bucket size: 0x%x" % self.buck_size) idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 4, "Flags: 0x%x" % self.flags) else: idc.MakeComm(map_attr_addr + 3*ADDR_SZ, "hash function for hashing keys (ptr to key, seed) -> hash") idc.MakeComm(map_attr_addr + 4*ADDR_SZ, "Key size: 0x%x" % self.key_size) idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 1, "Value size: 0x%x" % self.val_size) idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 2, "Bucket size: 0x%x" % self.buck_size) idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 4, "Flags: 0x%x" % self.flags) idaapi.autoWait() _debug("Map Key type: %s" % self.key_type.name) _debug("Map Elem type: %s " % self.elem_type.name)
def parse(self): self.elem_type_addr = read_mem(self.addr + self.rtype.self_size) if self.type_parser.has_been_parsed(self.elem_type_addr): self.elem_rtype = self.type_parser.parsed_types[self.elem_type_addr] else: self.elem_rtype = self.type_parser.parse_type(type_addr=self.elem_type_addr) idc.MakeComm(self.addr + self.rtype.self_size, "elem rtype: %s" % self.elem_rtype.name) idc.MakeNameEx(self.addr, "%s_slice" % self.elem_rtype.name, flags=idaapi.SN_FORCE) idaapi.autoWait()
def parse(self): elem_type_addr = read_mem(self.addr + self.rtype.self_size) if self.type_parser.has_been_parsed(elem_type_addr): self.elem_type = self.type_parser.parsed_types[elem_type_addr] else: self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr) slice_type_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ) if self.type_parser.has_been_parsed(slice_type_addr): self.slice_type = self.type_parser.parsed_types[slice_type_addr] else: self.slice_type = self.type_parser.parse_type(type_addr=slice_type_addr) self.len = read_mem(self.addr + self.rtype.self_size + 2 * ADDR_SZ) idc.MakeComm(self.addr + self.rtype.self_size, "elem type: %s" % self.elem_type.name) idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "slice type: %s" % self.slice_type.name) idc.MakeNameEx(self.addr, "%s_array" % self.elem_type.name, flags=idaapi.SN_FORCE) idaapi.autoWait()
def test_firstmoduledata(possible_addr): ''' Check if current addr is first module data ''' mod_data = ModuleData(possible_addr) mod_data.parse(is_test=True) if read_mem(mod_data.pclntbl_addr + 8 + ADDR_SZ, read_only=True) == mod_data.text_addr: print("Find firstmoduledata @ 0x%x" % possible_addr) return True return False
def parse(self): self.target_type_addr = read_mem(self.addr + self.rtype.self_size) if self.type_parser.has_been_parsed(self.target_type_addr): self.target_rtype = self.type_parser.parsed_types[self.target_type_addr] else: self.target_rtype = self.type_parser.parse_type(type_addr=self.target_type_addr) if self.target_rtype: self.name = self.target_rtype.name + "_ptr" idc.MakeComm(self.addr + self.rtype.self_size, "target rtype: %s" % self.target_rtype.name) idaapi.autoWait()
def parse(self): name_off = read_mem(self.addr, forced_addr_sz=4) name_addr = (self.types_addr + name_off) & 0xFFFFFFFF self.name_obj = Name(name_addr, self.type_parser.moddata) self.name_obj.parse(False) self.name = self.name_obj.simple_name type_off = read_mem(self.addr+4, forced_addr_sz=4) type_addr = (self.types_addr + type_off) & 0xFFFFFFFF if type_off > 0 and type_addr != idc.BADADDR: if self.type_parser.has_been_parsed(type_addr): self.type = self.type_parser.parsed_types[type_addr].rtype else: self.type = self.type_parser.parse_type(type_addr=type_addr) if name_off > 0 and name_off != idc.BADADDR: idc.MakeComm(self.addr, "imethod name: %s (@ 0x%x)" % (self.name, name_addr)) idaapi.autoWait() if type_off > 0 and type_addr != idc.BADADDR: idc.MakeComm(self.addr + 4, "imethod type: %s (@ 0x%x)" % (self.type.name_obj.name_str, type_addr))
def parse(self): _debug("PtrType @ 0x%x" % self.addr) self.target_type_addr = read_mem(self.addr + self.rtype.self_size) if self.type_parser.has_been_parsed(self.target_type_addr): self.target_rtype = self.type_parser.parsed_types[self.target_type_addr] self.target_rtype_origname = self.target_rtype.rtype.name_obj.orig_name_str else: self.target_rtype = self.type_parser.parse_type(type_addr=self.target_type_addr) self.target_rtype_origname = self.target_rtype.name_obj.orig_name_str if self.target_rtype: self.name = self.target_rtype.name + "_ptr" idc.MakeComm(self.addr + self.rtype.self_size, "target rtype: %s" % self.target_rtype_origname) idaapi.autoWait() _debug("target rtype: %s" % self.target_rtype_origname)
def build_all_types(self, depth=1): _info("Building all types...") for idx in xrange(self.moddata.type_num): type_off = read_mem(self.moddata.typelink_addr + idx*4, forced_addr_sz=4) & 0xFFFFFFFF if type_off == 0: continue type_addr = self.moddata.types_addr + type_off if type_addr in self.parsed_types.keys(): _debug(" "*depth + 'already parsed') continue #print self.parsed_types.keys() #try: self.parse_type(type_addr=type_addr) idc.MakeComm(self.moddata.typelink_addr + idx*4, "type @ 0x%x" % type_addr) idaapi.autoWait() #except Exception as e: # _error("Failed to parse type_off( 0x%x ) @ 0x%x" % (type_off, type_addr)) # raise Exception(e) _info("types building finished. Total types number: %d" % len(self.parsed_types.keys()))
def find_first_moduledata_addr_by_brute(): magic_num = pclntbl.Pclntbl.MAGIC first_moduledata_addr = idc.BADADDR segn = ida_segment.get_segm_qty() for idx in range(segn): curr_seg = ida_segment.getnseg(idx) curr_addr = curr_seg.start_ea while curr_addr <= curr_seg.end_ea: if idc.Dword( read_mem(curr_addr, read_only=True) ) & 0xFFFFFFFF == magic_num: # possible firstmoduledata if test_firstmoduledata(curr_addr): break curr_addr += ADDR_SZ if curr_addr >= curr_seg.end_ea: continue first_moduledata_addr = curr_addr break return first_moduledata_addr
def parse(self, is_test=False): func_addr = common.read_mem(self.addr, forced_addr_sz=self.pclntbl.ptr_sz, read_only=is_test) name_addr = common.read_mem(self.addr + self.pclntbl.ptr_sz, forced_addr_sz=4, read_only=is_test) \ + self.pclntbl.start_addr raw_name_str = idc.GetString(name_addr) if raw_name_str and len(raw_name_str) > 0: self.name = common.clean_function_name(raw_name_str) if not is_test: idc.MakeComm(self.addr, "Func Entry") idaapi.autoWait() # make comment for func name offset idc.MakeComm( self.addr + self.pclntbl.ptr_sz, "Func name offset(Addr @ 0x%x), name string: %s" % (name_addr, raw_name_str)) idaapi.autoWait() # Make name string if len(self.name) > 0: if idc.MakeStr(name_addr, name_addr + len(raw_name_str) + 1): idaapi.autoWait() common._debug("Match func_name: %s" % self.name) else: common._error("Make func_name_str [%s] failed @0x%x" % (self.name, name_addr)) # Rename function real_func_addr = idaapi.get_func(func_addr) if len(self.name) > 0 and real_func_addr is not None: if idc.MakeNameEx(real_func_addr.startEA, self.name, flags=idaapi.SN_FORCE): idaapi.autoWait() common._debug("Rename function 0x%x: %s" % (real_func_addr.startEA, self.name)) else: common._error('Failed to rename function @ 0x%x' % real_func_addr.startEA) self.args = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4, forced_addr_sz=4, read_only=is_test) self.frame = common.read_mem(self.addr + self.pclntbl.ptr_sz + 2 * 4, forced_addr_sz=4, read_only=is_test) self.pcsp = common.read_mem(self.addr + self.pclntbl.ptr_sz + 3 * 4, forced_addr_sz=4, read_only=is_test) self.pcfile = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4 * 4, forced_addr_sz=4, read_only=is_test) self.pcln = common.read_mem(self.addr + self.pclntbl.ptr_sz + 5 * 4, forced_addr_sz=4, read_only=is_test) self.nfuncdata = common.read_mem(self.addr + self.pclntbl.ptr_sz + 6 * 4, forced_addr_sz=4, read_only=is_test) self.npcdata = common.read_mem(self.addr + self.pclntbl.ptr_sz + 7 * 4, forced_addr_sz=4, read_only=is_test) if not is_test: idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4, "args") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 2 * 4, "frame") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 3 * 4, "pcsp") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4 * 4, "pcfile") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 5 * 4, "pcln") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 6 * 4, "nfuncdata") idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 7 * 4, "npcdata") idaapi.autoWait()
def parse(self, is_test=False): if is_test: common._info("Test firstmoduledata addr: 0x%x" % self.start_addr) self.pclntbl_addr = read_mem(self.start_addr, read_only=is_test) self.pclntbl_sz = read_mem(self.start_addr + ADDR_SZ, read_only=is_test) self.pclntbl_cap = read_mem(self.start_addr + 2 * ADDR_SZ, read_only=is_test) self.ftab_addr = read_mem(self.start_addr + 3 * ADDR_SZ, read_only=is_test) self.func_num = read_mem(self.start_addr + 4 * ADDR_SZ, read_only=is_test) self.ftab_cap = read_mem(self.start_addr + 5 * ADDR_SZ, read_only=is_test) self.filetab_addr = read_mem(self.start_addr + 6 * ADDR_SZ, read_only=is_test) self.srcfile_num = read_mem(self.start_addr + 7 * ADDR_SZ, read_only=is_test) self.srcfile_tab_cap = read_mem(self.start_addr + 8 * ADDR_SZ, read_only=is_test) self.findfunctab = read_mem(self.start_addr + 9 * ADDR_SZ, read_only=is_test) self.min_pc = read_mem(self.start_addr + 10 * ADDR_SZ, read_only=is_test) self.max_pc = read_mem(self.start_addr + 11 * ADDR_SZ, read_only=is_test) self.text_addr = read_mem(self.start_addr + 12 * ADDR_SZ, read_only=is_test) self.etext_addr = read_mem(self.start_addr + 13 * ADDR_SZ, read_only=is_test) if is_test: return self.noptrdata_addr = read_mem(self.start_addr + 14 * ADDR_SZ, read_only=is_test) self.enoptrdata_addr = read_mem(self.start_addr + 15 * ADDR_SZ, read_only=is_test) self.data_addr = read_mem(self.start_addr + 16 * ADDR_SZ, read_only=is_test) self.edata_addr = read_mem(self.start_addr + 17 * ADDR_SZ, read_only=is_test) self.bss_addr = read_mem(self.start_addr + 18 * ADDR_SZ, read_only=is_test) self.ebss_addr = read_mem(self.start_addr + 19 * ADDR_SZ, read_only=is_test) self.noptrbss_addr = read_mem(self.start_addr + 20 * ADDR_SZ, read_only=is_test) self.enoptrbss_addr = read_mem(self.start_addr + 21 * ADDR_SZ, read_only=is_test) self.end_addr = read_mem(self.start_addr + 22 * ADDR_SZ, read_only=is_test) self.gcdata_addr = read_mem(self.start_addr + 23 * ADDR_SZ, read_only=is_test) self.gcbss_addr = read_mem(self.start_addr + 24 * ADDR_SZ, read_only=is_test) self.types_addr = read_mem(self.start_addr + 25 * ADDR_SZ, read_only=is_test) self.etypes_addr = read_mem(self.start_addr + 26 * ADDR_SZ, read_only=is_test) self.textsecmap_addr = read_mem(self.start_addr + 27 * ADDR_SZ, read_only=is_test) self.textsecmap_len = read_mem(self.start_addr + 28 * ADDR_SZ, read_only=is_test) self.textsecmap_cap = read_mem(self.start_addr + 29 * ADDR_SZ, read_only=is_test) self.typelink_addr = read_mem(self.start_addr + 30 * ADDR_SZ, read_only=is_test) self.type_num = read_mem(self.start_addr + 31 * ADDR_SZ, read_only=is_test) self.type_cap = read_mem(self.start_addr + 32 * ADDR_SZ, read_only=is_test) self.itablink_addr = read_mem(self.start_addr + 33 * ADDR_SZ, read_only=is_test) self.itab_num = read_mem(self.start_addr + 34 * ADDR_SZ, read_only=is_test) self.itab_cap = read_mem(self.start_addr + 35 * ADDR_SZ, read_only=is_test) self.ptab_addr = read_mem(self.start_addr + 36 * ADDR_SZ, read_only=is_test) self.ptab_num = read_mem(self.start_addr + 37 * ADDR_SZ, read_only=is_test) self.ptab_cap = read_mem(self.start_addr + 38 * ADDR_SZ, read_only=is_test) pluginpath_addr = read_mem(self.start_addr + 39 * ADDR_SZ, read_only=is_test) pluginpath_len = read_mem(self.start_addr + 40 * ADDR_SZ, read_only=is_test) self.pluginpath = str(idc.GetManyBytes(pluginpath_addr, pluginpath_len)) modulename_addr = read_mem(self.start_addr + 44 * ADDR_SZ, read_only=is_test) modulename_len = read_mem(self.start_addr + 45 * ADDR_SZ, read_only=is_test) self.modulename = str(idc.GetManyBytes(modulename_addr, modulename_len)) self.hasmain = idc.Byte(self.start_addr + 49 * ADDR_SZ) self.next = read_mem(self.start_addr + 54 * ADDR_SZ + 1, read_only=is_test) if not is_test: idc.MakeNameEx(self.start_addr, "runtime.firstmoduledata", flags=idaapi.SN_FORCE) idaapi.autoWait() idc.MakeComm(self.start_addr, "pclntbl addr") idc.MakeComm(self.start_addr + ADDR_SZ, "pclntbl size") idc.MakeComm(self.start_addr + 2 * ADDR_SZ, "pclntbl capacity") idc.MakeComm(self.start_addr + 3 * ADDR_SZ, "funcs table addr") idc.MakeComm(self.start_addr + 4 * ADDR_SZ, "funcs number") idc.MakeComm(self.start_addr + 5 * ADDR_SZ, "funcs table capacity") idc.MakeComm(self.start_addr + 6 * ADDR_SZ, "source files table addr") idc.MakeComm(self.start_addr + 7 * ADDR_SZ, "source files number") idc.MakeComm(self.start_addr + 7 * ADDR_SZ, "source files table capacity") idc.MakeComm(self.start_addr + 9 * ADDR_SZ, "findfunctable addr") idc.MakeComm(self.start_addr + 10 * ADDR_SZ, "min pc") idc.MakeComm(self.start_addr + 11 * ADDR_SZ, "max pc") idc.MakeComm(self.start_addr + 12 * ADDR_SZ, "text start addr") idc.MakeComm(self.start_addr + 13 * ADDR_SZ, "text end addr") idc.MakeComm(self.start_addr + 14 * ADDR_SZ, "noptrdata start addr") idc.MakeComm(self.start_addr + 15 * ADDR_SZ, "noptrdata end addr") idc.MakeComm(self.start_addr + 16 * ADDR_SZ, "data section start addr") idc.MakeComm(self.start_addr + 17 * ADDR_SZ, "data section end addr") idc.MakeComm(self.start_addr + 18 * ADDR_SZ, "bss start addr") idc.MakeComm(self.start_addr + 19 * ADDR_SZ, "bss end addr") idc.MakeComm(self.start_addr + 20 * ADDR_SZ, "noptrbss start addr") idc.MakeComm(self.start_addr + 21 * ADDR_SZ, "noptrbss end addr") idc.MakeComm(self.start_addr + 22 * ADDR_SZ, "end addr of whole image") idc.MakeComm(self.start_addr + 23 * ADDR_SZ, "gcdata addr") idc.MakeComm(self.start_addr + 24 * ADDR_SZ, "gcbss addr") idc.MakeComm(self.start_addr + 25 * ADDR_SZ, "types start addr") idc.MakeComm(self.start_addr + 26 * ADDR_SZ, "types end addr") idc.MakeComm(self.start_addr + 27 * ADDR_SZ, "test section map addr") idc.MakeComm(self.start_addr + 28 * ADDR_SZ, "test section map length") idc.MakeComm(self.start_addr + 29 * ADDR_SZ, "test section map capacity") idc.MakeComm(self.start_addr + 30 * ADDR_SZ, "typelink addr") idc.MakeComm(self.start_addr + 31 * ADDR_SZ, "types number") idc.MakeComm(self.start_addr + 32 * ADDR_SZ, "types table capacity") idc.MakeComm(self.start_addr + 33 * ADDR_SZ, "itabslink addr") idc.MakeComm(self.start_addr + 34 * ADDR_SZ, "itabs number") idc.MakeComm(self.start_addr + 35 * ADDR_SZ, "itabs caapacity") idc.MakeComm(self.start_addr + 36 * ADDR_SZ, "ptab addr") idc.MakeComm(self.start_addr + 37 * ADDR_SZ, "ptab num") idc.MakeComm(self.start_addr + 38 * ADDR_SZ, "ptab capacity") idc.MakeComm(self.start_addr + 39 * ADDR_SZ, "plugin path addr") idc.MakeComm(self.start_addr + 40 * ADDR_SZ, "plugin path length") idc.MakeComm(self.start_addr + 44 * ADDR_SZ, "module name addr") idc.MakeComm(self.start_addr + 45 * ADDR_SZ, "module name length") idc.MakeComm(self.start_addr + 49 * ADDR_SZ, "hasmain flag") idc.MakeComm(self.start_addr + 54 * ADDR_SZ + 1, "next moduledata addr") idaapi.autoWait() idc.MakeStr(modulename_addr, modulename_addr + modulename_len) idaapi.autoWait() idc.MakeStr(pluginpath_addr, pluginpath_addr + pluginpath_len) idaapi.autoWait()
def parse(self, has_star_prefix): flag_byte = idc.Byte(self.addr) & 0xFF self.is_exported = flag_byte & self.EXPORTED != 0 self.is_followed_by_tag = flag_byte & self.FOLLOWED_BY_TAG != 0 self.is_followed_by_pkgpath = flag_byte & self.FOLLOWED_BY_PKGPATH != 0 self.len = ((idc.Byte(self.addr + 1) & 0xFF << 8) | (idc.Byte(self.addr + 2) & 0xFF)) & 0xFFFF self.orig_name_str = str(idc.GetManyBytes(self.addr + 3, self.len)) self.name_str = self.orig_name_str # delete star_prefix: while True: if self.name_str[0] == '*': self.name_str = self.name_str[1:] else: break if self.is_followed_by_tag: self.tag_len = (idc.Byte(self.addr+ 3 + self.len) & 0xFF << 8) \ | (idc.Byte(self.addr + 3 + self.len + 1) & 0xFF) self.tag = str(idc.GetManyBytes(self.addr + 3 + self.len + 2, self.tag_len)) # if name was reased, the replace name string with tag string if (not self.name_str or len(self.name_str) == 0) and self.tag and self.tag_len > 0: self.name_str = self.tag self.len = self.tag_len if self.is_followed_by_pkgpath: pkgpath_off_addr = self.addr + 3 + self.len if self.is_followed_by_tag: pkgpath_off_addr += (self.tag_len + 2) pkgpath_off = read_mem(pkgpath_off_addr, forced_addr_sz=4) & 0xFFFFFFFF if pkgpath_off > 0: pkgpath_addr = self.moddata.types_addr + pkgpath_off pkgpath_name_obj = Name(pkgpath_addr, self.moddata) pkgpath_name_obj.parse(False) self.pkg = pkgpath_name_obj.name_str self.pkg_len = len(self.pkg) if self.pkg_len: idc.MakeComm(pkgpath_off_addr, "pkgpath(@ 0x%x): %s" % (pkgpath_addr, self.pkg)) idaapi.autoWait() self.full_name = "%s%s%s" % (self.pkg if self.pkg else "", ("_%s" % self.name_str) \ if self.pkg else self.name_str, ('_%s' % self.tag) if self.tag else "") self.simple_name = "%s%s" % (self.pkg if self.pkg else "", ("_%s" % self.name_str) \ if self.pkg else self.name_str) flag_comm_str = "flag: " if self.is_exported: flag_comm_str += "exported" if self.is_followed_by_tag: if self.is_exported: flag_comm_str += ", followed by tag" else: flag_comm_str += "followed by tag" if self.is_followed_by_pkgpath: if self.is_exported or self.is_followed_by_tag: flag_comm_str += ", followed by pkgpath" else: flag_comm_str += "followed by pkgpath" if len(flag_comm_str) > 6: # has valid flag idc.MakeComm(self.addr, flag_comm_str) idaapi.autoWait() idc.MakeStr(self.addr + 3, self.addr + 3 + self.len) idaapi.autoWait() if self.is_followed_by_tag: idc.MakeStr(self.addr + 3 + self.len + 2, self.addr + 3 + self.len + 2 + self.tag_len) idc.MakeComm(self.addr + 3 + self.len + 2, "tag of @ 0x%x" % self.addr) idaapi.autoWait()
def parse(self): _debug("RType @ 0x%x" % self.addr) self.size = read_mem(self.addr) self.ptrdata = read_mem(self.addr + ADDR_SZ) self.hash = read_mem(self.addr + 2*ADDR_SZ, forced_addr_sz=4) & 0xFFFFFFFF self.tflag = idc.Byte(self.addr + 2*ADDR_SZ + 4) & 0xFF self.align = idc.Byte(self.addr + 2*ADDR_SZ + 5) & 0xFF self.field_align = idc.Byte(self.addr + 2*ADDR_SZ + 6) & 0xFF self.kind = idc.Byte(self.addr + 2*ADDR_SZ + 7) & 0xFF & RType.KIND_MASK self.alg = read_mem(self.addr + 2*ADDR_SZ + 8) self.gcdata = read_mem(self.addr + 3*ADDR_SZ + 8) self.name_off = read_mem(self.addr + 4*ADDR_SZ + 8, forced_addr_sz=4) & 0xFFFFFFFF self.name_addr = (self.moddata.types_addr + self.name_off) & 0xFFFFFFFF self.ptrtothis_off = read_mem(self.addr + 4*ADDR_SZ + 12, forced_addr_sz=4) & 0xFFFFFFFF if self.ptrtothis_off > 0: self.ptrtothis_addr = (self.moddata.types_addr + self.ptrtothis_off) & 0xFFFFFFFF idc.MakeComm(self.addr, "type size") idc.MakeComm(self.addr + ADDR_SZ, "type ptrdata") idc.MakeComm(self.addr + 2*ADDR_SZ, "type hash") tflag_comm = "tflag:" if self.has_star_prefix(): tflag_comm += " Star Prefix;" if self.is_named(): tflag_comm += " Named;" if self.is_uncomm(): tflag_comm += " Uncommon" idc.MakeComm(self.addr + 2*ADDR_SZ + 4, tflag_comm) _debug(tflag_comm) idc.MakeComm(self.addr + 2*ADDR_SZ + 5, "align") idc.MakeComm(self.addr + 2*ADDR_SZ + 6, "field align") idc.MakeComm(self.addr + 2*ADDR_SZ + 7, "kind: %s" % self.get_kind()) idc.MakeComm(self.addr + 2*ADDR_SZ + 8, "alg") idc.MakeComm(self.addr + 3*ADDR_SZ + 8, "gcdata") _debug("kind: %s" % self.get_kind()) if self.ptrtothis_off > 0: idc.MakeComm(self.addr + 4*ADDR_SZ + 12, "ptrtothis addr: 0x%x" % self.ptrtothis_addr) _debug("ptrtothis addr: 0x%x" % self.ptrtothis_addr) else: idc.MakeComm(self.addr + 4*ADDR_SZ + 12, "ptrtothis addr") idaapi.autoWait() self.name_obj = Name(self.name_addr, self.moddata) self.name_obj.parse(self.has_star_prefix()) self.name = self.name_obj.simple_name idc.MakeComm(self.addr + 4*ADDR_SZ + 8, "name(@ 0x%x ): %s" % (self.name_addr, self.name_obj.orig_name_str)) _debug("name(@ 0x%x ): %s" % (self.name_addr, self.name_obj.orig_name_str)) # if a raw type is un-named, and name string is erased, the name it as it's kind string if len(self.name) == 0 and self.type_parser.is_raw_type(self.get_kind()) and not self.is_named(): self.name = self.get_kind() # if an un-raw type is named, then concat a kind string as suffix with it's name if len(self.name) > 0 and self.is_named() and not self.type_parser.is_raw_type(self.get_kind()): self.name += ("_%s" % self.get_kind().lower()) if self.get_kind() == "Struct" and not self.is_named(): # un-named struct type self.name = "_struct_" if self.get_kind() == "Func" and not self.is_named(): # un-named func type self.name = "_func_" if self.get_kind() == "Ptr": self.name += "_ptr" if len(self.name) > 0: idc.MakeNameEx(self.addr, self.name, flags=idaapi.SN_FORCE) idaapi.autoWait() # parse type pointer if self.ptrtothis_off > 0 and self.ptrtothis_addr != idc.BADADDR: if self.type_parser.has_been_parsed(self.ptrtothis_addr): self.ptrtothis = self.type_parser.parsed_types[self.ptrtothis_addr] else: self.ptrtothis = self.type_parser.parse_type(type_addr=self.ptrtothis_addr) idaapi.autoWait()
def parse_str_ptr(addr): if idc.GetMnem(addr) != 'mov': return False # Validate that the string offset actually exists inside the binary if idc.get_segm_name(idc.GetOperandValue(addr, 1)) is None: return False # Check the operands' type: # - first one must be a register; # - second one must be a memory address if idc.GetOpType(addr, 0) != 1 or idc.GetOpType(addr, 1) != 2: return False addr_2 = idc.FindCode(addr, idaapi.SEARCH_DOWN) # same operands' type for addr_2 if idc.GetMnem(addr_2) != 'mov' or idc.GetOpType( addr_2, 0) != 1 or idc.GetOpType(addr_2, 1) != 2: return False opnd_val_1 = idc.GetOperandValue(addr, 1) opnd_val_2 = idc.GetOperandValue(addr_2, 1) opnd_diff = opnd_val_1 - opnd_val_2 # The 2 operands, one of addr of string length, another one is the addr of string pointer # and they must be side by side if opnd_diff != common.ADDR_SZ and opnd_diff != -common.ADDR_SZ: return False if opnd_diff > 0: str_len_addr, str_ptr_addr = opnd_val_1, opnd_val_2 else: str_len_addr, str_ptr_addr = opnd_val_2, opnd_val_1 str_len = common.read_mem(str_len_addr) str_ptr = common.read_mem(str_ptr_addr) str_addr = common.read_mem(str_ptr) # set max str len if str_len > 64: return False if 'rodata' not in idc.get_segm_name( str_ptr) and 'text' not in idc.get_segm_name(str_ptr): return False common._debug("------------------------------") common._debug("Possible str ptr:") common._debug("Code addr: 0x%x , str_ptr_addr: 0x%x , str_len_addr: 0x%x" % (addr, str_ptr_addr, str_len_addr)) common._debug("str_addr: 0x%x , str_len: 0x%x" % (str_ptr, str_len)) #if create_string(str_addr, str_len): if str_len > 1: if idc.MakeStr(str_ptr, str_ptr + str_len): idaapi.autoWait() if opnd_diff > 0: idc.MakeComm(addr, "length: %d" % str_len) idaapi.add_dref(addr_2, str_ptr, idaapi.dr_O) else: idc.MakeComm(addr_2, "length: %d" % str_len) idaapi.add_dref(addr, str_ptr, idaapi.dr_O) idaapi.autoWait() return True return False