OVH Cloud OVH Cloud

AV et émulation du code: svp , explanations needed !

35 réponses
Avatar
NickJrIII
Bonjour les pros !
j'ai une questio plutôt technique pour nos boss de la programmation
antiviral:
qu'est ce que "savoir émuler le code" ?
Je suis tombé un jour sur

http://groups.google.fr/groups?hl=fr&lr=&ie=UTF-8&oe=UTF-8&threadm=3B49CA63.9A4612EE%40worldnet.fr&rnum=1&prev=/groups%3Fq%3D%25C3%25A9muler%2Ble%2Bcode%2Bnod32%26hl%3Dfr%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D3B49CA63.9A4612EE%2540worldnet.fr%26rnum%3D1

et sur un contest entre Bogdanov/Daniloff (AVP/Dr.Web) sur l'art de
programmer et les erreurs de programmation de leur logiciel respectif
(fascinant,même pour le profane que je suis, étudiant en droit, c'est
dire si je m'y connais...;-) ).
Je comprend donc que certains AV ont un moteur mieux programmé,alors
doit-on en déduire que le must en matière de moteur serait Dr.Web, AVP
et NOD32 ?

Enfin, sur un tout autre sujet, j'ai cru comprendre que NOD32
bénéficie d'un des meilleurs moteurs heuristiques: reality checked ?

Merci de votre patience pour éclairer un béotien (bon j'exagère quand
même !).

Sincerement,
Nick

10 réponses

1 2 3 4
Avatar
LaDDL
Nick Jr III wrote:
qu'est ce que "savoir émuler le code" ?


IHMO c'est de le faire travailler instruction par instruction.

Avatar
Arnold McDonald \(AMcD\)
Nick Jr III wrote:

qu'est ce que "savoir émuler le code" ?


Cela peut vouloir dire des tonnes de choses. En général, il s'agit
d'exécuter les instructions (ou de faire semblant) pour voir le comportement
du programme. Bien évidemment, dans un environnement clos, c'est à dire que
tu n'exécutes pas vraiment les instructions, tu regardes ce qu'elles font,
tu ne prends pas le risque de les exécuter pour éviter d'endommager
l'extérieur ;o).

Malheureusemnt ce procédé à de grosses limites et est facilement
contournable. On ne donnera pas ici de mauvaises idées aux SK en herbe,
mais, en gros, si tu parsèmes ton code de boucles de temporisation, si tu
fait du décryptage "brute force" pour décoder ton code, si tu exiges un peu
beaucoup de ressources, l'émulateur rendra vite la main, il n'a pas que ça à
faire...

--
AMcD

http://arnold.mcdonald.free.fr/
(still in fossilization progress but now in english, thus the whole
world can see my laziness)

Avatar
Frederic Bonroy
Nick Jr III wrote:

j'ai une questio plutôt technique pour nos boss de la programmation
antiviral:
qu'est ce que "savoir émuler le code" ?


Pfff... où commencer? :-)

Alors, commençons au tout début: un virus est un programme, et
un programme est une série d'instructions (pour le processeur
dans le cas d'un virus binaire; mais, plus généralement, une instruction
peut très bien être destinée aussi à un interprète de scripts par
exemple).

Dans la préhistoire virale, quand on voulait détecter un virus, on
regardait de quelles instructions il était constitué. A partir de cela
on créait une "signature", c'est-à-dire une chaîne d'octets
représentant une partie des instructions du virus. Je vous donne
un exemple: pour le virus Cascade, la signature utilisée par McAfee
était 141$FL, ce qui correspondait au bout de code suivant:

xor [si], si
xor [si], sp
inc si
dec sp

Evidemment, il fallait choisir la signature de manière à ne pas
provoquer de fausses alerts: il fallait donc une signature dont
on était à peu près sûr qu'elle n'apparaîtrait jamais dans un
programme propre. Il fallait aussi que la signature puisse identifier
le virus à chaque fois, et pas seulement un exemplaire particulier du
virus.

Seulement voilà, quelques années après les débuts sont apparus les
virus polymorphes. Ces virus sont capables de changer d'apparence.
Une seule signature ne suffisait donc plus; théoriquement il aurait
fallu une signature pour chaque version possible du virus. Or même
dans le cas d'un changement d'apparence réalisé par un simple
cryptage xor avec un seul octet on se serait retrouvé avec
255 signatures.

