Log in

View Full Version : Log any DRX Access - srcs now available


[yAtEs]
September 21st, 2003, 01:49
some of you maybe interested in my latest source code on my
site,

http://www.yates2k.net/syscode.htm

I'll paste the readme here


This is a fully working example of using Intels GD(General Detection) bit,
to invoke debug exceptions upon any access to a debug register.

Currently, the provided source will lock down any drx access to only
NTICE, a hardcoded base for my NTICE is in the src, you may need to
modify this for you own, search the source for the keyword ACCESS_RIGHTS.

Any attempt of a MOV REG, DRX will be 'faked' by placing a default value
into the reg to fool the calling app into thinking no BPMs are set.
Any attempt of a MOV DRX, REG will be totally ignored, or emulated if
NTICE is the caller.

All output is given via debug msgs which have been formatted to be read
by sysinternals debugview(included) with force linefeed on.

Example data below:


-- I SET MY BPM TO CATCH CODE WRITTING --

00000548 1.99602408 Alert: MOV DR3, ESI ADDR: B666917B
00000549 1.99604000 004010DC < - contents of esi
00000550 1.99604894 DRX Updated

00000551 1.99606207 Alert: MOV DR7, EBX ADDR: B666917E
00000552 1.99607911 100004C0
00000553 1.99608777 DRX Updated

--- ASPROTECT SEH TRIES TO OVERWRITE, KERNEL IS DENIED ----


00000557 6.80938862 Alert: MOV DR0, ESI ADDR: 80465362
00000558 6.80940343 00000000
00000559 6.80941293 [o] Ignored MOV DRX, REG

00000560 6.80943025 Alert: MOV DR1, EDI ADDR: 80465368
00000561 6.80944506 00000000
00000562 6.80945427 [o] Ignored MOV DRX, REG

00000563 6.80947159 Alert: MOV DR2, EBX ADDR: 8046536B
00000564 6.80948640 00000000
00000565 6.80949590 [o] Ignored MOV DRX, REG

00000566 6.80951182 Alert: MOV DR3, ESI ADDR: 80465377
00000567 6.80952775 00000000
00000568 6.80953725 [o] Ignored MOV DRX, REG

00000569 6.80955317 Alert: MOV DR6, EDI ADDR: 8046537A
00000570 6.80956965 0000A005
00000571 6.80957915 [o] Ignored MOV DRX, REG

00000572 6.80959535 Alert: MOV DR7, EBX ADDR: 8046537D
00000573 6.80961156 00000155
00000574 6.80962133 [o] Ignored MOV DRX, REG

***************************

--- Running a SafeDisc EXE -------

Me setting a BPM, NTICE in action

00000566 3.91877124 Alert: MOV DR3, ESI ADDR: B666917B
00000567 3.91878856 00405273
00000568 3.91879750 DRX Updated

00000569 3.91881063 Alert: MOV DR7, EBX ADDR: B666917E
00000570 3.91882655 100004C0
00000571 3.91883522 DRX Updated

---

some memory doing checks, turns out to be SECDRV safediscs driver
drx requests are faked.

00000932 9.08994774 Alert: MOV EAX, DR1 ADDR: B707593A
00000933 9.08998239 00000000
00000934 9.08999216 [o] Faked MOV REG, DRX

00000935 9.09002122 Alert: MOV EAX, DR7 ADDR: B7075950
00000936 9.09003658 00000400 <- fake value placed in reg
00000937 9.09004608 [o] Faked MOV REG, DRX

00001154 9.60005839 Alert: MOV EAX, DR7 ADDR: B70759DA
00001155 9.60010811 00000400
00001156 9.60011817 [o] Faked MOV REG, DRX

00001157 9.60336942 Alert: MOV EAX, DR7 ADDR: B70759DA
00001158 9.60341161 00000400
00001159 9.60342138 [o] Faked MOV REG, DRX

00001160 9.61938878 Alert: MOV EAX, DR7 ADDR: B70759DA
00001161 9.61943180 00000400
00001162 9.61944716 [o] Faked MOV REG, DRX

00001163 9.62103089 Alert: MOV EAX, DR7 ADDR: B70759DA
00001164 9.62106245 00000400
00001165 9.62107279 [o] Faked MOV REG, DRX

--

and for interest heres ntice operating my bc* request

00000575 8.94788583 Alert: MOV ECX, DR7 ADDR: B66691C4
00000576 8.94790343 100004C0
00000577 8.94791321 [o] Emulated MOV REG, DRX

