def NFuncUp( fun, n ) : i=0 f=fun while ((i<n) and (f!=idc.BADADDR)): f=idc.PrevFunction(f) i=i+1 return f
def getFunc(self, ea=None, next=False): if ea == None: ea = idaapi.get_screen_ea() if next: ea = idc.NextFunction(ea) if ea == -1: return (0xFFFFFFFFL, 0xFFFFFFFFL) if ea < 0: return (0xFFFFFFFFL, 0xFFFFFFFFL) elif idc.GetFunctionName(ea) == idc.GetFunctionName(idc.PrevAddr(ea)): ea = idc.PrevFunction(ea) return (ea, idc.FindFuncEnd(ea))
def get_function_bounds(ea): """Get the bounds of the function containing `ea`. We want to discover jump table targets that are missed by IDA, and it's possible that they aren't marked as being part of the current function, and perhaps are after the assumed range of the current function. Ideally they will fall before the beginning of the next function, though. We need to be pretty careful with the case that one function tail-calls another. IDA will sometimes treat the end of the tail-called function (e.g. a thunk) as if it is the end of the caller. For this reason, we start with loose bounds using the prev/next functions, then try to narrow with the bounds of the function containing `ea`. TODO(pag): Handle discontinuous regions (e.g. because of function chunks). It may be worth to return an object here that can we queried for membership using the `__in__` method. """ seg_start, seg_end = idc.SegStart(ea), idc.SegEnd(ea) min_ea = seg_start max_ea = seg_end if is_invalid_ea(min_ea) or not is_code(ea): return ea, ea # Get an upper bound using the next function. next_func_ea = idc.NextFunction(ea) if not is_invalid_ea(next_func_ea): max_ea = min(next_func_ea, max_ea) # Get a lower bound using the previous function. prev_func_ea = idc.PrevFunction(ea) if not is_invalid_ea(prev_func_ea): min_ea = max(min_ea, prev_func_ea) prev_func = idaapi.get_func(prev_func_ea) if prev_func and prev_func.endEA < ea: min_ea = max(min_ea, prev_func.endEA) # Try to tighten the bounds using the function containing `ea`. func = idaapi.get_func(ea) if func: min_ea = max(min_ea, func.startEA) max_ea = min(max_ea, func.endEA) return min_ea, max_ea
def hasPrecedingFunction(ea): return False if isBad(ea) else not isBad(idc.PrevFunction(ea))
def getPreviousFunction(ea): return idc.PrevFunction(ea)
def ProgramAddrRange() : return idc.PrevFunction(idc.BADADDR) - idc.NextFunction(0)
def analyze(cu): objc_meth_map = {} methnamebegin = 0 methnameend = 0 forbitmeth = [ "alloc", "allocWithZone:", "allowsWeakReference", "autorelease", "class", "conformsToProtocol:", "copy", "copyWithZone:", "dealloc", "debugDescription", "description", "doesNotRecognizeSelector:", "finalize", "forwardingTargetForSelector:", "forwardInvocation:", "hash", "init", "initialize", "instanceMethodForSelector:" "instanceMethodSignatureForSelector:", "instancesRespondToSelector:", "isEqual", "isKindOfClass:", "isMemberOfClass:", "isProxy", "isSubclassOfClass:", "load", "methodForSelector:", "methodSignatureForSelector:", "mutableCopy", "mutableCopyWithZone:", "performSelector:", "performSelector:withObject:", "performSelector:withObject:withObject:", "respondsToSelector:", "release", "resolveClassMethod:", "resolveInstanceMethod:", "retain", "retainCount", "retainWeakReference", "superclass", "zone", ".cxx_construct", ".cxx_destruct", ] # find the segment which contains objc method names curseg = idc.FirstSeg() while curseg != 0xffffffff: if "__objc_methname" == idc.SegName(curseg): methnamebegin = idc.SegStart(curseg) methnameend = idc.SegEnd(curseg) break curseg = idc.NextSeg(curseg) # get objc method names if methnamebegin != 0: while methnamebegin < methnameend: funcname = idc.GetString(methnamebegin) objc_meth_map[funcname] = methnamebegin methnamebegin = methnamebegin + len(funcname) + 1 # get objc func table funcmap = {} addr = idc.PrevFunction(-1) while addr != 0xffffffff: curname = idc.GetFunctionName(addr) if -1 != curname.find('['): curname = curname.replace("[", "").replace("]", "") curname = curname.split(" ")[1] # may be more than one function with same sel but differenct class if curname not in funcmap: funcmap[curname] = [] funcmap[curname].append(addr) addr = idc.PrevFunction(addr) # make xref result = [] indx = 0 for (k, v) in objc_meth_map.items(): # find corresponding func addr if k in funcmap and k not in forbitmeth: farr = funcmap[k] # find xref to code and make xref for each curref = idc.DfirstB(v) while curref != 0xffffffff: for f in farr: cu.execute('insert into xref values (?,?,?,?,?)', [indx, curref, f, v, k]) indx += 1 curref = idc.DnextB(v, curref) return result
print "FuncName:%s,Start:0x%x,End:0x%x" % (idc.GetFunctionName( func.startEA), func.startEA, func.endEA) #获取指定地址所在函数的起始地址和结束地址 方式2 print "Start:0x%x,End:0x%x" % (idc.GetFunctionAttr( 0x10003F3BD, FUNCATTR_START), idc.GetFunctionAttr(0x10003F3BD, FUNCATTR_END)) #查看类有哪些属性 dir(func) #获取类型 type(func) #获取指定地址所在函数的前一个函数的起始地址 func = idc.PrevFunction(0x10000646D) print idc.GetFunctionName(func), hex(func) #获取指定地址所在函数的后一个函数的起始地址 func = idc.NextFunction(0x10000646D) print idc.GetFunctionName(func), hex(func) #获取下一条指令的地址 idc.NextHead() #遍历某个地址所在函数的所有指令 ea = here() start = idc.GetFunctionAttr(ea, FUNCATTR_START) end = idc.GetFunctionAttr(ea, FUNCATTR_END) cur_addr = start