Ilfak improved IDA-Pro scripting engine recently. many new functions were added. real gift for all script fans! the only problem is - the lack of documentations. it’s not easy to understand how to use these functions. take EnableTracing() for example. it’s very useful and powerful func, but… the way how it interacts with IDA-Pro debug engine is not trivial and involves GetDebuggerEvent(), GetEventEa() and other functions.

but we’re lucky! Ilfak polished a simple, but a very practicable script shows us how to unpack UPX with EnableTracing(). um, why we do need to trace an upxed program? it’s too slow. better to set hardware breakpoint on [ESP-4] and find the first jump after it. ok, never mind. it’s just EnableTracing() example. whatever.

the truth is - this is an example how do _not_ write scripts. I saw a few scripts based on this example. people just grabbed the code and rewrote it to fit their needs. please, do not do this unless you want to be fucked up. just look at this: http://www.hex-rays.com/idapro/scriptable.htm (the mirror: http://zen-way.org/ffh/unupx.zip)

EnableTracing(TRACE_STEP, 1);
for ( code = GetDebuggerEvent(WFNE_ANY|WFNE_CONT, -1); // resume
code > 0;
code = GetDebuggerEvent(WFNE_ANY, -1) )
{
r_eip = GetEventEa();
if ( r_eip >= tea1 &#038;&#038; r_eip < tea2 ) break;
}
if ( code <= 0 ) return Failed(code);
...
Ilfak does perform a lot of checks, but they are not quite correct and consequences are just terrible. dare to try? well, download http://nezumi-lab.org/ffh/hello_upxed.zip, set breakpoint on 00409CCCh and run Ilfak’ script. IDA-Pro freezes. CTRL-BREAK does not work and we have to kill IDA-Pro process.

why it happens? well, if EnableTracing() meets a breakpoint it stops the process, but the script waits an even - GetDebuggerEvent(WFNE_ANY, -1) which will never happen, coz the process has been stopped.

how to fix the problem? well, it’s easy. just replace “(code > 0)” by “((code > 0) &#038;&#038; (code != BREAKPOINT))” and “if ( r_eip >= tea1 &#038;&#038; r_eip < tea2 ) break;" by "if ( r_eip >= tea1 &#038;&#038; r_eip < tea2 ) { PauseProcess(); ... EnableTracing(TRACE_STEP, 0); break;}". it's still not good, but at least prevents IDA-Pro freezing on breakpoints. btw, don't forget about exceptions! you have to handle them as well.

btw, CTRL-Break does not disable tracing, enabled by EnableTracing(). what’s a… um, a nasty bug! to disable tracing press CTRL-F2.



http://nezumi-lab.org/blog/?p=33