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): _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): 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_hdr(self): ''' Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go ''' magic = idc.Dword(self.start_addr) & 0xFFFFFFFF if magic != Pclntbl.MAGIC: print magic, Pclntbl.MAGIC common._error("Invalid pclntbl header magic number!") idc.Exit(1) #raise Exception("Invalid pclntbl header magic number!") idc.MakeDword(self.start_addr) idc.MakeComm(self.start_addr, "Magic Number") idc.MakeNameEx(self.start_addr, "runtime_symtab", flags=idaapi.SN_FORCE) idaapi.autoWait() if idc.Word(self.start_addr + 4) & 0xFFFF != 0: raise Exception("Invalid pclntbl header") idc.MakeWord(self.start_addr + 4) self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4): raise Exception("Invalid pclntbl minimum LC!") idc.MakeComm(self.start_addr + 6, "instruction size quantum") idaapi.autoWait() self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF if (self.ptr_sz != 4) and (self.ptr_sz != 8): raise Exception("Invalid pclntbl pointer size!") idc.MakeComm(self.start_addr + 7, "ptr size") 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 readDefinition(self, ea): # Read all the fields from the stream. self.type = MakeAndGetWord(ea) idc.MakeWord(ea + 2) self.name_address = MakeAndGetDword(ea + 4) self.definition_address = MakeAndGetDword(ea + 8, "definition address") self.group_tag = MakeAndGetString(ea + 12, 4, "group tag") # Read strings. self.name_str = ReadString(self.name_address) # Comment the field type. idc.MakeComm(ea, field_type.field_types[self.type]) # Check if we should comment the name string. if self.name_address < g_BaseAddress: idc.MakeComm(ea + 4, self.name_str) # Check the field type and read the definition accordingly. if self.type == field_type._field_block: # Read the tag block definition. tagBlock = tag_block_definition() tagBlock.readDefinition(self.definition_address) elif self.type == field_type._field_struct: # Ghetto hack to read the struct definition struct. MakeAndGetDword(self.definition_address) MakeAndGetDword(self.definition_address + 4, "group tag") MakeAndGetDword(self.definition_address + 8) blockAddress = MakeAndGetDword(self.definition_address + 12, "block definition address") # Read the tag block definition. tagBlock = tag_block_definition() tagBlock.readDefinition(blockAddress)
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 OnDeleteLine(self, n): ans = idaapi.askyn_c( 1, "HIDECANCEL\nAre you sure you want to delete function [%s] @ [%s]?" % (self.items[n][3], self.items[n][4])) if ans == 1: asms = Assembler.LoadSavedAssemblers() item = int(self.items[n][2], 16) if asms != None and len(asms.keys()) > 0: for asm in asms.itervalues(): if asm.functions.has_key(item): print "Removed [%08x]!" % item del asm.functions[item] asm.SaveState() opty_ea = int(self.items[n][4], 16) print "set_name[%08x]" % opty_ea idc.MakeComm(opty_ea, "") idaapi.set_name(opty_ea, "") idc.DelFunction(opty_ea) comment = idc.Comment(item) comment = re.sub(r"(?i)OPTY@\[[\d+abcdef]+\];\s*", "", comment) idc.MakeComm(item, comment) self.populate_items() return n
def make_comment(pos, string): """ Creates a comment with contents `string` at address `pos`. If the address is already commented append the new comment to the existing comment """ current_comment = idc.Comment(pos) if not current_comment: idc.MakeComm(pos, string) elif string not in current_comment: idc.MakeComm(pos, current_comment + " " + string)
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 "_cgo_" in srcfile_path or "go/src/git" in srcfile_path): # 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 yatest_comments(self): eas = [] for offset in range(0, 3): for fn_cmt, fn_rpt, cmt, rpt, post, ant in tests: ea = get_func_item(offset) eas.append(ea) logger.debug("setting at 0x%08X : %r, %r, %r, %r, %r, %r" % (ea, fn_cmt, fn_rpt, cmt, rpt, post, ant)) if fn_cmt != None: self.assertEqual(idc.SetFunctionCmt(ea, fn_cmt, False), True) if fn_rpt != None: self.assertEqual(idc.SetFunctionCmt(ea, fn_rpt, True), True) if cmt != None: self.assertEqual(idc.MakeComm(ea, cmt), True) if rpt != None: self.assertEqual(idc.MakeRptCmt(ea, rpt), True) if post != None: for i, txt in enumerate(post.split('\n')): self.try_ext_lin(idc.ExtLinB, ea, i, txt) if ant != None: for i, txt in enumerate(ant.split('\n')): self.try_ext_lin(idc.ExtLinA, ea, i, txt) yaunit.save('comments', eas)
def LoadStringLiterals(ea=None): if ea is None: ea = ScreenEA() path = os.getcwd() os.system(path + '/unity_decoder.exe') file = open('./string_literal.txt') str_count = file.readline() skip_count = file.readline() ea += int(skip_count) * 0x4 for line in file: line = line.strip(' ').replace('\r', '').replace('\n', '') new_line = re.sub(r'[^a-zA-Z0-9_]', '_', line) new_line = 'StringLiteral_' + new_line i = 0 addr = GetVarFromAddr(ea) ret = idc.MakeNameEx(addr, str(new_line), SN_NOWARN) #ret = idc.MakeNameEx(addr, "", SN_NOWARN) while ret == 0 and i < 5: # failed new_line_rand = new_line + '_' + str(random.randint(0, 99999)) ret = idc.MakeNameEx(addr, str(new_line_rand), SN_NOWARN) i = i + 1 idc.MakeComm(ea, str(line)) #idc.MakeComm(ea, "") ea = IncreaseAddr(ea) file.close()
def LoadMethods(ea=None): if ea is None: ea = ScreenEA() path = os.getcwd() os.system(path + '/unity_decoder.exe') file = open('./method_name.txt') str_count = file.readline() i = 0 for line in file: line = line.strip(' ').replace('\r', '').replace('\n', '') new_line = re.sub(r'[^a-zA-Z0-9_$]', '_', line) i = 0 addr = GetMethodFromAddr(ea) ret = idc.MakeNameEx(addr, str(new_line), SN_NOWARN) while ret == 0 and i < 5: # failed new_line_rand = new_line + '_' + str(random.randint(0, 99999)) ret = idc.MakeNameEx(addr, str(new_line_rand), SN_NOWARN) idc.MakeComm(ea, str(line)) i = i + 1 ea = IncreaseAddr(ea) file.close()
def PrintMsrTable(self, msr_code, function_ea, inst_ea): mnemonic = idc.GetMnem(inst_ea) call_addr = self.GetJumpAddr(inst_ea, function_ea) function_name = idc.GetFunctionName(function_ea) + '+' + call_addr dwSize = 30 - len(function_name) delimeter = " " * dwSize if (msr_code == None): msr_code_hex = 'Not imm value' else: msr_code_hex = self.NormalizeHexValue(msr_code) if (msr_code == None): msr_name = msr_code_hex else: msr_name = msr_list.get(int(msr_code_hex, 16)) idc.MakeComm(inst_ea, '{}({})'.format(mnemonic, msr_name)) idc.SetColor(inst_ea, idc.CIC_ITEM, 0xf8abef) msr_name_delimeter = (" " * (15 - len(msr_code_hex))) print '{}{}| {} | {} {} | {}'.format(function_name, delimeter, mnemonic, msr_code_hex, msr_name_delimeter, msr_name)
def main(doAllFuncs=True): #doAllFuncs=False #jayutils.configLogger('', logging.DEBUG) jayutils.configLogger('', logging.INFO) logger = jayutils.getLogger('stackstrings') logger.debug('Starting up now') filePath = jayutils.getInputFilepath() if filePath is None: self.logger.info('No input file provided. Stopping') return vw = jayutils.loadWorkspace(filePath) ea = idc.ScreenEA() res = idc.AskYN(0, 'Use basic-block local aggregator') if res == -1: print 'User canceled' return uselocalagg = (res == 1) ranges = getFuncRanges(ea, doAllFuncs) for funcStart, funcEnd in ranges: try: logger.debug('Starting on function: 0x%x', funcStart) stringList = runStrings(vw, funcStart, uselocalagg) for node, string in stringList: if isLikelyFalsePositiveString(string): #if it's very likely a FP, skip annotating continue print '0x%08x: %s' % (node[0], string) #print '0x%08x: 0x%08x: %s %s' % (node[0], node[1], binascii.hexlify(string), string) idc.MakeComm(node[0], string.strip()) except Exception, err: logger.exception('Error during parse: %s', str(err))
def add_comment(cfunc, s, ea): idc.MakeComm(ea, s) tl = idaapi.treeloc_t() tl.ea = ea tl.itp = idaapi.ITP_SEMI cfunc.set_user_cmt(tl, s) cfunc.save_user_cmts()
def treat_element(): "Display an element" global graphs, comments, sol_nb, settings, addr, ir_arch try: graph = graphs.next() except StopIteration: comments = {} print "Done: %d solutions" % (sol_nb) return sol_nb += 1 print "Get graph number %02d" % sol_nb filename = os.path.join(tempfile.gettempdir(), "solution_0x%08x_%02d.dot" % (addr, sol_nb)) print "Dump the graph to %s" % filename open(filename, "w").write(graph.graph.dot()) for node in graph.relevant_nodes: try: offset = ir_arch.blocks[node.label].irs[node.line_nb].instr.offset except IndexError: print "Unable to highlight %s" % node continue comments[offset] = comments.get(offset, []) + [node.element] idc.SetColor(offset, idc.CIC_ITEM, settings.color) if graph.has_loop: print 'Graph has dependency loop: symbolic execution is inexact' else: print "Possible value: %s" % graph.emul().values()[0] for offset, elements in comments.iteritems(): idc.MakeComm(offset, ", ".join(map(str, elements)))
def createUserTypeStruct(self, addr, name, size, self_size): fields = [] sid = idc.GetStrucIdByName("structField") sz = idc.GetStrucSize(sid) sid_type = idc.GetStrucIdByName("type") fields = [] curr_offset = 0 idc.MakeComm(addr, name) for i in xrange(size): fieldname = self.nameFromOffset( self.getPtr(sid, addr + i * sz, "Name")) type_addr = self.getPtr(sid, addr + i * sz, "typ") typename = self.getType(type_addr) size = self.getPtr(sid_type, type_addr, "size") if fieldname == "" or fieldname is None: fieldname = "unused_" + Utils.id_generator() offset = self.getStructFieldOffset(sid, addr + i * sz) if offset != curr_offset: print "Offset missmatch.Got %d expected %d. Adding padding..." % ( curr_offset, offset) if offset < curr_offset: raise ("Too many bytes already") while offset != curr_offset: fields.append(("padding", "char")) curr_offset += 1 curr_offset += size if size != 0: offset_kind = idc.GetMemberOffset(sid_type, "kind") kind_of_type = self.getKindEnumName(type_addr) print kind_of_type if kind_of_type == "STRUCT_": #Disabled for now name_type = self.getName(type_addr) while name_type[0] == "*": name_type = name_type[1:] name_type = Utils.relaxName(name_type) name_type = "ut_" + name_type #print "setting type %s" % name_type fields.append((fieldname, name_type)) elif kind_of_type == "STRING": fields.append((fieldname, "string")) elif kind_of_type == "SLICE": fields.append((fieldname, "slice")) elif kind_of_type == "INTERFACE": fields.append((fieldname, "__iface")) else: fields.append((fieldname, "char [%d]" % size)) if curr_offset != self_size: print "%x: Structure size mismatch: %x" % (addr, curr_offset) if self_size < curr_offset: raise ("Too many bytes already") while self_size != curr_offset: fields.append(("padding", "char")) curr_offset += 1 new_type = [(name, fields)] self.settings.structCreator.createTypes(new_type) new_type_sid = idc.GetStrucIdByName(name) sz = idc.GetStrucSize(new_type_sid) if sz != self_size: print "%x" % addr raise ("Error at creating structure")
def processIMethods(self, offst, size): sz = idc.GetStrucSize(idc.GetStrucIdByName("imethod")) comm = [] for i in xrange(size): comm.append(self.processIMethod(offst + i * sz)) idc.MakeComm(offst, "\n".join(comm)) return comm
def revise_syscall(rename=False): if not rename: print( 'Change the function name with `CGCHeler.revise_syscall(True)`.' ) # visit all instructions start_ea, end_ea = utils.get_seg_range('.text') eax = -1 ip = start_ea while ip < end_ea and ip != idaapi.BADADDR: if 'int' in idc.GetMnem(ip) and '80h' == idc.GetOpnd(ip, 0): if eax != -1: # fix comment and function name print('{}: {}'.format(hex(ip), syscall_table[eax])) idc.MakeComm(ip, 'CGC syscall: {}'.format(syscall_table[eax])) if rename: print('Change {} to {}'.format(idc.GetFunctionName(ip), syscall_table[eax])) idc.MakeName( idc.GetFunctionAttr(ip, idc.FUNCATTR_START), syscall_table[eax]) elif 'mov' in idc.GetMnem(ip) and 'eax' == idc.GetOpnd( ip, 0) and 5 == idc.GetOpType(ip, 1): value = idc.GetOpnd(ip, 1) if re.search('^[0-9]+$', value) != None: eax = int(value) if eax > 7 or eax < 1: eax = -1 ip = idc.NextHead(ip)
def add_arg_descr(function, segment_ea, arg_description_format): """ Name address in added segment annotated with argument descriptions. Arguments: function -- function object segment_ea -- start looking for empty byte to annotate from this ea Return: next possible free address to add information to """ # No arguments if len(function.arguments) == 0: return segment_ea for argument in function.arguments: try: free_ea = get_segment_end_ea(segment_ea) except FailedToExpandSegmentException as e: raise e fields = { "function_name": function.name, "function_dll": function.dll, "argument_name": argument.name, } name = arg_description_format.format(**fields).encode('utf-8') if not name_exists(name): g_logger.debug(' Adding name {} at {}'.format(name, hex(free_ea))) idaapi.set_name(free_ea, name) description = argument.description[:MAX_ARG_DESCR_LEN] idc.MakeComm(free_ea, format_comment(description)) else: g_logger.debug(' Name %s already exists' % name) return (free_ea + 1)
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 markupLine(self, loc, sym): comm = '%s!%s' % (sym.libName, sym.symbolName) logger.debug("Making comment @ 0x%08x: %s", loc, comm) if using_ida7api: idc.set_cmt(loc, str(comm), False) else: idc.MakeComm(loc, str(comm))
def handle_offset(self, offset): #Check if we already parse this if offset in self.type_addr: return print "Processing: %x" % offset self.type_addr.append(offset) #Set type and get name idc.SetType(offset, "type") name = self.getName(offset) idc.MakeComm(offset, name) #get kind name kind_name = self.getKindEnumName(offset) print kind_name if name[0] == "*" and kind_name != "PTR": name = name[1:] name = Utils.relaxName(name) Utils.rename(offset, name) self.betterTypePlease(offset) sid = idc.GetStrucIdByName("type") addr = self.getPtrToThis(sid, offset) if addr != 0: addr = self.getOffset(addr) self.handle_offset(addr) return if kind_name != "FUNC": self.processUncommon(sid, offset)
def clean_lines(): "Remove previous comments" global comments for offset in comments: idc.SetColor(offset, idc.CIC_ITEM, 0xffffff) idc.MakeComm(offset, "") comments = {}
def append_comment(ea, s, repeatable=False): """ add the given string as a (possibly repeating) comment to the given address. does not add the comment if it already exists. adds the comment on its own line. Args: ea (int): the address at which to add the comment. s (str): the comment text. repeatable (bool): if True, set a repeatable comment. Raises: UnicodeEncodeError: if the given string is not ascii. """ # see: http://blogs.norman.com/2011/security-research/improving-ida-analysis-of-x64-exception-handling s = s.encode("ascii") if repeatable: string = idc.RptCmt(ea) else: string = idc.Comment(ea) if not string: string = s # no existing comment else: if s in string: # ignore duplicates return string = string + "\\n" + s if repeatable: idc.MakeRptCmt(ea, string) else: idc.MakeComm(ea, string)
def dispatch(self, ea, mnem, ops): cond = '' if (mnem.startswith('LDR') or mnem.startswith('STR')) and len(mnem) == 6: mnem, size = mnem[:-1], mnem[-1] else: size = None for suffix in self.suffixMap: if mnem.endswith(suffix): tempmnem = mnem[:-len(suffix)] if not self.findHandler(tempmnem, nonCmp=True): continue mnem = tempmnem if self.cmp: cond = '%s %s %s' % (self.cmp[0], self.suffixMap[suffix], self.cmp[1]) cond = 'if(%s) ' % ' && '.join(self.cmp[2] + [cond]) break if size: mnem += size handler = self.findHandler(mnem) if handler != None: out = handler(mnem, ops) if out != None and out != False: #idc.MakeComm(ea, cond + out) idc.MakeComm(ea, '') else: pass # print 'Unhandled instruction:', mnem, ', '.join(ops)
def MakeComm(self, address, comment): """ MakeComm(int addr, string comment) => None Add a comment to the current IDB at the location `address`. Example: ida MakeComm 0x40000 "Important call here!" """ addr = long(address, 16) if ishex(address) else long(address) return idc.MakeComm(addr, comment)