Log in

View Full Version : debug registers & SI


remains
February 10th, 2004, 23:32
Hi:

Long time ago i made a lamme program wich allows loading plugins for softice and now i'm trying to make one myself wich prevents anti-bpm tricks. The method i want to use seems symple in theory: hook idt's vector 1 and then set Dr7 register's flag 13 so every time a debug register is going to be accessed my exception handler will be called. The problem is that i can't figure out how do windows and softice handle debug registers. If i change Dr7 directly when executing in softice's environment, i get a system crash. If i change it in the context structure of the debuggees thread, it seems that the changes don't take efect. At this point arises the question: are debug registers mantained in a global manner or are they mantained in a per thread basis ? If they are globaly mantained, how does the system know to wich program's address space does a bpm belong ? And if they are mantained in a per-thread basis, why are only 4 bpms allowed with softice ?

I'll continue debugging and trying to answer that questions myself, but if anyone could give me any idea my poor pc would probably suffer less hard reboots :/.

Bye and sorry for my hardly understandable english

Kayaker
February 11th, 2004, 12:28
Hi

Quickly, A couple of things that might be useful to you are Yates' DRxLOG example - 'Log DRX operations via DR7 General Detection(GD) bit', as well as Spath's Softice Internals document, if you haven't seen either.

Kayaker

remains
February 11th, 2004, 13:53
Hi again:

Thx for your quick response. I looked spath's article briefly searching in googles cache the highlighted words related with debug registers, but i didn't found what i was looking for. I will take a look to the drxlog program instead.

Thx again for your help.

JMI
February 11th, 2004, 14:54
Well Spath's article is very close at hand. Try this URL and notice how close to the one you are already on. It is :

http://www.woodmann.com/crackz/Tutorials/Siceints.txt

Using "Softice Internals" as the search key words I got this result:

http://search.earthlink.net/search?q=Softice+Internals+&area=earthlink-ws

which listed many working links, several through Links found at the bottom of these pages.

You may also notice that there is a Link for Yates down there also. You will find the second article using "DRxLOG" as your search key word. You will find the article at:

http://www.woodmann.com/yates/syscode.htm


Regards,

volodya
February 11th, 2004, 16:33
Kayaker/JMI

Collegues, I do apologize, but what you are both talking about is old-old-old crap. The question about DR-regs and Soft-Ice is a pretty difficult one. Win9x and NT+ both handle DR-regs in the completely differnet manner!
OK, I'm not going to talk about 9x any more...
On NT the following picture is here, but, unfortunately it is not clear for myself as well. Under NT we DO NOT have TSS. The task switch is a software event, not a hardware one any more. One may go to ntoskrnl and disassemble SwapContext function. There you'll be able to see CR0/CR3 reloading, KPCR-reloading, etc... Now the question arises! A very difficult one. If you go to the Intel Manual you'll notice there so called GD-bits in DR-reg - chapter 15. Citation:



L0 through L3 (local breakpoint enable) flags (bits 0, 2, 4, and 6)
Enable (when set) the breakpoint condition for the associated breakpoint for
the current task. When a breakpoint condition is detected and its associated Ln
flag is set, a debug exception is generated. The processor automatically clears
these flags on every task switch to avoid unwanted breakpoint conditions in the
new task.

G0 through G3 (global breakpoint enable) flags (bits 1, 3, 5, and 7)
Enable (when set) the breakpoint condition for the associated breakpoint for all
tasks. When a breakpoint condition is detected and its associated Gn flag is set,
a debug exception is generated. The processor does not clear these flags on a
task switch, allowing a breakpoint to be enabled for all tasks.


If you set G0-G3 for DR0-DR3 you expect the processor to make a trap upon a task switch if the specified VA is met. BUT THERE IS NO TSS! No hardware task switches!!! How can Windows handle the situation? If the breakpoint comes from the ring-3, one should go deep into KeContextToKframes. The sequence of events is as follows:

