flat assembler
Message board for the users of flat assembler.

Index > Windows > HARDWARE MASTER DRIVER

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
-----------------------------
I.D.T. Master Hooker Driver
-----------------------------


This "Hardware master driver" is programmed to hook
ALL the IDT gates (interrupts, traps, faults and tasks)
for executing its code before calling the original ISR.
It has also the function to customise the range of IDT
gates we want to hook.

This project is my last one about hooking interrupt
in a operating system, because i'm bored now by them.
They are just too simple (for me) to modify as i want!

I made generical hooked functions for who want to make
his personal hook routine, but if you aren't able to
do it you shouldn't modify them or you can cause a
crash on your system! (the blue screen of PC death)
Any modification to this code is at own risk...

I optimized the code to make it smaller as possible,
and in the same time has a lot of freatures and error
control checks (seems to be PERFECT).

FREATURES:
1) All the hooked interrupts become available
for USER-MODE call (using INT or CALL FAR)
after the driver load.
Unloading the driver restores the original
state of the IDT.

2) The driver doesn't use imported function
from NT kernel or other KM libraries.
It do all by itself.

3) The driver exports its functions for who
wants use them indirectly form other
kernel mode locations.

4) Is possible to customize the hook range by
setting the VECTOR_START and VECTORS_LIMIT
constants (also you have to modify the
"PrepareHookedList" function).

5) All hooked ISR are personalizables for
code PRE-EXECUTION and POST-EXECUTION
(referred to the original ISR).
I wrote them only for standard PRE-EXECUTION
because some interrupt are kernel functions
that change the IRET stack and then you have
to modify it manually for any of them.

CONTROLS:
1) Deactivating the most part of interrupts
by clearing the IF flag when the driver
is modifing an IDT gate.

2) The driver checks if the requested gate
isn't over the IDT limit.
For any reason, some vectors may not be
available. (who knows)

3) During driver loading, the start routine
will restore all the IDT gates it changed
if an error occurs.
An unsuccessful code will stop the loading.

In conclusion, i prefer remember:
the power is nothing without control:
the power can miss, but the control can't.



Pirata [PHOENIX] Derek L.S.


Description: Souce code and binary of driver
Download
Filename: Hardware master driver.zip
Filesize: 25.95 KB
Downloaded: 160 Time(s)

Post 11 Jan 2010, 15:39
View user's profile Send private message Send e-mail Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Pirata, have you tried this in a multi-code system? Recently I've read an article about hooking in the GDT ( http://blog.48bits.com/?p=856 , Spanish, but AFAIK you can read it), and one interesting aspect was that every core has its own table. Perhaps the same happens with the IDT?
Post 11 Jan 2010, 18:25
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

With my driver, I hook all interrupts (256 at the same time) to a general dispatcher,
and after, I redirect each interruption to its original code.
This, in a multi-core System (4µPs - Q6600) and XP Pro.
I can intercept any interrupts, depending on any conditions.
Processor and/or process and/or ... others.
It works 100%, perfect stability.
Yes .... each processor has its IDT and GDT, and they are not necessarily identical

I looked at your code Pirata.
Your driver does not work on a "multi-core" system.

Code:
proc PointInterruptGate vector
sidt [idt_register]    

which IDT? which processor?
With a multi-core system,
the function "KeSetSystemAffinityThread" is essential and you're not using it.
(to scan each processor and collect all necessary informations)

Code:
proc HookInterrupt vector,new_routine,old_gate_buffer
.backup: cli
stdcall PointInterruptGate,[vector]
or eax,eax
jz .error
push eax
stdcall MoveMemory,eax,[old_gate_buffer],4*2
.edit: pop edx
mov ax,cs
mov word [edx+2],ax
mov word [edx+4],INTERRUPT_GATE_FLAGS
mov eax,[new_routine]
mov word [edx],ax
ror eax,16
mov word [edx+6],ax
.finish: mov eax,TRUE
.error: sti
ret
    

On a multi-core Syteme, again, it does not work.
The "cli" is insufficient on a "multi-core/Multi-tasking" system.
You must hook atomically. (lock cmpxchg8b)


_________________
I am not young enough to know everything (Oscar Wilde)- Image


Last edited by ouadji on 12 Jan 2010, 07:05; edited 8 times in total
Post 12 Jan 2010, 01:30
View user's profile Send private message Send e-mail Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
I was not expecting stability problems but rather missing some system calls/interrupts when them don't originate on the core that hooked the GDT/IDT (well, depending on how do you manipulate the hooking it may be some instability problems at setup, but then it should not cause problems)
Post 12 Jan 2010, 01:52
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji
Quote:
may be some instability problems at setup

absolutely not, no instability. Smile (look above LocoDA)
However, the code is more complex than Piarata

go to bed Very Happy 03.15 hr here ! Shocked

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 02:13
View user's profile Send private message Send e-mail Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Yes, in your explanation I see that you use a very conservative operation. Also, instead of using ZwSetInformationThread like the blog, you use a function that is much more specific for the task (and perhaps the blog is somewhat wrong as I didn't see in MSDN documentation of affinity mask using that NTDLL.DLL function).
Post 12 Jan 2010, 02:52
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

