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

Loading symbols in IDA Pro

IDA Pro has included symbol loading facility some time back. But different installations had yield different results; sometimes symbol loading works, sometimes it didn’t. This has led me to scratch my head for an extended period of time until now.

What happened is when IDA ask the following:

IDA Pro has determined that the input file was linked with debug information. Do you want to look for the corresponding PDB file at the local symbol store and the Microsoft Symbol Server?

it made use of its dbghelp.dll and symsrv.dll to load the symbols. We are supposed to accept Microsoft’s terms for using their symbols, but since symsrv.dll is used directly by the plugin the prompt to accept the terms is not displayed, the license cannot be accepted, and hence the symbol loading fails.

The solution is to include an empty symsrv.yes file alongside symsrv.dll in IDA’s directory to indicate that we’d gladly accept the terms that never appear.