ring-3:
SetThreadContext or SEH -> CONTEXT.DRx = VA, CONTEXT.DR7 = mask;

ring-0:
NtConinue->KiContinue->KeContextToKframes
In KeContextToKframes Windows puts the content of the CONTEXT structure in KTRAP_FRAME structure. Along with it Windows makes a lot of checks. Examples are:


.text:00430777 mov ecx, [esi+CONTEXT.Dr1]
.text:0043077A cmp MmHighestUserAddress, ecx
.text:00430780 sbb eax, eax
.text:00430782 not eax
.text:00430784 and eax, ecx
.text:00430786 jmp back1

As you see, here is the check for 7FFFFFFF is made.

.text:0043059C mov [ebx+KTRAP_FRAME.Dr3], eax
.text:0043059F mov eax, [esi+CONTEXT.Dr6]
.text:004305A2 and eax, 0E00Fh
.text:004305A7 mov [ebx+KTRAP_FRAME.Dr6], eax
.text:004305AA mov eax, [esi+CONTEXT.Dr7]
.text:004305AD and ax, 155h
.text:004305B1 test dl, dl
.text:004305B3 mov [ebx+KTRAP_FRAME.Dr7], eax
.text:004305B6 jz short loc_4305D9

As you see, here Windows is playing with G0-G3 bits.
So, ring-3 debugger cannot put a bpm anywhere it wants to!
As to the ring-0 there are no limitations, BUT!
If you set GD bit to 1, there is immediately one hardware feature available to you. As remains mentioned, there should be the int1 vector ready for the situation. But, remains, what are you going to do if something (like StarForce or ExtremeProt) is ALREADY sitting on int 1, ah????? OK, there is perhaps a solution even for this case, but I'm not going to mention it so far.

JMI
February 11th, 2004, 16:46
Thanks Volodya.

Just one small correction to your observation about my response. I was not "talking about" the "old-old-old crap" at all. I had only responded to a request for help in finding the articles. I don't believe I made any comment about their usefulness or lack thereof. You other comments, however, were useful and interesting.

Regards,

volodya
February 11th, 2004, 17:03

JMI, did you get my email about Adobe?

JMI
February 11th, 2004, 17:12
volodya:

Yes, thank you. I have finally checked that email addy and have gotten "both" of your messages, as you can see. I will use the proper title in the future but am somewhat confused. Again a "small" correction. My use of "Vlad," here and on exetools was short for "Vladimir," your (now former) nick here, not as an abreviation for "Vladislav."

But I would like to use whatever you prefer. Would you prefer "Volodya" or "Vladimir" on this Forum? We could change your registration here, if you wish, to "Volodya" keeping your current post count and other information.

Regards,

evaluator
February 11th, 2004, 17:12
Little correcture:

TSS must present in all system which have more then Ring0.
TSS can absent only if system(test?) has only Ring0.

another fact is, that M$ not uses TSS for task-switching..
But it always cares about TSS.

volodya
February 11th, 2004, 18:01
Of course. In fact, there are two more TSS. One for NMI, another... I forgot

JMI, convert me to "Volodya" then.

"Vlad" is always in abbreviation of "Vladislav"
"Vladimir" and "Volodya" both have the shorten form of "Vova", but the last one I really hate

OK. Sorry for offtop. As a partial excuse here is the code of SwapContext.