i don't use functions inside ntdll.dll, i'm in ring0, with a driver.
I use functions inside Ntoskrnl. exe (ntkrnlmp.exe - multi-core)
and also those of hall.dll (halmacpi.dll).

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 07:02
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

here, only to scan each processor and collect all the information I need.
With this driver, I hook all interrupts (simultaneously), but also other features.
So, before continuing, i need all info for each processor


Code:
proc GetInfosCPUs ;(XP Pro Sp3 - 4µPs Q6600)

              mov ecx , IA32_SYSENTER_EIP
              rdmsr
              mov [KiDispServ] , eax  ;here, no matter the  of processor,
                                      ;it's just a start reference point.
              call KeGetCurrentThread 

              mov [MyThread] , eax

              mov ecx,[eax + KTHREAD.ApcState.Process]
              mov edx,[ecx + KPROCESS.DirectoryTableBase]
              mov ecx,[ecx + KPROCESS.Affinity] ;= +5Ch

              push ecx

              call KeQueryActiveProcessors

              pop ecx

              xchg eax , ecx ; eax = "Mon_Affinity" - ecx = "System_Affinity"

;ici j'ai ceci:
;—————————————
;ecx = "System" Affinity 
;eax = "my" Affinity

              xor ebx , ebx
              xor edx , edx

              bsr esi , ecx
              bts edx , esi    ;"masque_maximum"
              bsf esi , ecx
              bts ebx , esi    ;"masque_minimum" = masque de départ

              xor edi , edi    ;edi = index pour la mémorisation. Départ = 0
              xor esi , esi

.next_µP:
              test ebx , ecx    ; bit/on dans "System_Affinity" ?
              jz .bad

              pushad

              mov [CPU.Masque + edi] , ebx

              test ebx , eax
              mov eax , 000010b      ;µP faisant partie de "Mon_Affinity"
              jnz .DMProc
              mov eax , 000100b      ;µP "extérieur"
.DMProc:      mov [CPU.Origine + edi] , eax

              push edi
 
              stdcall KeSetSystemAffinityThread , ebx 
 
              pop edi

              sidt fword [CPU.IDTR + edi] ;Mémo des IDTR et GDTR
              sgdt fword [CPU.GDTR + edi]

;-----------------------------------------------------

              ;mov eax , [fs:0 + KPCR.SelfPcr]
              ;or,
              mov ecx , IA32_FS_BASE ;IA32_FS_BASE equ 0C0000100h
              rdmsr
              mov [CPU.PKPCR + edi] , eax

;-----------------------------------------------------

              imul eax , esi , DimTAA * 256
              mov [CPU.ShiftTableAll + edi] , eax

;----------------------------------------------------- Mémo des MSR_ESP
              mov ecx , IA32_SYSENTER_ESP
              rdmsr             ;(YY)
              mov [CPU.R0_Stack + edi] , eax

              if pileperso eq 1 ;"ma" pile ? 
                 lea eax , [esi + 1]
                 imul eax , eax , 1000h
                 lea eax , [ma_pile + eax]
                 wrmsr            ;edx from (YY)
              end if

 ;-----------------------------------------------------

              mov ecx , IA32_SYSENTER_EIP
              rdmsr             ;(XX)
              mov [CPU.KiDispServ + edi] , eax

              cmp eax , [KiDispServ]
              jz .okKDS

              mov eax , 77000003h ;des "KiDispServ" différents !
              jmp problem   ;usually, never !

.okKDS:       cmp [CPU.Origine + edi] , 000100b
              jz .pasmoi

              imul eax , esi , DimSPC ;DimSPC = sizeof."SysParCpu"
              add eax , offset hook_se

              wrmsr ;<=== HOOK de "MSR_EIP" - edx from (XX)

.pasmoi:      nop

;HOOK de "MSR_EIP" = offset "hook_se" + (0xDimSPC),(1xDimSPC)...
;-----------------------------------------------------

              mov ecx , IA32_APIC_BASE ;mémo des "APIC_BASE"
              rdmsr
              mov [CPU.ApicBase + edi] , eax

              bt eax , 8       ;bootstrap processor ?
              jnc .no_BSPµP

              mov ebx , [fs:0 + KPCR.KdVersionBlock]
              mov [CPU.KdVersionBlock] , ebx

.no_BSPµP:

;----------------------------------------------------------
              popad
;----------------------------------------------------------

             inc esi        ;compteur
             add edi , Dim  ;Dim = sizeof(CPU) , CPU = struct "INFOµP".
.bad:        shl ebx , 1

             cmp ebx , edx

             jbe .next_µP   ;jump si scan_masque <= masque_maximum

; les butées (pas toucher)
; ————————————————————————
             mov [CPU.IdtrVecteur + edi] , 0      ;dans "close"
             mov [CPU.GdtrVecteur + edi] , 0      ;
             mov [CPU.ApicBase + edi]    , 0      ;
             mov [CPU.Masque + edi]      , 'stop' ;dans "close"

             call KeRevertToUserAffinityThread   ;pas de paramètres.

             retproc
