• Aucun résultat trouvé

Processus d’exécution d’un bytecode

Notre approche étant basée sur une analyse statique, elle effectue une analyse dubytecodesans l’exécuter réellement. Elle se base sur la simulation de toutes les structures de données que génère la JCVM, dans l’exécution d’un programme.

Une JCVM est une machine abstraite définie par une spécification. Elle permet d’exécuter des bytecodeJava Card. Lors de son lancement, la JCVM initialise les espaces de données nécessaires à l’exécution du programme. Le tas (Heap) et l’espace des méthodes sont les principaux espaces.

Chaque thread du bytecode possède une pile privée où sont sauvegardées les frames. Une frame est créée à chaque invocation d’une méthode. Elle consiste en une pile d’opérandes, un tableau de variables locales et une référence au pool de constantes de la classe de la méthode courante.

Fig. 5.2 – Représentation des structures de la JCVM

5.3.1 Zones de données

La mémoire de la machine virtuelle est organisée en zones de données dont : le tas, la zone de méthodes et les piles Java (pile dethreads) permettant de stocker différents types de données tels que les objets créés, les variables locales de méthodes, les opérandes des méthodes, les valeurs de retour de méthodes, etc. Il existe aussi des piles de méthodes natives pour les codes natifs appelés par les applications Java.

Certaines zones sont créées au démarrage de la JCVM et sont détruites seulement lorsque celle-ci est arrêté. D’autres zones de données sont utilisées pour chaque thread, et ont la même durée de vie que lethread associé. Dans ce qui suit, nous présentons brièvement ces différents espaces de stockage de données.

1. Le registre PC (program counter)

La machine virtuelle peut exécuter plusieurs threads à la fois. Chaque thread possède son propre PC. Quand le thread exécute une méthode, PC indique l’adresse de la prochaine instruction dubytecodeà exécuter.

2. La pile de la JCVM

Chaque thread de la JCVM dispose d’une pile privée, créée en même temps que lethread.

La pile est composée d’un ensemble de frames [Apa06]. À chaque invocation de méthode, une nouvelle frame est créée et empilée au sommet de la pile Java duthreadassocié. Elle est dépilée et détruite à la fin de l’exécution de la méthode.

3. Le tas

C’est une zone mémoire commune à tous lesthreadsde la machine virtuelle, où sont stockés tous les objets instances de classes ou de tableaux. A chaque objet d’instance est associée une référence qui permet d’accéder aux valeurs de chaque champ et aux méthodes associées à la classe de l’objet. La libération d’espace dans le tas est gérée automatiquement par le ramasse-miettes.

4. Zone des méthodes

La JCVM possède un espace de méthodes qui est partagé par tous les threads. Cet espace contient le bytecode des méthodes, les constructeurs et des informations telles que la table des symboles de constantes, tables de méthodes, champs de classe. Elle contient aussi les informations de typage sur les objets (nom, modificateur, nom de la superclasse, nombre et noms des interfaces implémentées, nombre de méthodes) et pour chaque méthode, un descripteur (nom, modificateur, nombre et type de paramètres, type du résultat, table des exceptions, etc.)

5. La table des constantes

La table des constantes est allouée dans la zone des méthodes, pour chaque classe ou interface créée par la machine virtuelle Java. Elle contient plusieurs sortes de constantes telles que les valeurs de chaînes de caractères, les valeurs de constantes entières, noms symboliques de classes, interfaces, méthodes, les variables de classe ou d’instance, etc.

6. La pile des méthodes natives

Les méthodes natives sont des méthodes écrites dans un autre langage que Java (C/C++, assembleur) et compilées vers un langage natif de la machine sous-jacente. Ces méthodes

sont chargées dynamiquement lors d’une invocation par un programme Java. Notre analyse ne s’étend pas à ce type de méthodes. Nous nous limitons aux méthodes définies dans l’ap-plication analysée.

5.3.2 La frame

Une frame est générée à chaque invocation d’une méthode. Elle permet de stocker des données nécessaires à l’exécution de la méthode et/ou des résultats partiels de méthodes (des valeurs de retour ou des exceptions). Elle est composée d’un ensemble de structures de données à savoir :

La table de variables locales: stocke les paramètres et les variables locales de la méthode.

Les variables locales sont adressées par index. L’index de la première variable locale est 0.

Les valeurs de type long ou double occupent deux variables locales consécutives. Lors de l’invocation d’une méthode d’instance, la variable locale d’index 0 est utilisée pour référencer l’objet sur lequel la méthode a été invoquée (this en langage Java) et les variables locales sont indexées de manière consécutive à partir de l’index 1.

La pile des opérandes : contient les résultats partiels des calculs intermédiaires ou des valeurs de retour d’invocation d’autres méthodes.

Des informations complémentaires: il peut s’agir d’un registre contenant l’adresse de la prochaine instruction à exécuter, appelé communémentprogram counter(pc), d’une référence vers la table des constantes de la classe à laquelle appartient la méthode, d’une référence vers la table d’exceptions de la méthode, etc.

5.3.3 Les instructions de la JCVM

