Les Anti Soft-Ice

         
       

By PuLsar

Suite au petit essai sur softice que j'avais écrit; j'ai pensé que certains d'entres vous pourrez être interressés par la méthode qui etait utilisée pour passer en ring0 dans mes routines S_DRx et S_DRxP; bien que ma routine RingZero soit assez transparente pour l'utilisateur :)

On va commencer par parler un peu de l'IDT.
En gros l'IDT (Interrupt Descriptor Table) est comme son nom l'indique la table ou sont stockées les addresses correspondantes aux interruptions...

Le mieux est de prendre pour exemple la bien connue int 03h. Quand le processeur rencontre un int il va voir dans l'IDT quelle routine gère cette interruption puis l'appelle... Rien de franchement fabuleux ici, sauf qu'il l'appelle en ring0. En arrivant à remplacer la fonction originale par la notre, on peut utiliser du code
en ring0 dans nos programmes normalement limité au ring3 (belles perspectives n'est-ce-pas :))

Regardons un dump des premiers bytes de mon IDT (les votres peuvent être différentes)
(en utilisant la commande dd dans softice vous n'aurez pas a inverser l'ordre des bytes pour trouver les bonnes valeurs)

0030:C000D474 00281350 C0008E00 0028AFDA C00EEE00 P.(.......(.....
0030:C000D484 00288BF6 C0038E00 0028AFE0 C00EEE00 ..(.......(.....
0030:C000D494 0028AFE7 C00EEE00 0028AFEF C00EEE00 ..(.......(.....
0030:C000D4A4 00288C14 C0038E00 002813B0 C0008E00 ..(.......(.....
0030:C000D4B4 00680000 00008500 00288CAA C0038E00 ..h.......(.....
0030:C000D4C4 002813E0 C0008E00 00288C23 C0038E00 ..(.....#.(.....
0030:C000D4D4 0028E7C4 C0028E00 00288C41 C0038E00 ..(.....A.(.....
0030:C000D4E4 00288C50 C0038E00 00288CB9 C0038E00 P.(.......(.....
0030:C000D4F4 00284720 C000EE00 00284728 C000EE00 G(.....(G(.....
0030:C000D504 00284730 C000EE00 00284738 C000EE00 0G(.....8G(.....
0030:C000D514 00284740 C000EE00 00284748 C000EE00 @G(.....HG(.....
0030:C000D524 00284750 C000EE00 00284758 C000EE00 PG(.....XG(.....
0030:C000D534 00284760 C000EE00 00284768 C000EE00 `G(.....hG(.....
0030:C000D544 00284770 C000EE00 00284778 C000EE00 pG(.....xG(.....

L'IDT réserve 8 bytes pour chaque interruption differente
Ce qui donne quelque chose dans ce gout là pour chaque ligne:

Lowword de la routine de l'int (n+1)___________
                                    |      ____________ high word de la routine (n+1)
                                   _|__ __|_	
             XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
                 ---- ----
Lowword de la routine___|	  |_____high word
	qui gere l'int n

En sachant que la premiere int est l'int0, on en deduit que les bytes concernants l'interrupt 03h sont les suivants:

0028AFE0 C00EEE00

On trouve que le lowword de notre routine est AFE0 et le highWord C00E, ce qui nous fait une adresse egale a C00EAFE0

(Remarque:pour trouver sous softice l'offset à laquelle est située l'IDT, faites IDT puis d IDT_base_donne_par_softice)
Bien, maintenant il va falloir essayer de changer ces valeurs pour les remplacer par les notres....

Il est possible de modifier un peu le code de Stone pour obtenir une fonction transparente permettant de passer en Ring0:

RingZero proc Fct_Address:DWORD

sidt  fword ptr IDT                      ;on obtient l'IDT
mov   ebx, dword ptr [IDT+2]             ;ebx=IDT base
add   ebx, 8*ExceptionUsed               ;ebx=selector pour l'int recherchee
cli                                      ;clear interupts

                                         ;On sauvegarde l'ancienne routine
mov   dx, word ptr [ebx+6]               ;le highword
shl   edx, 16d
mov   dx, word ptr [ebx]                 ;le lowword
mov   [OldGate], edx
mov   eax, Fct_Address                   ;on installe notre routine
mov   word ptr [ebx], ax                 ;le lowword
shr   eax, 16d
mov   word ptr [ebx+6], ax               ;le highword

int   ExceptionUsed                      ;on passe en ring 0 :)))
  
mov   ebx, dword ptr [IDT+2]             ;on restore la vielle routine
add   ebx, 8*ExceptionUsed
mov   edx, [OldGate]
mov   word ptr [ebx], dx
shr   edx, 16d
mov   word ptr [ebx+6], dx

ret
RingZero ENDP

On a donc une fonction parfaitement operationnelle prenant comme parametre d'entrée l'offset de la routine que nous voulons utiliser en ring0.
On l'utilisera alors comme suit

push offset Ring0Proc
call RingZero

Ring0Proc:
mov eax,dr7                         ;par exemple :)

iretd           ;ne pas oublier le iretd tres important sinon vous allez tout planter :)

Greetz to:
Christal,Alsindor,Frog's Print,Spath,Acid_Burn,Stone,G-ROM,Elraizer,DXP,Fravia,ShroOm
Iczelion,ArseniK,Lucifer48,DXP,Nody,TeeJi,TaiefOon...and the others i've forgotten :)

Vous pouvez me joindre si vous avez des questions (ou si vous avez des sources asm a faire partager :))
pulsar_c@geocities.com UIN:13411849

Pulsar Decembre 1999