On a donc "exploité" une "faille" dans les virus polymorphes: en effet,
leur corps ne change pas - c'est uniquement la manière dont le corps
est crypté et le code de décryptage qui changent. Donc, s'il y a une
partie constante, on peut créer une signature.
Mais pour pouvoir appliquer la recherche de signatures il a d'abord
fallu trouver un moyen pour décrypter le corps du virus. Le meilleur
moyen de réaliser cela était l'émulation, c'est-à-dire qu'on dotait
l'antivirus d'un moteur capable de simuler en partie un ordinateur.
En fait un programme est donc exécuté à l'intérieur de l'antivirus,
sans aucun danger pour le vrai système à l'extérieur.
Donc, les virus se sont décryptés eux-mêmes et l'antivirus n'avait
plus qu'à chercher la signature. :-)

Donc l'émulation sert d'une part à la détection de virus qu'on ne
peut pas détecter avec une simple chaîne d'octets. D'autre part,
l'émulation permet d'obtenir au fur et à mesure de son progrès des
informations sur le comportement d'un programme, et ces informations
peuvent ensuite être utilisées pour l'analyse heuristique (c'est
l'analyse heuristique dynamique par opposition à l'analyse statique
qui consiste à rechercher des séquences de code sous forme de chaîne
et à effectuer d'autres analyses... statiques quoi).

Quant à savoir émuler correctement le code: une bonne émulation n'est
pas facile à programmer et elle peut être contournée assez facilement.
Il y a donc des différences de qualité entre les différents émulateurs.

Dans ce cas précis de Dr. Web contre Kaspersky, il s'agissait je crois
de l'émulation de l'instruction idiv qui sert à diviser deux nombres.
Il faut prendre en compte par exemple que l'on ne peut pas diviser par
zéro, que le résultat peut être trop grand pour résider dans la mémoire
interne du processeur, etc.

Avatar
Arnold McDonald \(AMcD\)
Frederic Bonroy wrote:

Pfff... où commencer? :-)


En général, par le début ;o)

Alors, commençons au tout début: un virus est un programme, et
un programme est une série d'instructions (pour le processeur
dans le cas d'un virus binaire; mais, plus généralement, une
instruction peut très bien être destinée aussi à un interprète de
scripts par exemple).


Houla, pas clair ça. Un script est interprété par l'OS (par un logiciel
habituellement appelé moteur de script). Au final, bien sûr les instructions
du moteur de script seront transformées en instructions processeur. Un
programme binaire n'a pas besoin du moteur. Donc :

script -> moteur -> instructions processeur
prog binaire -> instructions processeur

Dans la préhistoire virale, quand on voulait détecter un virus, on
regardait de quelles instructions il était constitué. A partir de cela
on créait une "signature", c'est-à-dire une chaîne d'octets
représentant une partie des instructions du virus. Je vous donne
un exemple: pour le virus Cascade, la signature utilisée par McAfee
était 141$FL, ce qui correspondait au bout de code suivant:

xor [si], si
xor [si], sp
inc si
dec sp


Attention, la signature est obtenue à partir des opcodes des instructions.
Les instructions du processeur c'est le microcode (hîn, hîn, j'aime bien
chipoter)

Evidemment, il fallait choisir la signature de manière à ne pas
provoquer de fausses alerts: il fallait donc une signature dont
on était à peu près sûr qu'elle n'apparaîtrait jamais dans un
programme propre. Il fallait aussi que la signature puisse identifier
le virus à chaque fois, et pas seulement un exemplaire particulier du
virus.


Et si possible faire en sorte qu'une modif du code n'ait pas besoin d'une
nouvelle signature. Quand on voit KAV qui aujourd'hui ajoute des signatures
par wagons, on sait que cela a échoué ;o).

Seulement voilà, quelques années après les débuts sont apparus les
virus polymorphes. Ces virus sont capables de changer d'apparence.


Pas tout à fait. La boucle de cryptage change, les instructions sont les
mêmes.

Une seule signature ne suffisait donc plus; théoriquement il aurait
fallu une signature pour chaque version possible du virus. Or même
dans le cas d'un changement d'apparence réalisé par un simple
cryptage xor avec un seul octet on se serait retrouvé avec
255 signatures.


Voire même plus.

On a donc "exploité" une "faille" dans les virus polymorphes: en
effet, leur corps ne change pas - c'est uniquement la manière dont le
corps est crypté et le code de décryptage qui changent. Donc, s'il y
a une partie constante, on peut créer une signature.


Eh oui. Les polymorphes c'est dur à mettre au point mais ça se détecte
facile.