Notre analyse étant basée sur une interprétation abstraite de l’exécution du bytecode, il est nécessaire de connaitre les différentes instructions d’un bytecode et comment ces dernières sont interprétées dans la JCVM.

Une instruction de la machine virtuelle Java est composée d’unopcode sur un octet, spécifiant l’opération à effectuer, suivi par zéro ou plusieurs opérandes servant d’arguments qui seront utilisés par l’opération. Pour une grande partie desopcodes, le mnémonique qui leur est associé est préfixé par une lettre représentant le type de la donnée associée à ces instructions. Par exemple, la lettre

"i" correspond à la manipulation d’une donnée de type « integer » (entier signé de taille 32 bits signé). Dans ce qui suit, nous présentons quelques exemples d’instructions.

Instructions de chargement et de stockage

Les instructions de chargement et de stockage permettent de transférer les valeurs entre les variables locales et la pile d’opérandes d’une frame de la JCVM. Ces instructions peuvent être classées comme suit :

1. Instructions de chargement de variables locales dans la pile des opérandes : iload, iload_N, lload, lload_N, fload, fload_N, dload, dload_N, aload, aload_N.

2. Instructions de chargement d’une valeur depuis la pile des opérandes vers une variable locale : istore, istore_N, lstore, lstore_N, dstore, dstore_N, astore, astore_N.

3. Instructions de chargement de constantes dans la pile des opérandes : bipush, sipush, ldc, ldc_w, ldc2_w, aconst_null, iconst_m1, iconst_N, lconst_N, dconst_N.

4. Les instructions qui accèdent aux champs des objets :(putstatic, getstatic, putfield, getfield) et aux éléments des tableaux (baload, caload, saload, iaload, laload, daload, aaload, bas-tore, casbas-tore, sasbas-tore, iastore lasbas-tore, dasbas-tore, aastore), ces instructions transfèrent aussi des données depuis et vers la pile des opérandes.

Le format des instructions avec des lettres génériques N désigne des familles d’instructions spécifiques à une instruction générique qui ne prend qu’un paramètre.

Instructions de manipulation de la pile d’exécution

Ces instructions permettent de manipuler directement le sommet de la pile : pop, pop2, dup, dup2, dup_x1, dup2_x1, dup_x2, dup2_x2, swap.

Les instructions arithmétiques

Les instructions arithmétiques prennent deux valeurs sur la pile des opérandes et chargent le résultat au-dessus de cette même pile. Parmi ces instructions :

– Addition :iadd, ladd, dadd.

– Soustraction :isub, lsub, dsub.

– Multiplication :imul, lmul, dmul.

– Division :idiv, ldiv, ddiv.

– Reste (modulo) :irem, lrem, drem.

– OR (bit à bit) :ior, lor.

– AND (bit à bit) :iand, land.

– XOR (bit à bit) :ixor, lxor.

– Incrémentation des variables locales :iinc.

– Comparaison :dcmpg, dcmpl, lcmp.

Création d’objet

La machine virtuelle crée les instances de classe et les tableaux de façon distincte avec un jeu d’instructions propre à chacun :

– Création d’une nouvelle instance de classe :new.

– Création d’un nouveau tableau :newarray, anewarray, multianewarray.

Les instructions de branchement

Les instructions de branchements conditionnels ou inconditionnels permettent à la JCVM de continuer à s’exécuter avec une instruction différente de celle suivant l’instruction de branchement.

Les instructions de branchement sont :

– Branchement conditionnel : ifeq,iflt, ifle, ifne,ifgt, ifge, ifnull, ifnonnull,

if_icmpeq, if_icmpne,if_icmplt,if_icmpgt, if_icmple, if_icmpge, if_acmpeq, if_acmpne.

– Branchement conditionnel composé :tableswitch, lookupswitch.

– Branchement inconditionnel :goto, goto_w, jsr, jsr_w, ret.

Instructions d’invocation de méthode

Les instructions suivantes permettent d’invoquer une méthode :

Invokevirtual : invoque une méthode d’un objet, en appelant la bonne méthode virtuelle de l’objet.

Invokeinterface: invoque une méthode qui est implémentée par une interface, en cherchant les méthodes implémentées par cet objet pour trouver la méthode appropriée.

Invokespecial: invoque une instance qui requiert un traitement spécial ; une méthode d’ini-tialisation d’instance, une méthode privée, ou une méthode de la super classe.

Invokestatic: invoque une méthode de classe statique.

Les instructions de retour de méthodes

Elles se distinguent par leur type de données de retour. L’instructionreturn est utilisée pour un retour depuis des méthodes déclarées void, des méthodes d’initialisation d’instance, et des méthodes d’initialisation de classe ou d’interface. les instructionsdreturn, areturnet ireturn sont utilisées pour retourner des valeurs de typeboolean, byte, char, short, ou int.

Lancement d’exception

Une exception est lancée par le programme en utilisant l’instructionathrown ou par d’autres instructions de la JCVM lorsqu’une condition inhabituelle est détectée (par exemple, la division par zéro).