.text:00404334 SwapContext proc near ; CODE XREF: KiUnlockDispatcherDatabase+6Ep
.text:00404334 ; KiSwapThread+BCp ...
.text:00404334 or cl, cl ; esi - KTHREAD
.text:00404334 ; cl - BYTE WaitIrql
.text:00404334 ; ebx - KPCR.SelfPcr
.text:00404336 mov es:[esi+KTHREAD.State], 2
.text:0040433B pushf
.text:0040433C mov ecx, [ebx] ; ecx - *KPCR
.text:0040433E cmp dword ptr [ebx+80Ch], 0 ; KPCR.KPRCB.DpcRoutineActive
.text:00404345 push ecx
.text:00404346 jnz KeBugCheck
.text:0040434C mov ebp, cr0
.text:0040434F mov edx, ebp
.text:00404351 mov cl, [esi+KTHREAD.DebugActive]
.text:00404354 mov [ebx+50h], cl ; KPCR.DebugActive
.text:00404357 cli
.text:00404358 mov [edi+KTHREAD.KernelStack], esp
.text:0040435B mov eax, [esi+KTHREAD.InitialStack]
.text:0040435E mov ecx, [esi+KTHREAD.StackLimit]
.text:00404361 sub eax, 210h
.text:00404366 mov [ebx+KPCR.NtTib.StackLimit], ecx
.text:00404369 mov [ebx+KPCR.NtTib.StackBase], eax
.text:0040436C xor ecx, ecx
.text:0040436E mov cl, [esi+KTHREAD.NpxState]
.text:00404371 and edx, 0FFFFFFF1h
.text:00404374 or ecx, edx
.text:00404376 or ecx, [eax+20Ch]
.text:0040437C cmp ebp, ecx
.text:0040437E jnz zero_CR0
.text:00404384
.text:00404384 loc_404384: ; CODE XREF: SwapContext+107j
.text:00404384 test dword ptr [eax-1Ch], 20000h
.text:0040438B jnz short loc_404390
.text:0040438D sub eax, 10h
.text:00404390
.text:00404390 loc_404390: ; CODE XREF: SwapContext+57j
.text:00404390 mov ecx, [ebx+KPCR.TSS]
.text:00404393 mov [ecx+4], eax ; KTSS.Esp0
.text:00404396 mov esp, [esi+KTHREAD.KernelStack]
.text:00404399 mov eax, [esi+KTHREAD.Teb]
.text:0040439C mov [ebx+KPCR.NtTib.Self], eax
.text:0040439F sti
.text:004043A0 mov ecx, [ebx+KPCR.GDT]
.text:004043A3 mov [ecx+3Ah], ax ; into GDT fs
.text:004043A7 shr eax, 10h
.text:004043AA mov [ecx+3Ch], al
.text:004043AD shr eax, 8
.text:004043B0 mov [ecx+3Fh], al
.text:004043B3 mov eax, [edi+KTHREAD.ApcState.Process]
.text:004043B6 cmp eax, [esi+KTHREAD.ApcState.Process]
.text:004043B9 jz short __ret
.text:004043BB mov edi, [esi+KTHREAD.ApcState.Process]
.text:004043BE xor eax, eax
.text:004043C0 db 66h
.text:004043C0 mov gs, ax
.text:004043C3 mov eax, [edi+KPROCESS.DirectoryTableBase]
.text:004043C6 mov ebp, [ebx+KPCR.TSS]
.text:004043C9 mov ecx, dword ptr [edi+KPROCESS.IopmOffset]
.text:004043CC mov [ebp+KTSS.CR3], eax
.text:004043CF mov cr3, eax
.text:004043D2 mov [ebp+KTSS.IoMapBase], cx
.text:004043D6 xor eax, eax
.text:004043D8 cmp [edi+KPROCESS.LdtDescriptor.LimitLow], ax
.text:004043DC jnz short lldt
.text:004043DE lldt ax
.text:004043E1 lea ecx, [ecx]
.text:004043E3
.text:004043E3 __ret: ; CODE XREF: SwapContext+85j
.text:004043E3 ; SwapContext+102j
.text:004043E3 inc [esi+KTHREAD.ContextSwitches]
.text:004043E6 inc [ebx+KPCR.PrcbData.KeContextSwitches]
.text:004043EC pop ecx
.text:004043ED mov [ebx+KPCR.NtTib.ExceptionList], ecx
.text:004043EF cmp [esi+KTHREAD.ApcState.KernelApcPending], 0
.text:004043F3 jnz short _ret
.text:004043F5 popf
.text:004043F6 xor eax, eax
.text:004043F8 retn
.text:004043F9 ; ---------------------------------------------------------------------------
.text:004043F9
.text:004043F9 _ret: ; CODE XREF: SwapContext+BFj
.text:004043F9 popf
.text:004043FA jnz short ___ret
.text:004043FC mov al, 1
.text:004043FE retn
.text:004043FF ; ---------------------------------------------------------------------------
.text:004043FF
.text:004043FF ___ret: ; CODE XREF: SwapContext+C6j
.text:004043FF mov cl, 1
.text:00404401 call ds:_imp_HalRequestSoftwareInterrupt
.text:00404407 xor eax, eax
.text:00404409 retn
.text:0040440A ; ---------------------------------------------------------------------------
.text:0040440A
.text:0040440A lldt: ; CODE XREF: SwapContext+A8j
.text:0040440A mov ebp, [ebx+KPCR.GDT]
.text:0040440D mov eax, dword ptr [edi+KPROCESS.LdtDescriptor.LimitLow]
.text:00404410 mov [ebp+48h], eax
.text:00404413 mov eax, [edi+KPROCESS.LdtDescriptor.HighWord]
.text:00404416 mov [ebp+4Ch], eax
.text:00404419 mov eax, 48h
.text:0040441E mov ebp, [ebx+KPCR.IDT]
.text:00404421 mov ecx, dword ptr [edi+KPROCESS.Int21Descriptor.Offset]
.text:00404424 mov [ebp+108h], ecx
.text:0040442A mov ecx, dword ptr [edi+KPROCESS.Int21Descriptor.Access]
.text:0040442D mov [ebp+10Ch], ecx
.text:00404433 lldt ax
.text:00404436 jmp short __ret
.text:00404438 ; ---------------------------------------------------------------------------
.text:00404438
.text:00404438 zero_CR0: ; CODE XREF: SwapContext+4Aj
.text:00404438 mov cr0, ecx
.text:0040443B jmp loc_404384
.text:00404440 ; ---------------------------------------------------------------------------
.text:00404440
.text:00404440 KeBugCheck: ; CODE XREF: SwapContext+12j
.text:00404440 push 0B8h
.text:00404445 call KeBugCheck
.text:0040444A retn
.text:0040444A SwapContext endp