Mais pour pouvoir appliquer la recherche de signatures il a d'abord
fallu trouver un moyen pour décrypter le corps du virus. Le meilleur
moyen de réaliser cela était l'émulation, c'est-à-dire qu'on dotait
l'antivirus d'un moteur capable de simuler en partie un ordinateur.
En fait un programme est donc exécuté à l'intérieur de l'antivirus,
sans aucun danger pour le vrai système à l'extérieur.
Donc, les virus se sont décryptés eux-mêmes et l'antivirus n'avait
plus qu'à chercher la signature. :-)


En clair, l'émulateur décrypte le virus et l'anti-virus voit le résultat.

Donc l'émulation sert d'une part à la détection de virus qu'on ne
peut pas détecter avec une simple chaîne d'octets.


Ou plus simplement à parfois voir ce que fait réellement un code douteux.

D'autre part,
l'émulation permet d'obtenir au fur et à mesure de son progrès des
informations sur le comportement d'un programme, et ces informations
peuvent ensuite être utilisées pour l'analyse heuristique (c'est
l'analyse heuristique dynamique par opposition à l'analyse statique
qui consiste à rechercher des séquences de code sous forme de chaîne
et à effectuer d'autres analyses... statiques quoi).


ouaip.

Quant à savoir émuler correctement le code: une bonne émulation n'est
pas facile à programmer et elle peut être contournée assez facilement.
Il y a donc des différences de qualité entre les différents
émulateurs.


En fait, il est virtuellement impossible d'écrire un émulateur exhaustif.

Dans ce cas précis de Dr. Web contre Kaspersky, il s'agissait je crois
de l'émulation de l'instruction idiv qui sert à diviser deux nombres.
Il faut prendre en compte par exemple que l'on ne peut pas diviser par
zéro, que le résultat peut être trop grand pour résider dans la
mémoire interne du processeur, etc.


Au fait il est où cet article, t'as un lien?

Bon j'arrête de t'embêter. En fait ma connexion réseau foire et je peupo
jouer sur le net, je m'em[buzz]de un peu là. Fallait bien que je fasse
quelque chose ;o)

--
AMcD

http://arnold.mcdonald.free.fr/
(still in fossilization progress but now in english, thus the whole
world can see my laziness)

Avatar
NickJrIII
"Arnold McDonald (AMcD)" wrote in message news:<3f2afe7c$0$14311$...


Au fait il est où cet article, t'as un lien?


pour AMcD:
http://madchat.org/vx/vxtuts/idiv_e.txt

Avatar
Frederic Bonroy
"Arnold McDonald (AMcD)" wrote:

Débat : l'apparence est-elle la forme ?


Oula.... je veux bien parler technique mais pas à ce niveau là
quand-même. Si on veut, il y a une différence entre apparence et
forme, mais dans notre contexte (forum où on explique leur
fonctionnement) les deux signifient la même chose.

C'est bon, grâce à Nick je viens de le lire. C'est nul.


Bah, c'est une idée intéressante. Au lieu de comparer les interfaces,
comparer l'émulation. :-)

Faut avouer aussi que ces temps-ci c'est pas folichon la lecture de ce NG.


Tu es libre de lancer des débats. :-)

Avatar
NickJrIII
Frederic Bonroy wrote in message news:<bgghlr$o6940$...


Bah, c'est une idée intéressante. Au lieu de comparer les interfaces,
comparer l'émulation. :-)



Désolé de poser cette question, mais peut-on en déduire qu'un AV qui
émule correctement le code est un bon AV au niveau programmation ?

dans ce cas, quels AVs sortent du lot ? (sur le plan de la qualité de
prog)
Dr.Web ?
AVP ?
NOD32 ?
J'ai l'impression ,grâce à vos explications, que l'émulation est
difficile à réaliser...cela réduit donc le nombre des AVs bien
réalisés me semble t-il...
Je vous remercie de vos réponses qui m'éclairent ! :-)
Merci

Nick

Avatar
Frederic Bonroy
Nick Jr III wrote:

Désolé de poser cette question,


Mais non! C'est mieux que les "mon Norton veut pas se mettre à jour"!

mais peut-on en déduire qu'un AV qui émule correctement le code est
un bon AV au niveau programmation ?

dans ce cas, quels AVs sortent du lot ? (sur le plan de la qualité de
prog)
Dr.Web ?
AVP ?
NOD32 ?
J'ai l'impression ,grâce à vos explications, que l'émulation est
difficile à réaliser...


On se retrouve face à plusieurs problèmes quand on veut faire une
bonne émulation:

