# another EnableTracing() bug

looks like IDA Pro 5.3 has another bug. EnableTracing()/GetDebuggerEvent(WFNE_ANY, -1); returns 10h (BREAKPOINT) on function calls thanks to internal IDA-Pro breakpoints. IDA-Pro sets breakpoints after calls to perform step over tracing (TRACE_FUNC). Soft-Ice and OllyDbg do the same thing. the problem is – EnableTracing() does it every time, even we ask it for TRACE_STEP or TRACE_INSN. IDA-Pro should hide internal breakpoints, but she forgets to do it!

not good for us! well, how we’re going to handle this? um, r_eip = GetEventEa() points to the next instruction after the call and GetBptAttr(r_eip, BPTATTR_EA) = = -1, where -1 means no breakpoint here. why? coz, GetBptAttr() hides internal breakpoints, but GetDebuggerEvent() does not. so, it’s definitely a bug. normally, debuggers always hides internal breakpoints – nobody wants to confuse users. well, IDA-Pro does.

another bug: a real breakpoint just freezes IDA-Pro and GetDebuggerEvent(WFNE_ANY, -1) will never return, so we have to specify the second argument (time to wait), calling the function like this: GetDebuggerEvent(WFNE_ANY, 0×3). of course, if GetDebuggerEvent() returns DBG_TIMEOUT we have to check for real breakpoints. if GetBptAttr(r_eip, BPTATTR_EA) = = r_eip it means that a real breakpoint is here. it’s a simple heuristic algorithm, but it works!

I wrote a simple script to demonstrate how to use EnableTracing(). download it and run. the output should look like this:

IDA says breakpoint:
00402CECh:call ds:HeapFree
00402CECh:pop esi

IDA says breakpoint:
00401AC4h:call _calloc
00401AC4h:pop ecx

IDA says breakpoint:
00401067h:call _printf
00401067h:add esp, 10h

4010B0: hit breakpoint
heuristic says breakpoint!

did you see this? IDA-Pro stops at every calls!!! so, the final version of the correct tracer should look like this:

// start tracing
EnableTracing(TRACE_XA, 1);

// wait for any debug even
code = GetDebuggerEvent(WFNE_ANY | WFNE_CONT, MAX_WAIT);

while(1)
{
r_eip = GetEventEa(); // next even eip

if (code == BREAKPOINT) // <<< IDA BUG!!! Message("IDA says breakpoint:\n%08Xh:%s\n%08Xh:%s\n\n", r_eip, GetDisasm(PrevHead(r_eip, 0)), r_eip, GetDisasm(r_eip) ); if (code == DBG_TIMEOUT) // exit due to timeout { // check for breakpoints if (GetBptAttr(r_eip, BPTATTR_EA) == r_eip) // real bp Message("heuristic says breakpoint!\n"); break; } // check for errors if (code < 1) break; // wait for a next event // MAX_WAIT (time to wait, sec) - prevents IDA freezing code = GetDebuggerEvent(WFNE_ANY, MAX_WAIT); }

 

2 Comments

  1. A couple of bugs in just 2 weeks of 2009
    That’s what i called a great way to start a new year. (I’m feeling motivated)

  2. thanks! going to be more bugs here. if had I time to describe them all…

Leave a comment

Comments are closed.