View Full Version : Strange DRx
evaluator
March 20th, 2002, 19:12
Hello, Kayaker!
Hello, guys!
I read in INTEL-manual's "instruction set" about "MOV DRx,r32":
"The instructions must be executed
"at privilege level 0 or in real-address mode.
So why I can execute these instructions in "normal" Ring3 program???
Or I have magic PC!?
JimmyClif
March 20th, 2002, 19:22
I post you japheth's answer on the same question:
in Win9X these ops (mov eax,crx) are "emulated", AFAIK. "Emulated" here means you don't get a GPF, but you also don't get the "real" values of that registers. And of course you cannot set them.
On the contratry opcode "Halt" may be emulated correctly.
No magic in your PC

evaluator
March 20th, 2002, 19:57
But I can move values into DR0-3 and then
read that values.
you wrote:
"And of course you cannot set them"
??
JimmyClif
March 20th, 2002, 20:27
I never tried to execute ring0 instructions in my everyday code...
So here's the thread I was taking that quote from:
here (http://board.win32asmcommunity.net/showthread.php?s=&threadid=3825&highlight=ring3+drx)
Did you check it with a debugger ?
Kayaker
March 21st, 2002, 04:30
Hi
You're right Evaluator, I can read and write to the debug registers in Ring3 code as well as in Ring0. Weird huh? At least apparently. The reason I say "apparently" is a question I've had about the debug registers, to paraphrase Splaj - "Still searching for my +DRx" ,lol.
Let me explain (with some good old creative copy 'n pasting). There are 8 debug registers, 6 of which interest us.
DR7 is the CPU debug control register, whose bits define which (BPM) breakpoints are active, the breakpoint type (CODE or DATA), and the access size for DATA breakpoints. The breakpoint type is stored in the breakpoint structure, and is translated into the R/Wn fields of DR7 :
code execution = 00
data write only = 01
data read/write = 11
data read only = 11 (read and write sorted in the handler)
There are also some undocumented bits (isn't there always? See UNDOCUMENTED BITS IN DR7 Dr. Dobb's Journal). DR7 can also be used as a method of SICE detection...
DR6 is the debug status register which is used to identify the condition that caused the debug exception. Each time a task encounters a debug exception, the CPU encodes the source of the exception into bits of the DR6 debug status register (i.e. breakpoint 0, 1, 2, 3 or trace mode single step).
DR0-DR3 are the Debug Address Registers. Each of these registers contains the linear address associated with one of four breakpoint conditions. Each breakpoint condition is further defined by bits in DR7.
The debug address registers are effective whether or not paging is enabled. The addresses in these registers are linear addresses. If paging is enabled, the linear addresses are translated into physical addresses by the processor's paging mechanism. If paging is not enabled, these linear addresses are the same as physical addresses.
If you type 'CPU' in Softice you get a listing of all the current registers and selectors, including the control (CR) and debug (DR) registers. Now, my interest was to "find" the debug registers in memory so I could actually see and feel them rather than just accessing them through code. So I used this code in Ring0, which fills the 1st debug register DR0 with a searchable value:
mov eax, 'kcuf'
mov dr0, eax ; write to dr0
xor eax, eax
mov eax, dr0 ; read dr0
Doing a search for 'kcuf' I found where all the registers listed with 'CPU' actually are (C392xxxx on my system). You can actually see the register values changing as you trace or execute commands. OK, cool so far.
Now my question is, the docs say that DR0-DR3 contain the linear address associated with one of four breakpoint conditions (i.e you've got maximum 4 BPM breakpoints you can set). So if I set a BPM breakpoint or two, I was *expecting* to see those addresses listed in the debug registers (as shown by 'CPU'), but I don't!! Or, if I set a BPM breakpoint that is registered in say DR3 (as shown by 'BL'), and use "mov eax, dr3", I *still* don't get the breakpoint address returned to me.
Spath's Softice Internals document contains a good discussion of how Softice sets up breakpoints (BPX, BPM, BPR,..), how an internal table is used to store the addresses, and how the DRx registers are apparently secondary to this table and aren't immediately used. I'd like a better understanding of exactly *how* you can access breakpoint addresses (of any kind). If not directly through DR0-DR3 for BPM breakpoints, then *where* are the internal breakpoint tables used by Softice?? There are only 4 BPM breakpoints available *globally*, are the DRx addresses readable in a task's _CONTEXT structure? (see Spaths doc and the Softice ADDR command for wtf this means).
My interest (other than general curiousity) is to see if it's possible to set a breakpoint directly through code by modifying either the debug registers, or the breakpoint table, and to have Softice pop up. Specifically a break at the OEP. Or, to examine exactly how winice does it. I know a 'CC' is set at the first byte of the target address and when the INT3 is executed, SoftICE's INT 3 handler is called, and the original byte is restored. Somewhere in there Softice pops up.
It's the *implementation* of this code I'm interested in. Using a dll injection technique (which runs *before* the real OEP executes), I'm wondering if it's possible to set a breakpoint *on* the OEP so Softice pops up just as it normally would using Loader32.exe.
Or, to extend the idea further, let's say there's a redirected thunk address which is accessed during a registration routine. Could you set a BPM breakpoint on a READ of that address (or an eXection of the address pointed to by that thunk) THROUGH CODE?
Again, this would require accessing either the DR0-DR3 debug registers and inserting the proper linear address, and/or Softice's internal breakpoint table. Back to my question - Anybody have any ideas *where* the internal BP table(s) is(are), or how (if) the debug registers should be correctly used?
This make any sense?
Kayaker
DakienDX
March 21st, 2002, 07:34
Quote:
Originally posted by Kayaker
DR6 is the debug status register which is used to identify the condition that caused the debug exception. Each time a task encounters a debug exception, the CPU encodes the source of the exception into bits of the DR6 debug status register (i.e. breakpoint 0, 1, 2, 3 or trace mode single step). |
Hi Kayaker !
But you have also to clear DR6 after each breakpoint or you won't know why the next breakpoint has occured.

evaluator
March 21st, 2002, 19:58
Hello, Kayaker!
Hello, JimmyClif!
JimmyClif!
"DON'T TRUST OUTSIDE, DON'T TRUST CODEINSIDE

"
So lets resume our research!
Under [my]W98SE wE can in Ring3:
1. successfully write & read to-from DR0-DR3
>For this I wrote in HIEW super-little prog "DR0-3.EXE"
See in attachment. It run under "plain" W98SE & with WICE or TRW.
2. NOT_successfully write & read DR6-DR7 (& CR0,CR2-4)!
This means: I allowed try to move in this registers,
but when I read, "they" always returns 00000000.
Because of this I can't say: 'my values are written there'
Anyway we have NO fault.
Experimental:
I try also 0F24 & 0F26 opcodes.
HIEW shows them as TR0-TR8 (shows uppercase e.g theoretical?). Test registers???
Finally I get fault!
DakienDX
March 21st, 2002, 20:51
Hi evaluator !
The TR? regsiters where only present on the 486. So any access from CPU lower or higher than a 486 will generate an expection.
evaluator
March 21st, 2002, 21:52
Kayaker!
1. If I try search upper C3000000, wice become frozen...
2. you wrote:
>>My interest is to see if it's possible to set a breakpoint
>>directly through code by modifying either the debug registers...
here I can't help you with my knolidge, but have you read
INTEL's manual 3, chapter 15?
Probably you havn't read, because you write:
>>how the debug registers should be correctly used?
My eNgLiSh is too small for this, but as I understand,
BPM are NOT set only by MOV DRx, also there are lot of other registers..
DakienDX!
WE WILL...
JimmyClif
March 21st, 2002, 22:10
I wish I could test this

but I'm stuck on
real Operating
Systems.. such as WinME and WinXP (harharharharhar)
LOL,
JimmyClif
Kayaker
March 22nd, 2002, 07:16
Thanks for the feedback guys!
I'll be gone for a couple of weeks, drinking beer and kayaking someplace warm ;-)
Will have another look at it when I get back. Probably check in from some cybercafe somewhere...
Cheers all,
Kayaker
DakienDX
March 22nd, 2002, 16:02
Hi Kayaker !
I wish you all the best for your holidays.
You're going to "someplace warm", Florida perhaps? (Spring Break?

)
evaluator
March 23rd, 2002, 22:42
Kayaker!
I did it!
I set DR0 and then handle it in own code!!
Or you are no more here?
Kayaker
March 29th, 2002, 20:53
Quote:
Originally posted by evaluator
Kayaker!
Or you are no more here? |
LOL, nope, no more here. A continent or two away actually. Just wanted to check in from the jungle to make sure this place is still rocking. And it is, cool.
Adios,
Kayaker
crUsAdEr
May 2nd, 2002, 15:11
Since kayaker is back :>.. how about research on this still?
I found this thread rather interesting, though din understand everything
NT internals questions ( started by arthaxerxes)
http://www.woodmann.net/forum/showthread.php?s=&threadid=1146
I still dont get it... AsProtect seems to do everythign without a problem? clearing debug registers from 0 to 7 everywhere be it 98, NT, 2K or XP... guess i have lots of stuff to be read.. if only the damn exams could end earlier.. the Intel manual prolly takes a few years to finish reading..lol...
When you guys use
mov eax, 'kcuf'
mov dr0, eax ; write to dr0
xor eax, eax
mov eax, dr0 ; read dr0
is this in the seh handler or in your normal asm code? if in the normal code then isnt the case solved completely by using seh?
Gosh i am lost!!!!!
thanx,
crUsAdEr
evaluator
May 2nd, 2002, 16:19
Hello, binh81!
1.
>mov eax, 'kcuf'
>mov dr0, eax ; write to dr0
>xor eax, eax
>mov eax, dr0 ; read dr0
Of course, its ASM code.
2.
>how about research on this still?
Define exactly, what you want.
Setting DRx and handling?
On me W98se I did it very easy, but You are on W2k, Ok!?
Seems, here you must write your own NTICE~:0
fORgET iT! Or use NTICE
(In XP's NTOSKRNL there are banch of "MOV in-out DRX", so our poor DRx will cry in 90%)
3.
Why ASPR kills DRx?
R!SC's answer is enauf. Or no??
But ASPR (& any) can't kill BPR. Eh, there are no BPR on NT\W2k\XP.
Don't warry, be Happy, use BPX-Api.
4.
> the Intel manual prolly takes a few..
Nope, I read & very enjoE. You need for read:
Volume 3 CHAPTER 15
DEBUGGING AND PERFORMANCE MONITORING (24 page)
+ CHAPTER 5
crUsAdEr
May 3rd, 2002, 09:43
Thanx eval,
Shall read that Intel manual when i have time....
I was just wondering what is the fuss now about debug register? Since anytime we need to access it, we can just use a simple seh and everything is yours to play with?
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.