Log in

View Full Version : Debugging and tracer.


nikolatesla20
April 16th, 2002, 10:13
Just a couple quick questions here.

Okie, I've been reading some of the threads about Revirgin, and about ImpREC. What I am wondering is I read Revirgin uses Ring0 tracer I believe. SO first my question is how? I mean doesn't a ring 0 need to be a system driver? Or is the program (perhaps in a dll) somehow making a transition to ring 0 ?

If this is so, how is something like that done, and how safe is it.

Going further, I notice that programs like OllyDbg say they use only Win32 APIS for debugging - and it has a tracer built in. From what I know of the API for debugging, couldn't the app just check IsDebuggerPresent() and kick you in the *nuts*

The reason I am interested is because of the new OEPFinder tool, I thought perhaps we could add a basic tracer to it, that can start the target and simply watch the EIP register and when it hits the OEP jump point, it can log the eax register (or maybe even script it what to log for example), so now you have the real oep.

What I want to know for sure is, is it only possible to get to the register values of a process thru debugging it?

And how does a ring0 tracer like Revirgin actually work - I only see two dll's..is there something else fancy going on (I'm not a driver programmer, I think I will ask the driver guys a work some questions today )

I see on Win32 you can get a handle to a current thread with OpenThread() and then you can get the registers I think with GetThreadContext() but of course you have to call SuspendThread first and it says these functions supposedly work even when not debugging a process...hmmmm.



Thanks for hearing my rant !

-nt20

foxthree
April 16th, 2002, 11:00
Hi Tesla:

Glad to note that you're thinking along my lines. Actually, this thought stuck me a while ago. Before I begin, I'll attempt to answer your questions first:

(Q) Does RV use a Ring-0 tracer?
(A) Yes. The Trace in RV is an implementation of /tracex from TheOwl's ICEDump (albeit without integrating with SoftICE).

(Q) Does Ring-0 needs to be system driver?
(A) Yes and No. Yes, if you need to perform a "lot" of low-level stuff. No if you only need to peek at a thread' register set and set the DRx and stuff link that. (I mean GetThreadContext and SetThreadContext). RV uses a system driver called "rvtracer.sys". You must see this in the same directory as RV.

(Q) IsDebuggerPresent trick...
(A) OllyDbg and a lot of others feature a "ring-3" tracer. i.e. a Tracer that runs in user mode. Tracers' like this can be easily screwed with a "lot" of standard anti-tracing techniques (like IsDebuggerPresent and so many others). Look at my post on Anti-Tracing/Anti-Debug techniques. However, a ring-0 tracer - if coded well - can easily by pass all anti-trace techniques.

Contd...

Signed,
-- FoxThree

foxthree
April 16th, 2002, 11:06
In continuation with my previous post, for OEPFinder I actually thought of writing a tracer however it can be easily fooled unless it is a ring-0 tracer and I'm still not at that level of coding Writing a ring-0 tracer is quite a difficult task (unless you know your asm/Intel basics extremely well) as is evident by looking at the ICEDump source code.

Notice, that writing a tracer is in *NO WAY* a new idea as I've always admired the way it was done in ProcDump. An "automatic" unpacker with scripting capabilities... What more could ask for at that time? However, notice how that is kicked in the balls now-a-days by many packers...

As for debugging support, there is a lot of information to be done in the MSDN. Look for DebugActiveProcess and WaitForDebugEvent APIs and they'll show you how deep the rabbit hole goes

All in all, I've summarized my entire Protected Mode Intel knowledge in this two posts. (which reminds me, i hold just a drop of water from a vast ocean).

Maybe my posts wouldn't have helped your questions, but these are just my research findings and I thought I'd share it with fellow RCEs.

Which reminds me, Hey +Tsehp, why don't we integrate OEPFinder's Signature tactics to RV to make OEP finding a bit more "automagic". Just my thoughts...

Signed,
-- FoxThree

PS: Folks, if I've made any mistakes, feel free to correct it. That's how I learn. Thanks

crUsAdEr
April 16th, 2002, 12:34
All roads lead to Rome?

Hmm, somehow that is what i've been researching... somekind of tracer to unpack packed program... just planning to write a simple unpacker as practise... and a ring-3 tracer is such a good idea...

Yeah I know that the program can detect tracer and hence kick our butts, but if we know how our tracer is detected, then we can code our tracer in such a way that it will detect the trick and then patch the program appripriately? I have been wondering along this line, and i find it highly feasible... of course presuming that the target if on ring3 as well..

Maybe some of the resident guru can shine some light?

Thanx,

nikolatesla20
April 16th, 2002, 13:06
Yes, I was going thru the MSDN stuff at 4 this morning. (couldn't sleep, too hot up here now all of a sudden)

Yep, noticed all the basic debugging functions and stuff.

The thing is yes you can trick tracers supposedly, but we are not tracing for what revirgin is, I mean RV has a tracer.dll for resolving imports, this can be fooled - we would simply be looking for the signature byte to be executed.

Of course, maybe you could add this to RV as some sort of plugin ? I mean Tseph already has an actual prog tracer in it now too. I did try using it in this manner before, by putting in the range, I don't remember if it worked or not tho. And even so, it won't land you on the OEP, just right before it. If it reported the EAX register you would see it. (In this signature byte case that is).

So RV would need two more things: A "search for signature" button, and then a result window for registers you want to watch such as EAX.

Actually, I mean the tracer in RV is so fast on Win2K tho, (but I had it crashing yesterday !!!!!!) that you can usually find all the dips and end up on the OEP pretty quick. But using the sig byte you will know FOR SURE that this is the OEP and not a DIP. Sometimes it can be tough to know for sure, for newbies anyway.

But in either case it is good coding practice anyway, I think. Good learning. The guys that wrote icedump had to start somewhere...and Tseph had to start somewhere. Methinks Tseph is perhaps a device driver coder at some company out there ?? (Or in the upper levels of Soft Eng. department..)

-nt20

nikolatesla20
April 16th, 2002, 14:22
Actually, that call to IsDebuggerPresent() - we could probably hook that and return our own value to fake it out.

For example, we could hook any call to GetProcAddress() (obviously we first would need to find the call in the import table, even when it's messed up).

The only real problem with this is our hooked code has to be in the process's memory space, so it must be a DLL on its own, it would need to be injected into the process's space, but the MSDN has some articles on how to do this.

So we watch GetProcAddress() for the name "IsDebuggerPresent" and chain the call (We pass back the result as the address of OUR function ). Well, actually, hook and take over the call Just return a zero That wrapper software Asprotect does stuff like this, and so can WE !

I'm sure someone has tried this before? Maybe this is a small utility I could write IsDebuggerPresent killer...

-nt20

crUsAdEr
April 17th, 2002, 14:28
Yo,

Just tested out the tracer idea last nite... a lame tracer that single steps is REALLY slow.. guess it aint gonna work.... then it dawns upon me... /tracex and revirgin can take like 30 mins to trace to OEP of some program... just it really defeat the purpose of OEP Finder to wait for 30 mins to find out what OEP is...

Just my thoughts for now!

yoda
April 17th, 2002, 15:13
Hey plp...

Just a small note...
I don't really need to hook IsDebuggerPresent+GetProcessAddress to avoid proggies detecting that they are a debuggee.
I think (but haven't tested) that you can modify the windows internal variables which describe whether a process is under debug control or not...

NT: PEB.dwFlags (at PEB[0]) & 00010000
9x: PROCESS_DATABASE.dwFlags (at PROCESS_DATABASE[20])
& 1 (fDebugSingle)

y