endp
;-------------------------------------------------------------------------
Data "CPU = INFOµP"
;------------------
CPU INFOµP
rb (sizeof.INFOµP * (32-1)) ; max 0x20µPs with XP Pro


struct   INFOµP
;
 union
 IDTR               dp 0
    struct
       IdtrSize         dw 0
       IdtrVecteur  dd 0
    ends
 ends
 ;
 union
    GDTR            dp 0
    struct
       GdtrSize     dw 0
       GdtrVecteur  dd 0
    ends
 ends
 ;
 Masque             dd 0
 ApicBase           dd 0
 R0_Stack           dd 0
 KdVersionBlock     dd 0
 Origine            dd 0
 ShiftTableAll      dd 0
 KiDispServ         dd 0
 PKPCR              dd 0
      
 Int02h_NMI_A       dd 0
 Int02h_NMI_B       dd 0

 Res1               dd 0
 Res2               dd 0
 Res3               dd 0 
 ;
ends
Dim equ sizeof.INFOµP
    

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 07:48
View user's profile Send private message Send e-mail Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
My stupid computer is a 32 bit single core
how many times do i have to tell this?

Until i have this crappy computer i can make only single core 32 bit stuff...
let me some time and i'll change the computer.

I know the difference in a MULTI-CORE, but how can i check bugs with a single core?

This driver is the first pass...
For the work it have to do (Single core 32 bit) seems to be perfect


Last edited by Pirata Derek on 12 Jan 2010, 10:11; edited 1 time in total
Post 12 Jan 2010, 09:56
View user's profile Send private message Send e-mail Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
Pirata Derek: testing is obviously going to be a bit hard for you, but that doesn't mean you can't read up on how to support multicore Smile
Post 12 Jan 2010, 10:08
View user's profile Send private message Visit poster's website Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
Yes, but explain me how can you be sure if the code works correctly if you can't debug it in the right envoirment??????

if there's an error it will stay invisible until i prove it in a multi-core processor, or not?


Last edited by Pirata Derek on 12 Jan 2010, 10:22; edited 1 time in total
Post 12 Jan 2010, 10:18
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji
Quote:

but how can i check bugs with a single core ?

In the same way as with a multi-core
with a kernel debugger (syser, windbg)

Of course I can debug, i debug with Syser. is essential !

Quote:
it will stay invisible until i prove it in a multi-core processor, or not ?
>> yes, for some mistakes, of course!

_________________
I am not young enough to know everything (Oscar Wilde)- Image


Last edited by ouadji on 12 Jan 2010, 10:29; edited 3 times in total
Post 12 Jan 2010, 10:20
View user's profile Send private message Send e-mail Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
I know how can debug it, i'm using syser for years.

I'm telling another thing (read my last upper post)


Last edited by Pirata Derek on 12 Jan 2010, 10:29; edited 1 time in total
Post 12 Jan 2010, 10:25
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

ok ...
last Syser (1195) works fine !
multi-core kernel debugger .. I do a good job with it.

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 10:28
View user's profile Send private message Send e-mail Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
"last Syser (1195) works fine !
multi-core kernel debugger .. I do a good job with it. "

i'm agreee too Very Happy
Post 12 Jan 2010, 10:31
View user's profile Send private message Send e-mail Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
If you really wanted to test multicore code on a singlecore machine, you could test with one of the x86 emulators - not sure if they can catch all possible race conditions etc, especially not if each core is executed in-order...

QEMU has a built-in debugger iirc, and it has a GDB stub so you can connect GDB to it... or the IDA Pro debugger, if you have a GDB plugin for it. Haven't tried this myself, but it sounds pretty interesting; the ability to debug BIOS and kernel bootstraps... how cool is this? Smile
Post 12 Jan 2010, 13:32
View user's profile Send private message Visit poster's website Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
Thanks for the tip!

I don't know if QEMU will be able to make the same situation in a multi-core computer.

(I think no, because it is an HARDWARE-CONDITION...)
Post 12 Jan 2010, 14:48
View user's profile Send private message Send e-mail Reply with quote
Pirata Derek



Joined: 31 Oct 2008
Posts: 259
Location: Italy
Pirata Derek
To be sure that ALL the processors executes the HookAllIDT function (in my driver), the driver have only to use:

KeIpiGenericCall function, and check if the IDT gates are just hooked or not (if the cores have the same IDT)


Last edited by Pirata Derek on 12 Jan 2010, 15:41; edited 1 time in total
Post 12 Jan 2010, 15:21
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

Quote:
I think no, because it is an HARDWARE-CONDITION

I agree. Hard to really simulate multiple processors,
several IDTS, GDTS ... "MSRs" registers ...
This is no more totally "software", it's very tricky !


_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 15:32
View user's profile Send private message Send e-mail Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

Quote:
and check if the IDT gates are just hooked or not (if the cores have the same IDT)
Just go check with the debugger, no ?
PS : 4µPs =
4 different IDTs (in mémory) and 4 different IDTR (one in each µP).
also
4 different GDTs (in memory) and 4 different GDTR (one in each µP).


_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 12 Jan 2010, 15:35
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.