remains
February 11th, 2004, 18:30
Rehi:

JMI: Sorry but i didn't expressed correctly in my last post. What i meant was that i have already read spath's article, but instead of reading it entirely, i looked googles cache of this article, so the terms i searched would appear highlithed. This way i can find rapidly in the document the part that interest me. For example:

h**p://66.102.9.104/search?q=cache:8T0L6kFIFaEJ:www.woodmann.com/crackz/Tutorials/Siceints.txt+%22debug+registers%22+softice&hl=eu&ie=UTF-8

If you scroll down in that page you will rapidly see highlighted in yellow the part wich refers to "debug registers". Sorry for the confusion. I haven't had time to read yate's program code so i don't know if i will find there the answer.

Volodya: I'm having a look to xprotector's anti-debug tricks. It runs in ring0 and at certain point it has a loop wich makes what i supose is a crc (i've just looked it brefly) to the code that is going to be executed after the loop and also to the code of the loop itself, so i can't set a breakpoint outside the loop because it will be detected by the routine. The solution is to set a hardware breakpoint, but the loop itself clears debug registers (except dr7 register wich is set to 700h). Tracing the code until it ends the loop isn't a solution in itself...

You asked what would i do if int 1's vector would be already hooked by xprot: well, i simply don't let it hook that vector, instead i couldn't use sice to trace the code.

About thread switches: I have seen some interesting things tracing GetThreadContext and such apis, but until now i haven't been able to do a serious work around that because i was trying first to correct my program's bug. If yates's program hasn't the solution to the bug, the only solution i see is kernel hacking around setthreadcontext and exception handling routines. I'm also thinking another possible solution, but i will try it this night (another long long nigth of reversing and good music; it doesn't sound so bad, does it ?)

Well, a lot of thanks againg, and sorry for my english, plese try to understand my efforts to make my posts understandable.