00000578 8.94792914 Alert: MOV DR7, ECX ADDR: B66691C9
00000579 8.94794478 10000400
00000580 8.94795344 DRX Updated


comments, bug reports to yates@reverse-engineering.info

dELTA
September 21st, 2003, 07:50
Hehe, very nice!

nikolatesla20
September 26th, 2003, 13:22
Excellent. I was wondering why nobody had ever tried using the General Detection flag before, since it IS there

Good work and thanks for sharing

-nt20

volodya
September 27th, 2003, 00:51
BTW, guys, I have one funny question due to the point.
Dr. Golova showed you the NtContinue trick (if someone needs I can share pseudocode for NtContinue which I disassembled from ntoskrnl) and, basically, with the help of [yAtEs]'s tools and NtContinue trick it is not that hard to destroy ANY application that will fill DR-registers with garbage... But I can't imagine for now how one can protect from the application that USES DR-regs, e.g. for tracing itself... May be some restoring... Detecting access to DR, saving the value, restoring it back in sometime... Your ideas if any?

evaluator
September 27th, 2003, 03:15
to NT20,

this flag (as describied in manuals) is mostly for emulation-system use.
it is not big matter using for restrict change via SEH.

& always remember, there is 2 kind SEH use:
1. passive (as in asspr), when it just tries clear DRx.
2. active (as in telock), when it setups DRx for real break.
(3. fake values for not break, but for checking in next seh)

volodya
September 27th, 2003, 21:40
What to do in this case?

evaluator
September 28th, 2003, 04:51
for "active" case there is no way for blocking.
Either DRx will be setuped for break or there will NO-break.

This case in fact shows weakness of SEH-blocking method.
BUT in other hand, I not meet "active" method in most protectors.

So, seems, "active" method is not much correct!?

okey, I can imagine only following fact against "active" method:

W9x(at least my W98SE) Kernel NOT DIVIDES DRx context for processes.
So DRx setuped in one process is global & CAN cause break-crash in
other process, if accidentally will executed same address.
(Winice probably checks process-thread for own DRx..)

In W2k-XP systems Kernel DIVIDES DRx context, so here no prob.
(curious: NTICE breaks this enhansements!)

nikolatesla20
September 28th, 2003, 10:08
All you really need to do the, is if the active doesn't set up a "real" break, but only for checking values, is to emulate the instructions, and keep an internal table of DR's to Processes in your own driver.

For example, when TeLock tries to set a DR register, we catch it and set up an internal variable instead to emulate that it worked. When the same process again tries to read the register, simply return the value stored in the variable.

Not sure if this method would work for real breakpoints or not, but suspecting it might since it would emulate for the process...(including kernel32, etc)

is this perhaps a workable idea?

-nt20

volodya
September 28th, 2003, 12:12
evaluator, thanks for the explanation!
nikolatesla20, I'll talk to Sten, perhaps it may be possible to implement sth like this in NT+ due to context specific nature of DR-regs there

volodya
October 2nd, 2003, 09:53
nikolatesla20

seems like in general case it is impossible to do sth
Yes, indeed, we can emulate the content of DR-regs, but we cannot make the program to BREAK on it. It is the hardware feature....

[yAtEs]
October 2nd, 2003, 12:00
Quote:
[Originally Posted by vladimir]nikolatesla20

seems like in general case it is impossible to do sth
Yes, indeed, we can emulate the content of DR-regs, but we cannot make the program to BREAK on it. It is the hardware feature....



nothing generically is really possible, you can always program things to help
you find checks etc, using internals vars as nt20 said to keep a constant
set of drx free for ur own bpms is fine apart from the if the program is
checking to make sure its bpm is called then it wont work, or maybe it
will just read drx later to make they are still there, then ur ok, if it only does
one breakpoint, your handler could mov it to dr3 then just use 0->2 for ur
own bpms, if the handler is just a simpler handler which counts then you can
fake the bpms by changing dr6 to say a certain bpm has occured and passing
it off to the original int 1 handler, or hm you can simply debugger the handlers

either way, having simple access reports will help debug a protection at least


yates.

volodya
October 2nd, 2003, 12:27
Quote:
[Originally Posted by '[yAtEs]']

either way, having simple access reports will help debug a protection at least

yates.


Yes, you are right. I've played with your driver. It is pretty nice. The only thing I wish it would have is it can watch for SPECIFIC thread only. I don't need complete system report. It contains to many unneccessary information for me, but for the specific thread it would be fine.