For those who are interested in IDA Pro/idapython, here is a “mystery” I found myself getting stuck. Consider the following snippet for a .idb of a sizeable binary (e.g. user32.dll):
f = idaapi.get_func(idc.here()) print f.startEA for x in idautils.Heads(): idaapi.get_func(x) print f.startEA
The output will be something like this:
Different addresses?! Mind-blowing!! (Of course, ignorance is the #1 reason for getting mind-blown.) Now for the reason behind this phenomenon, from idapython project site:
What happens is that the returned
func_t*points inside the internal cache of
func_tobjects, and as you do more
get_func()calls eventually that cache slot gets replaced by another function.
So instead of the code above, we can replace with the following using helper class
f = idaapi.get_func(idc.here()) print f.startEA flock = idaapi.lock_func(f) # lock the pointer for x in idautils.Heads(): idaapi.get_func(x) print f.startEA flock = None # don't need it anymore, free the lock
In short, excessive use of idapython
idaapi.get_func() inside IDA Pro should be complemented with helper class
idaapi.lock_func unless you are fine with references changing under your nose (a.k.a. without warning).