PDA

View Full Version : Tracing Over System Calls In OllyDbg


Ring3 Circus
04-13-2008, 10:22 PM
Things have been quiet over here since installing Life 2.0, so to start warming things up again I present a simple trick to counter a frustrating problem. This isn’t particularly clever, but it didn’t occur to me first few times ’round so maybe it will save some newbies a little time.

How many times have you attempted a run-trace in Olly with a break-condition set, only to find that the break never occurs and you have to start over? It happens to me all the time, and it’s usually my fault. But sometimes the cause isn’t a poorly thought-out condition, but the presence of a system call during the trace. Being a lowly ring3 process, OllyDbg doesn’t have permission to follow the CPU’s execution of your program into kernel space, so when it encounters a SYSCALL, SYSENTER, or CALL/JMP FAR out of the debuggee’s address-space, no choice remains other than to let the process run away and hope it comes back. As we’ve established, this doesn’t always happen.

Now, the most commonly encountered system calls are those in ntdll, but these pose no problem to us. Set ‘Always trace over system DLLs’ in Olly’s ‘Trace’ options and you’ll never need to trace over such an instruction directly. (If this still isn’t working for you, be sure to ‘Mark [ntdll] as system DLL’ in the ‘Executable modules’ dialog). But if you play with some nastier targets, such kernel transitions will occur in modules you need the trace data for.

Olly intrinsically supports three modes of tracing (although it doesn’t give you much control over which it uses): hardware breakpoints, software breakpoints and execution trapping (using the EFlags ‘trap bit’. Unfortunately, given the way Windows implements its kernel transitions, we can’t use any of these to our advantage. Arguments are passed to these system calls via the general-purpose registers, rather than by the stack-frame system we’re all used to, and moreover the return address isn’t always that of the instruction following the system call. Hence without complete knowledge of these ‘fastcall’ specifications, there’s no way to be sure where user-mode execution will resume, and so we’re at a loss when it comes to placing the next breakpoint. For this reason, there is no one-size-fits-all solution that I’m aware of, but it is possible to clean up this little mess on a per-case basis with only minimal effort.

Take a look at the run trace produced by your failed run. It’s probably a lot shorter than you expected, with its dying instructions indicating an upcoming transition to ring0. Scroll up a little and work out a location where execution is very likely to pass through shortly after ring3 execution resumes. This doesn’t need to be the actual return address, but ideally something that follows soon after. Usually, the saved return-address belonging to the function at the top of the call stack does a good job. Our goal is to trap execution at this point and resume the trace. Of course, we could do this manually by placing a breakpoint and keeping our fingers on ctrl-F11, but that’s the dumb way. The last piece of the puzzle is to make OllyDbg automate this for us: employ a conditional breakpoint, with an impossible condition (say, 1 == 2). Now our trace executes over the system call flawlessly without the need for us to lift a finger.



http://www.ring3circus.com/rce/tracing-over-system-calls-in-ollydbg/

dELTA
04-14-2008, 04:11 AM
Nice trick Admiral. And what's with the Life 2.0, new girlfriend or child?

Admiral
04-14-2008, 02:34 PM
Nothing quite so glamorous, I'm afraid. I just hit the two-month mark of a new job in a new town. I'm new to the world of security but really enjoying it and embracing the opportunity to push my RCE skills to their absolute limit. It also gives me plenty of ideas and material to write about, if I can only find the time .

blabberer
04-17-2008, 01:40 PM
well ollydbg provides a native way to do this

rightclick -> runtrace -> skip selection when tracing

now you might ask what to skip

right click ->search for ->sequence of commands

Code:

mov edx,7ffe0300 <--- standard signature for calls that go through syscall interface
call edx


then comes some long manual process which you can automate with a simple plugin
hint
undocumented FindAllSequences() api and documented ModifyHitTrace (..,..,ATR_RTSKIP) in all modules at one go

the manual process is keep hitting ctrl+l and then right clicking -> run trace -> skip selection from runtrace on every sequence
in say user32.dll, advapi32.dll,gdi32.dll,and ntdll.dll (only system modules that have syscall calls )
ollydbg will happily ignore all those syscalls and simply turn back to executing runtrace on retn #n in all these

like you can see here ollydbg has skipped ZwQuerySystemInformation Syscall in this runtrace log

Code:

77E784AE Main MOV EBP,ESP EBP=0012FEE0
77E784B0 Main SUB ESP,18C
77E784B6 Main PUSH EBX
77E784B7 Main PUSH ESI
77E784B8 Main PUSH EDI
77E784B9 Main XOR EDI,EDI EDI=00000000
77E784BB Main PUSH EDI pReqsize = NULL
77E784BC Main PUSH 138 Bufsize = 138 (312.)
77E784C1 Main LEA EAX,DWORD PTR SS:[EBP-18C] EAX=0012FD54
77E784C7 Main PUSH EAX Buffer = 0012FD54
77E784C8 Main PUSH 2 InfoType = SystemPerformanceInfo
77E784CA Main CALL DWORD PTR DS:[<&ntdll.NtQuerySystemInformation>]
ZwQuerySystemInformation Main MOV EAX,0AD EAX=000000AD
77F76157 Main MOV EDX,7FFE0300 EAX=00000000, ECX=0012FD30, EDX=7FFE0304
77F7615E Main RETN 10
End of gathered information, live log begins

Admiral
04-17-2008, 06:00 PM
Great stuff, blabberer .

LaBBa
06-04-2008, 01:51 AM
Hi
i try to use your explanation :
"Scroll up a little and work out a location where execution is very likely to pass through shortly after ring3 execution resumes"

i don't get it ... what do you mean ? can you show an example of code that you do this ?
blabberer : Is there a plug that already doing this ?