JMI
February 11th, 2004, 18:47
Volodya:

Please call your parents and advise them that you have now officially been re-christened as "volodya" and they should stop referring to you by that "other" name. I think I found all the old references and, where appropriate, updated them to "volodya" also, in hopes of avoiding any confusion about just who the heck you are. And I always did say your Russian was way, way better than mine.

My own given name was usually extended, rather than abbreviated. It usually came out as something like; "Hey sh*tforbrains" or some such flattering designation. But that was just my Mom's way of showing affection.

Regards,

evaluator
February 12th, 2004, 03:03
to remains

>If i change Dr7 directly .. in softice's environment, i get a system crash.
try playing only with 13flag & your handler must proper manage
all 13flag related occurences.

>are debug registers mantained in a global manner or .. per thread basis?
W2K,XP(NT-systems) mainteins DRx per Process basis.
(however Ntice cracks this system enhancement)
W98se not mainteins DRx, so they are global
(& dangerous, bcz in other process can happen crash)

>If they are globaly mantained, how does the system know to wich program's
debuger must care about correct process.

>why are only 4 bpms allowed with softice ?
Read manuals.

volodya
February 12th, 2004, 10:55
JMI

Mucho gracias, senior

JMI
February 12th, 2004, 12:25
You are welcome. Keep that good information flowing in and best of luck with your website and the attacker.

Regards,

[yAtEs]
February 13th, 2004, 12:51
Quote:
[Originally Posted by remains]

If i change Dr7 directly when executing in softice's environment, i get a system crash.



I had fun with his also, the problem is that you must handle the exception
in your handler, you need to emulate the instruction then the important
bit of increasing EIP so you dont cause an exception loop, you probably
jmp to the original handler afterwards, or bpint 1 for testing, and softice
int 1 handler doesnt know what to do and dies with it, and general system int1 seems to ignore it

/yates.

remains
February 13th, 2004, 13:54
Yes, I saw that the problem is there, so i've made some proves. First i made the next prove in the handler (i've earlyer changed dr7's bit 13's value succesfully and hooked vector 1):

OurExceptionHandler proc ;vector 1's new handler

mov eax, [esp]
int 3
...

When i'm in a ring3 program with sice and i hit f8, before the handler gets naturally called due to the single step feature, sice makes it's own work, and it touches debug registers (your program showed me that too), so when this happens the code showed above gets called. What i wanted to see with this code is if i got in eax the VA where the exception was generated. But here it comes the funny part (wich would be funnyer without the system crash wich comes later). When i hit f8 in sice the "int 3" i put in the handler doesn't get called. Instead sice pops again in the VA where the exception is generated in Ntice.sys (mov eax, dr0). What follows is the system crash (sice has problems debugging itselve, duh)

So, as softice sets fs register to 10h, i've though it could be a good idea just to make a iret without further processing when i get this value in fs. Something as:

OurExceptionHandler proc

push eax
mov ax, fs
cmp ax, 10h
jz epilog2

epilog2:

pop eax
iret

Anyway when this code gets called i get a system crash too. Now I'm downloading a very interesting 2*100 mb file with my modem so until tomorrow i'm not going to be able to make more proves.

Again lots of thanks for your help, no i know i'm closest to the solution of the problem

volodya
February 13th, 2004, 16:44
Now I'm downloading a very interesting 2*100 mb file with my modem so until tomorrow i'm not going to be able to make more proves

I know what file you are downloading
Really cool one.

dELTA
February 13th, 2004, 18:37
Yep, who wouldn't want to download something that contains the full source code to Notepad...

nikolatesla20
February 13th, 2004, 18:54
volodya and delta and JMI: Not trying to start any flames, but my goodness enough thread hijacking lately?

(I just hijacked this thread to say that, so I'm no better)

-nt20

Timbo
February 18th, 2004, 18:47
????
I took the dial command like this
mov eax, my value
mov dr7,eax
sti
ret
no error with xp so far ??