1. La vitesse.
Les instructions x86 sont complexes et il ne suffit pas de les exécuter,
il faut bien évidemment les décoder avant. Les décoder signifie qu'il
faut effectuer un tas d'opérations au niveau des bits sur les différents
octets qui constituent une instruction. En plus de ça le codage n'est
pas toujours très logique (il est même bordellique, excusez
le vocabulaire). Merci Intel.
J'ai lu il y a longtemps qu'AVG était capable d'émuler 100.000
instructions par seconde sur un Pentium 100. Cela revient donc à 1000
cycles du vrai processeur pour émuler une seule instruction.
Certains auteurs de virus sont conscients de la contrainte du temps et
font exécuter un tas d'instructions inutiles à leur virus. Sur un vrai
processeur on ne s'en apercevra pas (puisqu'on parle du Pentium 100, il
est capable, en (très) gros d'exécuter environ, je dis bien environ,
100.000.000 instructions à la seconde. Dans certains cas il peut
exécuter 2 instructions par cycle, mais beaucoup d'instructions peuvent
prendre de 10 à 20 cycles). Donc à en croire ces chiffres un émulateur
est 1000 fois plus lent qu'un vrai processeur.
L'émulateur ne peut pas émuler infiniment longtemps; s'il s'arrête avant
d'être parvenu au virus proprement dit, le virus ne sera pas détecté.

2. La complexité.
Il existe des centaines d'instructions pour le processeur, avec
plusieurs modes d'accès à la mémoire différents, avec des instructions
différentes pour plusieurs types d'opérations: opérations "normales",
coprocesseur pour opérations mathématiques, opérations MMX, SSE et
3Dnow.
Beaucoup d'émulateurs n'émulent pas toutes ces instructions. Insérer une
seule instruction inconnue peut faire foirer l'émulation.
Ensuite, la gestion de la mémoire est très complexe en mode protégé.

3. La complexité bis.
Les systèmes d'exploitation modernes proposent des centaines de
fonctions différentes. Il est presque impossible de toutes les émuler.

4. Encore la complexité.
Les virus peuvent se servir de fonctions non-documentées du matériel
ou du système d'exploitation.

5. Choix.
Supposez que le programme que vous émulez compare deux valeurs. Si
A > B, il vous fait sauter à l'adresse x, si A <= B, vous sautez
à l'adresse y. Le problème c'est que dans certains cas vous ne
connaissez pas les valeurs de A et B, par exemple quand ces valeurs
représentent la date ou l'heure actuelle. Peut-être que le virus
ne se met en route que le deuxième mercredi des mois impairs? Vous
devez donc poursuivre l'émulation aussi bien à l'adresse x qu'à
l'adresse y, donc il vous faut mémoriser d'où vous venez pour pouvoir
y retourner plus tard.

cela réduit donc le nombre des AVs bien réalisés me semble t-il...


Aucun antivirus sérieux ne peut se passer d'émulation de nos jours.
C'est impensable. Il y a de bonnes émulations et des émulations de
qualité un peu inférieure. Mais en général écrire une émulation,
ce n'est pas du n'importe quoi.

Avatar
Roland Garcia

Désolé de poser cette question, mais peut-on en déduire qu'un AV qui
émule correctement le code est un bon AV au niveau programmation ?


Tout dépend de ce que vous entendez par programmation.

L'algorithme permettant d'émuler le code est indépendant de l'OS. Vous
pouvez donc avoir le meilleur système d'émulation et un anti-virus mal
programmé incapable de fonctionner sur un OS.

AVP en 1995 était un très bon exemple. Il était le seul à émuler
correctement mais le seul ne sachant pas fonctionner sous Windows 95,
seule la version DOS était viable.


dans ce cas, quels AVs sortent du lot ? (sur le plan de la qualité de
prog)
Dr.Web ?
AVP ?
NOD32 ?


Normalement tous les anti-virus actuels devraient émuler presque
parfaitement. Les meilleurs ont un taux de détection des virus
polymorphes de quasi 100% dans tous les tests.

J'ai l'impression ,grâce à vos explications, que l'émulation est
difficile à réaliser...


Certainement puisque certains n'y arrivent pas encore, mais ça marche.

Roland Garcia

Avatar
Roland Garcia

2. La complexité.
Il existe des centaines d'instructions pour le processeur, avec
plusieurs modes d'accès à la mémoire différents, avec des instructions
différentes pour plusieurs types d'opérations: opérations "normales",
coprocesseur pour opérations mathématiques, opérations MMX, SSE et
3Dnow.


Amha ces instructions sont plutôt élaguées.....

Il y avait eu un virus de Benny utilisant des instructions MMX, ça n'a
pas l'air d'avoir pris.

Roland Garcia

1 2 3 4