Point to note when using idapython get_func()

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:

2024480284
2024989954

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_t objects, 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 lock_func:

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).

 

On-Line IDA Python Plugin manual: idaapi.lock_func

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s