FR 3056787 A1 20180330 FR 1670555 A 20160927 METHODE DE PROTECTION D'UN PROGRAMME LOGICIEL PAR OFFUSCATION PAR VIRTUALISATION DOMAINE DE L'INVENTION La présente invention concerne une méthode de protection d'un programme logiciel. La méthode selon l'invention procède par offuscation du code dudit programme. L'offuscation de ce code est effectuée au moyen d'une virtualisat ion. ART ANTERIEUR L'ingénierie inverse d'un programme logiciel est classiquement réalisée par des attaquants qui procèdent par analyse statique de ce programme logiciel, ou par 15 analyse dynamique de celui-ci. L'analyse statique consiste à lire et analyser le programme logiciel « à plat », c'est-à-dire à tenter de récupérer ce programme logiciel dans sa version 20 exécutable, soit la version livrée et disponible pour l'analyste, en blocs intelligibles, et à en faire l'analyse. La lecture est effectuée sans recourir à l'exécution du programme logiciel. Le seul outil nécessaire à l'attaquant est la connaissance du langage 25 du logiciel dans sa forme exécutable. Il peut s'agir de l'assembleur si l'analyse est effectuée sur un exécutable natif, c'est à dire correspondant à une machine réelle spécifique par exemple de type IntelTM X86 ou ARMTM7, ou d'un bytecode pour un langage interprété correspondant à 30 une machine virtuelle telle que JavaTM ou .NETTM. Pour faciliter l'analyse, il est possible de produire des transformations dans le programme logiciel dans sa forme 3056787 2 exécutable en vue, par exemple, de disposer d'une forme plus abstraite de ce programme logiciel et de se rapprocher du programme dans sa forme en code source. Cela est effectué à l'aide d'un décompilateur. 5 L'analyse dynamique consiste par contre à tracer, au travers de l'exécution du code, chacune des instructions exécutées, ainsi que les modifications engendrées dans la mémoire et les registres de travail du processeur, 10 lorsque ces registres existent. L'outil utilisé pour cette analyse est un débogueur. Le débogueur met en oeuvre une instrumentation du programme, qui permet notamment de mettre en place des points d'arrêt dans l'exécution du programme logiciel. Il permet de récupérer la trace de l'exécution du code, c'est-à-dire la séquence des instructions exécutées et les états de la mémoire de travail du processeur associés à chaque instruction. On connaît des méthodes qui permettent de contrer les attaques procédant par analyse statique d'un programme logiciel. Ces méthodes ont pour but de faire en sorte que le programme logiciel ne se trouve jamais « en clair » en mémoire. Le programme est donc chiffré. Néanmoins, si les techniques de chiffrement interdisent effectivement l'analyse statique, le programme doit au moins être déchiffré pour son exécution. Le chiffrement de code ne présente donc qu'une défense relative et, via l'analyse dynamique, l'attaquant pourra pointer l'état de la mémoire correspondant au fichier déchiffré et le récupérer pour produire une analyse du programme alors « en clair ». On connaît de même des méthodes qui permettent de contrer les attaques procédant par analyse dynamique d'un 35 programme logiciel. Toutefois, quelles que soient ces 3056787 3 méthodes, on notera que, dès lors qu'il est possible de relier la machine portant le programme logiciel à un débogueur, il devient très difficile d'interdire une telle analyse. Certaines méthodes proposent de bloquer 5 l'usage de débogueurs mais elles sont très pénalisantes pour les utilisateurs licites et peu efficaces, car contournables. En pratique, pour contrer l'analyse dynamique, il convient de la ralentir à un niveau tel que le niveau d'effort pour la réalisation de l'ingénierie 10 inverse devienne rédhibitoire par un accroissement colossale de la taille du code à tracer et, dans la mesure du possible, sans qu'il soit possible de réduire cette taille par l'utilisation de résultats d'analyse antérieurement acquis. Pour ce faire, les méthodes selon 15 l'art antérieur proposent bien souvent au moins de générer une certaine variabilité dans la génération de ce code. Les méthodes procédant par offuscation de programmes 20 logiciels permettent de rendre les analyses statique et dynamique beaucoup plus complexes. Certaines de ces méthodes proposent d'offusquer le code en produisant des transformations prédéfinies sur celui-ci et en substituant des séquences du code initial avec des 25 séquences plus complexes. D'autres méthodes proposent du chiffrer certains blocs du code exécutable. De telles méthodes procédant par chiffrement partiel nécessitent cependant que le code chiffré soit déchiffré avant exécution. D'autres méthodes encore proposent de 30 virtualiser le code. La mise en oeuvre des méthodes précitées peut être effectuée à différents stades dans la chaîne de génération du programme exécutable et, en particulier, au 35 stade du développement du code source par le développeur, 3056787 4 plus particulièrement au stade de sa compilation au moyen d'un compilateur spécifique qui produit l'offuscation et génère les séquences de code offusqué, ou alors, dans un stade plus avancé, où on dispose du programme logiciel 5 lui-même, sous une forme exécutable. Par ailleurs, la mise en oeuvre de ces méthodes peut être effectuée pour des chaines de génération de programmes logiciels natifs, c'est-à-dire résultant d'un code 10 binaire structuré pour un processeur particulier, ou pour une chaine de génération de langage interprété tel que le langage JavaTM ou .NETTM. Les méthodes procédant par virtualisation de code 15 proposent de transformer le code du programme logiciel à protéger en un code intermédiaire virtualisé ou bytecode, qui n'est pas directement exécutable sur la machine portant le programme. Ces méthodes sont connues pour être mises en oeuvre sur des programmes logiciels interprétés 20 du type JavaTM, .NETTM ou PythonTM. Le bytecode est alors décodé par une machine virtuelle comprenant des exécuteurs qui déchiffrent chaque ligne du bytecode à la volée. Toutefois, dans le cas des langages interprétés, la syntaxe de la machine virtuelle et la structure du 25 bytecode sont connues de tous et, notamment, des attaquants. Dans le cas de la virtualisation appliquée à l'offuscation, la syntaxe de la machine virtuelle et la structure du bytecode sont par contre inconnues de l'attaquant. En effet, cette syntaxe est produite à 30 chaque utilisation de la machine virtuelle. De manière générale, la virtualisation de code consiste donc à transformer le programme à protéger en un code intermédiaire virtualisé et une machine virtuelle qui n'a rien en commun avec le programme original. La machine virtuelle décode le bytecode, qui est un fichier de 3056787 5 données comprenant la fonctionnalité du code original. Elle interprète ce bytecode. La virtualisation conduit donc à une déstructuration massive et globale du programme original. Ainsi, si un attaquant réalise une 5 analyse statique, il bute sur la machine virtuelle, car c'est le logiciel qui est exécuté, et non plus le code original. Les méthodes procédant par virtualisation de code sont 10 connues pour présenter un très bon niveau d'offuscation. Cela provient en particulier de la très grande variabilité dans la génération du code qu'elle permet d'obtenir, qui réduit d'autant la capacité de l'attaquant de capitaliser son travail d'analyse. Par la génération 15 hautement variable des séquences de code pour une même instruction originale, le principe est d'éviter la reproduction de séquences identiques qui permettrait à l'analyste de traiter en une seule analyse toutes ces séquences identiques. 20 Toutefois, ces méthodes sont connues pour engendrer une grande expansion du code exécuté et donc pour être consommatrice de temps machine sur le processeur, aboutissant à une dégradation des performances du 25 logiciel et notamment de sa vitesse d'exécution. Dans le cas où le code est dans un langage interprété, et où la machine virtuelle et le bytecode sont connus, alors l'offuscation peut être réalisée par un étage de 30 virtualisation supplémentaire et, par suite, par la mise en cascade de deux machines virtuelles. Dans ce cas, les pertes en termes de performance du programme logiciel sont particulièrement conséquentes. C'est la raison pour laquelle, en pratique, l'offuscation de programmes 35 logiciels déjà virtualisés n'est pas mise en oeuvre. 3056787 6 Finalement, bien que les méthodes d'offuscation par virtualisation de code selon l'art antérieur soient performantes en termes de protection, leur usage est 5 restreint à certains cas précis. Elles n'ont pas pu être mise en oeuvre de manière pertinente dans de vastes domaines où les besoins de protection sont pourtant réels. Il s'agit, à titre d'exemple, du secteur défense où les contraintes de vitesse d'exécution sont au coeur de 10 l'efficacité opérationnelle des systèmes, et qui requièrent une parfaite maîtrise de l'impact des moyens de protection sur le délai d'exécution du logiciel. Ainsi, sans visibilité sur la dégradation de performance et sans moyen d'ajustement du niveau d'offuscation et du 15 périmètre sur lequel elle s'applique, la virtualisation de code n'est pas utilisable, notamment, dans le secteur de la défense. RESUME DE L'INVENTION 20 Considérant ce qui précède, un problème que se propose de résoudre l'invention est de fournir une méthode permettant d'offusquer un programme logiciel par virtualisation en limitant les dégradations de 25 performance de ce programme logiciel ou, à tout le moins, d'avoir un contrôle sur cette dégradation de performances associée à l'offuscation par virtualisation. La solution proposée de l'invention à ce problème a pour 30 objet une méthode de protection d'un programme logiciel initial par offuscation par virtualisation comprenant les étapes suivantes selon lesquelles : on fournit une ou plusieurs machines virtuelles, la ou lesdites machines virtuelles ayant été générées 35 indépendamment dudit programme logiciel initial ; 3056787 7 on fournit le programme logiciel initial, ce programme comprenant un jeu d'instructions exécutable ou en code source ; on réalise une transformation du programme logiciel 5 initial dans une représentation intermédiaire ; on analyse le programme logiciel initial dans sa représentation intermédiaire et on identifie un ou plusieurs blocs d'instructions indépendants ; on associe une machine virtuelle à chaque bloc 10 d'instructions indépendant identifié ; on compile l'association entre la représentation intermédiaire et la ou les machines virtuelles en vue d'obtenir un bytecode; on estime la part contributive individuelle de 15 chaque instruction du programme logiciel initial dans un temps d'exécution de ce programme, une fois que le ou les blocs d'instructions sont offusqués par virtualisation en association avec la ou les machines virtuelle. sur la base de cette part contributive, on 20 sélectionne des instructions dans le programme logiciel initial à exclure de l'offuscation par virtualisation ; on compile le programme logiciel initial de manière à générer un nouveau bytecode qui offusque les instructions non-sélectionnées dudit programme logiciel 25 initial par virtualisation ; la ou les machines virtuelles interprètent le nouveau bytecode généré pour l'exécution des instructions non-sélectionnées ; et Les instructions sélectionnées sont exécutées de 30 manière séparée de l'exécution des instructions non-sélectionnées. De manière avantageuse, - on fournit une pluralité de machines virtuelles, lesdites machines ayant été 35 générées indépendamment du programme logiciel initial, on 3056787 8 identifie une pluralité de de blocs d'instructions indépendants dans le programme logiciel initial, et on associe une machine virtuelle différente à chaque bloc identifié, de sorte à paralléliser l'exécution desdits 5 blocs, notamment par des demandes d'octroi de disponibilité sur un coeur de traitement pour un bloc particulier de manière à favoriser l'emploi d'autres coeurs de traitement pour d'autres blocs mettant en oeuvre une parallélisation des traitements ; - la méthode 10 comporte en outre une étape d'analyse de la machine cible destinée à exécuter programme logiciel protégé par offuscation par virtualisation en vue de déterminer un nombre de coeurs de traitement disponibles sur cette machine, et en ce que le nombre de machines virtuelles 15 et/ou blocs est déterminé en fonction de ce nombre de coeurs disponibles pour la parallélisation des traitements ; - la part contributive individuelle de chaque instruction du programme logiciel initial dans le temps d'exécution de ce programme, une fois le ou les 20 blocs d'instructions offusqués par virtualisation en association avec la ou les machines virtuelles dépend d'un taux d'expansion du code desdites instructions lors de l'offuscation par virtualisation, et/ou d'un nombre d'exécutions de cette instruction obtenu par une 25 exécution du programme initial ; - les instructions sélectionnées comprennent des instructions de boucle de programme, imbriquées ou indépendantes ; - l'estimation de la part contributive de chaque instruction du programme logiciel initial dans un temps d'exécution de 30 ce programme, une fois le ou les blocs d'instructions offusqués par virtualisation en association avec la ou les machines virtuelles est présentée à un opérateur, qui effectue la sélection des instructions dans le programme logiciel initial à exécuter par une machine réelle avec 35 une reconstruction dynamique du code de ces instructions 3056787 9 ou par remplacement dans le logiciel original de séquences de code par simple offuscation ou sans aucune protection ; - en complément ou en remplacement des parts individuelles contributives présentées à l'opérateur, on 5 présentes les boucles dans le programme original pour permettre notamment leur suppression de la virtualisation ; - les instructions sélectionnées, exécutées de manière séparées, font l'objet d'une exécution sans protection, d'une offuscation simple ou 10 d'une méthode de reconstruction de code dynamique ; - le code des instructions sélectionnées par le mode de reconstruction dynamique, est reconstruit par un module de reconstruction qui génère le code au fil de l'exécution du programme, juste avant leurs exécutions 15 puis une fois leurs exécutions produites, réalise les opérations inverses de telle manière que les instructions ne sont présentes en clair que durant un lapse de temps très succinct ; - les suppressions d'instructions du traitement de virtualisation sont réalisées de manière 20 automatique, sans intervention de l'opérateur, par la mise en place de seuils sur différents critères portant sur les informations disponibles ; - la sélection des suppressions d'instructions du traitement de virtualisation est réalisée de façon automatique sur la 25 base de critères ou proposée à un opérateur pour validation ; et - la sélection des suppressions d'instructions du traitement de virtualisation est réalisée de façon automatique sur la base de critères résultant d'un paramétrage produit antérieurement par un 30 opérateur sur un projet de protection correspondant à une version antérieure du logiciel à protéger. BREVE DESCRIPTION DES FIGURES 3056787 10 L'invention sera mieux comprise à la lecture de la description non limitative qui suit, rédigée au regard des dessins annexés, dans lesquels : la figure 1 schématise des premières étapes de la 5 méthode selon l'invention ; et la figure 2 schématise des secondes étapes de la méthode selon l'invention. DESCRIPTION DETAILLEE DE L'INVENTION 10 La présente invention concerne une méthode de protection d'un programme logiciel initial (ou partie de ce programme logiciel). Cette protection est effectuée par offuscation par virtualisation. 15 Un tel programme logiciel est destiné à être exécuté par une machine munie d'un processeur. Le processeur est par exemple un processeur d'un ordinateur tel qu'un ordinateur personnel, d'une plateforme embarquée telle 20 que, par exemple, une plateforme embarquée d'un téléphone intelligent, d'objets connectés, ou même d'une carte à puce, disposant notamment de mémoires, par exemple d'une mémoire dite morte et d'une mémoire dite vive, pour le stockage et l'exécution du programme, ainsi que de 25 systèmes de bus d'adresses et de données. Un tel programme peut être dans sa version en langage de programmation ou code source ou dans sa version après compilation, c'est-à-dire dans sa version destinée à être exécutée sur un type de processeur spécifique ou une 30 machine virtuelle telle que la machine virtuelle JavaTM ou .NETTm Framework. Ainsi que cela est montré à la figure 1, selon une première étape de la méthode selon l'invention, on 35 fournit une ou plusieurs machines virtuelles. La ou les 3056787 11 machines virtuelles sont générées indépendamment du programme logiciel initial, plus précisément, indépendamment de la connaissance a priori de ce programme logiciel initial. 5 Selon une seconde étape de ma méthode selon l'invention, on fournit un programme logiciel initial ou la partie de ce programme que l'on souhaite protéger, ce programme comprenant un jeu d'instructions exécutable ou un jeu 10 d'instructions en code source. Selon une troisième étape de la méthode selon l'invention, on réalise une transformation du programme logiciel initial ou de la partie de ce programme dans une 15 représentation intermédiaire, c'est-à-dire en utilisant un ensemble restreint d'instructions abstraites communes à tous le processeurs réalisant des opérations élémentaires, et ce que ledit logiciel soit sous une forme exécutable ou sous la forme d'un code source. On 20 produit cette représentation abstraite à partir du programme initial à protéger qu'il soit dans sa forme exécutable ou dans sa forme en langage de programmation (code source). Pour cette étape, on pourra utiliser des compilateurs spécifiques basés, par exemple, mais pas 25 uniquement, sur LLVM (Low Level Virtual Machine - en français Machine Virtuelle de Bas Niveau) qui produit cette représentation intermédiaire à partir du code source, ou en utilisant tous autres moyens, ou en procédant par analyse des instructions dans leur forme 30 exécutable directement. Puis, selon une quatrième étape de la méthode selon l'invention, on réalise une analyse du programme logiciel initial (ou de la partie de celui-ci que l'on 35 souhaite protéger) dans sa représentation intermédiaire. 3056787 12 Il s'agit d'une analyse dite statique, qui est automatisée et qui permet d'identifier la sémantique et/ou la syntaxe du programme logiciel initial dans cette représentation intermédiaire et, par suite, d'identifier 5 un ou plusieurs blocs d'instructions indépendants dans ce programme. On identifie donc au moins, à l'issue de cette analyse, un ou plusieurs blocs d'instructions. Cette analyse est effectuée sans recourir à l'exécution du programme logiciel initial. Avantageusement, l'analyse 10 permet de récupérer un graphe d'exécution du programme logiciel initial. Les instructions de saut conditionnel et/ou les boucles sont identifiées dans ce graphe. Dans une cinquième étape de la méthode selon l'invention, 15 on associe une machine virtuelle à chaque bloc d'instructions indépendant identifié à l'étape précédente. Si une pluralité de machines virtuelles a été fournie et une pluralité de blocs d'instructions a été identifiée, alors on associe, par exemple, une machine 20 virtuelle différente à chaque bloc identifié. Il sera ainsi possible de paralléliser l'exécution des blocs, ainsi que cela sera expliqué dans la suite de la présente description de l'invention. 25 Dans une étape ultérieure de la méthode selon l'invention, on compile l'association entre la représentation intermédiaire du programme logiciel initial (ou de la partie de celui-ci) et la ou les machines virtuelles en vue d'obtenir un bytecode. 30 Dans une étape encore ultérieure de la méthode selon l'invention, on estime la part contributive individuelle de chaque instruction du programme logiciel initial dans un temps d'exécution de ce programme une fois que le ou 35 les blocs d'instructions sont offusqués par 3056787 13 virtualisation en association avec la ou les machines virtuelles. Cette étape est une étape de compilation de la représentation intermédiaire en bytecode relié à une machine virtuelle. Pour cette estimation, on réalise par 5 calcul pour chaque instruction du logiciel original l'impact de la virtualisation, c'est-à-dire résultant des différentes opérations successives de sa virtualisation, soit des étapes de transformation en représentation intermédiaire, puis de compilation avec la ou les 10 machines virtuelles. On procède aussi à une exécution du programme original pour y extraire d'autres données et en particulier le nombre d'exécutions de chaque instruction à l'exécution du programme. Le temps d'exécution du programme logiciel lui-même sous sa forme virtualisée est 15 en outre déterminé. Ce temps peut être comparé au temps d'exécution du programme original. Les résultats de cette analyse sont fournis à un opérateur, par exemple, sous la forme d'un graphe mettant en lumière la part contributive des instructions, prises individuellement, dans le temps 20 d'exécution de ce programme, une fois que le ou les blocs d'instructions sont offusqués par virtualisation en association avec la ou les machines virtuelles. Cette mise en lumière est réalisée par exemple au moyen de codes couleurs. 25 Dans une étape en suivant de la méthode selon l'invention, on sélectionne des instructions dans le programme logiciel initial à exclure de l'offuscation par virtualisation. Cette sélection est effectuée sur la base 30 de cette part contributive déterminée précédemment, c'est-à-dire en tenant compte de cette part contributive. Les instructions exclues sont destinées à être exécutées par la machine réelle soit par une reconstruction dynamique du code de ces instructions sous leur forme 35 originale, c'est-à-dire sous leur forme contenue dans le 3056787 14 programme logiciel initial, soit à ne pas faire l'objet d'une protection ou d'une simple offuscation. La décision de sélection ou non est avantageusement mise en oeuvre pour l'ensemble des instructions identifiées dans 5 le programme logiciel initial, et pour lesquelles on a évalué un impact sur l'exécution du programme. La sélection est effectuée sur la base de la part contributive de chaque instruction du programme, prise individuellement, dans le temps d'exécution de ce 10 programme, une fois que le ou les blocs d'instructions sont offusqués par virtualisation en association avec la ou les machines virtuelles. Si cette part contributive est jugée importante, alors les instructions correspondantes sont avantageusement sélectionnées. Si 15 cette part contributive est faible, alors les instructions correspondantes ne sont pas sélectionnées. La sélection permet d'identifier les instructions du programme qui seront exécutées directement par la machine réelle, et qui, de ce fait, n'impacteront que faiblement 20 ou de manière non significative le temps d'exécution du programme protégé (selon qu'elles seront reconstruites dynamiquement, simplement offusquées ou pas protégées du tout) et par ailleurs, les instructions qui seront exécutées dans le cadre des machines virtuelles, et qui 25 feront notamment l'objet d'une expansion de code importante, mais raisonnable en considération de leur part contributive relative. Par exemple, si le nombre d'itérations d'une boucle est important ou, à tout le moins, trop important pour la destination qui est faite 30 du programme logiciel, alors la ou les instructions correspondant à ladite boucle devraient être sélectionnées afin de ne pas être incluses dans le code logiciel intermédiaire virtualisé à générer à partir du programme logiciel initial. La décision de sélection ou 35 non des instructions et du mode de protection 3056787 15 (virtualisation, reconstruction dynamique, simple offuscation ou sans protection) est prise par un opérateur auquel on aura présenté les résultats de l'estimation de la part contributive des instructions 5 dans l'exécution du programme protégé. Toutefois, la mise en place de seuils sur différents critères peut être réalisée en automatisant la sélection des instructions qui ne seront pas virtualisées. Ces critères peuvent être la localisation de cette instruction dans une boucle et 10 selon différents niveaux d'imbrication de boucles (boucles de premier niveau, de second niveau, ...) ou séparément, la complexité individuelle de la virtualisation traduite en nombre d'instructions exécutées résultant de la virtualisation ou le nombre 15 d'exécution de cette instruction lors de l'exécution du programme. On peut ainsi automatiquement extraire toutes les instructions situées dans une boucle de second niveau ou dont la virtualisation engendre plus de 500 instructions exécutées. 20 Avec une telle technique de seuils, la sélection peut être automatisée, et ne pas nécessiter l'intervention d'un opérateur à ce stade de la méthode selon l'invention. 25 Selon l'invention, une fois qu'on a effectué la sélection des instructions contenues dans le logiciel initial pour être exécutées par la machine réelle soit sans protection ou par une simple offuscation, soit après reconstruction 30 dynamique du code, on compile le programme logiciel initial de manière à générer un nouveau bytecode qui reflétera cette répartition entre les différents modes de protection; les instructions sélectionnées pour une reconstruction dynamique seront présentes dans le 35 bytecode mais sont exécutées de manière séparée, par la 3056787 16 machine réelle directement, après reconstruction dynamique (juste avant leur exécution) du code de ces instruction. Les instructions sélectionnées pour ne pas être protégées ou simplement offusquées sont extraites du 5 bytecode et placées directement dans le programme original et sont exécutées par la machine réelle. Il s'agit du bytecode définitif correspondant au projet de protection et à la découpe des instructions 10 sélectionnées/non-sélectionnées. L'ensemble des instructions sélectionnées destinées à être exécutée par la machine réelle par le mode de reconstruction dynamique de code, fait avantageusement 15 l'objet d'une sécurisation distincte de la sécurisation obtenue par offuscation par virtualisation selon l'invention. Il peut s'agir d'une sécurisation desdites instructions par offuscation, par exemple au moyen de transformations appliquées ponctuellement dans lesdites 20 ou certaines desdites instructions ou séquences d'instructions. Il peut s'agir encore d'une insertion de code mort dans ces instructions, c'est-à-dire d'un code logiciel qui n'est pas destiné à faire l'objet d'une exécution. Il peut s'agir d'un encodage logique par la 25 réalisation d'une opération ou d'une séquence d'opérations logiques élémentaires sur les registres mémoire contenant la chaîne d'instructions. Il peut s'agir enfin d'un chiffrement de certaines ou de toutes les instructions de l'ensemble. 30 Ainsi que cela est plus particulièrement montré en figure 2, la ou les machines virtuelles interprètent le bytecode généré pour les instructions non sélectionnées, c'est-à-dire le bytecode correspondant aux parties du programme 35 logiciel initial offusquées par virtualisation. Par 3056787 17 contre, les instructions sélectionnées, qui ne sont pas offusquées par virtualisation, sont exécutées par la machine réelle après reconstruction dynamique de code ou directement présentes sans protection ou simplement 5 offusquées. En effet, ces instructions ne sont pas interprétables par la ou les machines virtuelles. L'ensemble des instructions sélectionnées, et par suite exclu de l'offuscation par virtualisation est donc exécuté de manière séparée du code intermédiaire 10 virtualisé. Lorsque, dans l'exécution du bytecode, il est demandé l'exécution d'une ou plusieurs instructions particulières exclues de la virtualisation et contenue dans l'ensemble 15 exclu, alors une requête est transmise à cet effet à la machine réelle, plus spécifiquement à un processeur de cette machine réelle. La machine réelle demande alors l'exécution des instructions visées dans cette requête et contenues dans l'ensemble des instructions sélectionnées. 20 Il s'agit d'un transfert de contexte d'exécution de la machine virtuelle à la machine réelle. Si ces instructions exclues sont protégées, par exemple par chiffrement, un module de reconstruction des instructions reconstruit celles-ci pour les besoins de leur exécution. 25 Les instructions sont donc exécutées en clair. Une fois que les instructions de l'ensemble exclu sont exécutées, elles sont alors de nouveau protégées, par le module précité. Le résultat de l'exécution des instructions de l'ensemble exclu est transmis à la machine réelle et il 30 est, si cela est nécessaire, communiqué à la machine virtuelle, qui le prend en compte pour la continuation de l'exécution du programme. L'exécution du programme logiciel protégé selon 35 l'invention permet de d'obtenir son temps d'exécution. Ce 3056787 18 temps d'exécution est comparé avec le temps de la version non protégée de ce programme, à savoir du programme logiciel initial. Un seuil d'acceptation de l'augmentation du temps d'exécution peut être défini. Ce 5 seuil est représentatif de la dégradation globale du temps d'exécution du programme logiciel dans sa version sécurisée. De manière avantageuse, l'exécution du programme logiciel 10 protégé selon l'invention est parallélisée au moyen d'une pluralité de machines virtuelles et d'une machine réelle disposant d'une pluralité de processeurs pour le traitement ou de processeurs comportant une pluralité de coeurs. En effet, une machine virtuelle peut interpréter 15 un bytecode correspondant à un ou plusieurs blocs d'instructions, l'exécution de ce bytecode étant réalisée au moyen de ressources correspondant à un premier processeur, tandis qu'un autre machine virtuelle peut interpréter en parallèle un bytecode correspondants à un 20 ou plusieurs autres blocs d'instructions, l'exécution de ce bytecode étant réalisée au moyen de ressources différentes, et notamment d'un autre processeur. L'avantage de la parallélisation de l'exécution du programme logiciel protégé selon l'invention réside dans 25 la diminution du temps d'exécution et, par suite, dans l'augmentation de la performance de ce programme protégé. Par ailleurs, la parallélisation aura pour effet de compliquer la tâche de l'analyste qui devra suivre l'exécution de plusieurs machines virtuelles réalisant 30 des opérations simultanées. On notera que, dans le cas précédent, dans lequel l'exécution du programme est parallélisée, on analyse avantageusement la machine cible destinée à exécuter le 35 programme logiciel protégé par offuscation par 3056787 19 virtualisation en vue de déterminer un nombre de coeurs de traitement disponibles sur cette machine. Le nombre de blocs ou de machines virtuelles associées est alors avantageusement déterminé en fonction de ce nombre de 5 coeurs disponibles pour la parallélisation des traitements. On notera par ailleurs qu'une telle parallélisation n'est pas connue de l'art antérieur, dans le contexte de 10 l'offuscation de code par virtualisation. Si le temps d'exécution du programme logiciel sécurisé selon l'invention, à savoir du code logiciel intermédiaire virtualisé et de l'ensemble des 15 instructions exclues, se révèle supérieur à un seuil d'acceptation, alors la méthode selon l'invention est de nouveau mise en oeuvre, et de nouvelles instructions, qui n'étaient pas sélectionnées auparavant, sont sélectionnées. Il est donc possible de contrôler la 20 performance de la méthode selon l'invention et de l'adapter selon les besoins de la destination qui en est faite. On notera que, comme la ou les machines virtuelles sont 25 créées indépendamment du programme logiciel à protéger, il est possible de réutiliser ces machines virtuelles. En effet, dans de nombreux usages industriels et, en particulier, dans les domaines industriels dans lesquels une normalisation est requise et où la sûreté de bon 30 fonctionnement est essentiel, comme dans le cas de l'industrie des transports, il peut s'avérer utile de figer une machine virtuelle que l'on aura pris soin de qualifier/certifier. REVENDICATIONS1. Méthode de protection d'un programme logiciel initial ou d'une partie de celui que l'on souhaite protéger 5 par offuscation par virtualisation comprenant les étapes suivantes : fourniture d'une ou plusieurs machines virtuelles, la ou lesdites machines virtuelles ayant été générées indépendamment dudit programme logiciel initial ; 10 fourniture du programme logiciel initial ou d'une partie de ce programme comprenant un jeu d'instructions exécutable ou en code source ; réalisation d'une transformation du programme logiciel initial dans une représentation intermédiaire ; .15 analyse du programme logiciel initial dans sa représentation intermédiaire et on identifie un ou plusieurs blocs d'instructions indépendants ; association d'une machine virtuelle à chaque bloc d'instructions indépendant identifié ; 20 compilation de l'association entre la représentation intermédiaire du programme logiciel initial et la ou les machines virtuelles en vue d'obtenir un bytecode ; d'estimation de la part contributive individuelle de chaque instruction du programme logiciel initial dans un 25 temps d'exécution de ce programme, une fois que le ou les blocs d'instructions sont offusqués par virtualisation en association avec la ou les machines virtuelles ; sur la base de cette part contributive, de sélection des instructions dans le programme logiciel initial à 30 exclure de l'offuscation par virtualisation ; 3056787 22 compilation du programme logiciel initial de manière à générer un nouveau bytecode qui offusque les instructions non sélectionnées dudit programme logiciel initial par virtualisation ; la ou les machines virtuelles interprètent le nouveau bytecode généré pour l'exécution des instructions non-sélectionnées ; et les instructions sélectionnées sont exécutées de manière séparée de l'exécution des instructions non-10 sélectionnées. 2. Méthode selon la revendication 1, caractérisée en ce qu'elle comprend les étapes de fourniture d'une pluralité de machines virtuelles, lesdites machines ayant _15 été générées indépendamment du programme logiciel initial, d'identification d'une pluralité de de blocs d'instructions indépendants dans le programme logiciel initial, et d'association d'une machine virtuelle différente à chaque bloc identifié, de sorte à paralléliser 20 l'exécution desdits blocs, notamment par des demandes d'octroi de disponibilité sur un coeur de traitement pour un bloc particulier de manière à favoriser l'emploi d'autres coeurs de traitement pour d'autres blocs mettant en oeuvre une parallélisation des traitements. 25 3. Méthode de la revendication 2, caractérisée en ce qu'elle comporte en outre une étape d'analyse de la machine cible destinée à exécuter le programme logiciel initial protégé par offuscation par virtualisation en vue de 30 déterminer un nombre de coeurs de traitement disponibles 3056787 23 sur cette machine, et en ce que le nombre de machines virtuelles et/ou blocs est déterminé en fonction de ce nombre de coeurs disponibles pour la parallélisation des traitements. 5 4. Méthode selon l'une des revendications 1 ou 2 ou 3, caractérisée en ce que la part contributive individuelle de chaque instruction du programme logiciel initial dans le temps d'exécution de ce programme, une fois le ou les 10 blocs d'instructions offusqués par virtualisation en association avec la ou les machines virtuelles dépend d'un taux d'expansion du code desdites instructions lors de l'offuscation par virtualisation, et/ou d'un nombre d'exécutions de cette instruction obtenu par une exécution _15 du programme initial. 5. Méthode selon l'une des revendications précédentes, caractérisée en ce que les instructions sélectionnées comprennent des instructions de boucle de 20 programme, imbriquées ou indépendantes. 6. Méthode selon l'une des revendications précédentes, caractérisée en ce que l'estimation de la part contributive de chaque instruction du programme 25 logiciel initial dans un temps d'exécution de ce programme, une fois le ou les blocs d'instructions offusqués par virtualisation en association avec la ou les machines virtuelles est présentée à un opérateur, qui effectue la sélection des instructions dans le programme logiciel 30 initial à exécuter par une machine réelle avec une 3056787 24 reconstruction dynamique du code de ces instructions ou par remplacement dans le logiciel original de séquences de code par simple offuscation ou sans aucune protection. 5 7. Méthode selon l'une des revendications précédentes, caractérisée en ce qu'en complément ou en remplacement des parts individuelles contributives présentées à l'opérateur, les boucles dans le programme original sont présentées pour permettre notamment leur suppression de la virtualisation. 8. Méthode selon l'une des revendications précédentes, caractérisée en ce que les instructions sélectionnées, exécutées de manière séparées, font l'objet _15 d'une exécution sans protection, d'une offuscation simple ou d'une méthode de reconstruction de code dynamique. 9. Méthode selon l'une des revendications précédentes, caractérisée en ce le code des instructions 20 sélectionnées par le mode de reconstruction dynamique, est reconstruit par un module de reconstruction qui génère le code au fil de l'exécution du programme, juste avant leurs exécutions puis une fois leurs exécutions produites, réalise les opérations inverses de telle manière que les 25 instructions ne sont présentes en clair que durant un lapse de temps très succinct. 10. Méthode selon l'une des revendications précédentes, caractérisée en ce que les suppressions 30 d'instructions du traitement de virtualisation sont 3056787 25 réalisées de manière automatique, sans intervention de l'opérateur, par la mise en place de seuils sur différents critères portant sur les informations disponibles. 5 11. Méthode selon l'une des revendications précédentes, caractérisée en ce que la sélection des suppressions d'instructions du traitement de virtualisation est réalisée de façon automatique sur la base de critères ou proposée à un opérateur pour 10 validation. 12. Méthode selon l'une des revendications précédentes, caractérisée en ce que la sélection des suppressions d'instructions du traitement de virtualisation est réalisée de façon automatique sur la base de critères résultant d'un paramétrage produit antérieurement par un opérateur sur un projet de protection correspondant à une version antérieure du logiciel à protéger.20