Simple Science

La science de pointe expliquée simplement

# Informatique# Génie logiciel

Récupérer des noms de variables à partir de fichiers binaires

Une méthode pour restaurer des noms de variables significatifs dans l'analyse de logiciels.

― 11 min lire


Récupération de noms àRécupération de noms àpartir de fichiersbinairesvariables compréhensibles.Transforme le code binaire en noms de
Table des matières

Dans le monde du logiciel, comprendre comment fonctionnent les programmes est essentiel, surtout quand il s'agit de fichiers binaires. Ces fichiers sont créés quand le code est compilé en langage machine, que les ordinateurs peuvent lire mais que les humains ne peuvent pas facilement comprendre. Ça complique la vie des programmeurs et des experts en sécurité pour analyser le comportement des logiciels, surtout quand ils cherchent des vulnérabilités ou du code malveillant. Une partie clé de cette analyse est de retrouver des noms significatifs pour des variables qui sont souvent effacés dans le format binaire.

L'importance des Noms de Variables

Les noms de variables dans la programmation servent de labels pour les données utilisées par les programmes. Ils aident les développeurs à comprendre ce que chaque élément de données représente. Par exemple, une variable nommée userAge est beaucoup plus claire qu'une nommée a1. Quand le logiciel est compilé, beaucoup de ces noms sont supprimés pour économiser de l'espace ou protéger la propriété intellectuelle. Cette suppression rend très difficile la compréhension du code plus tard. Sans noms significatifs, analyser le programme devient un jeu de devinettes.

Défis dans le Code décompilé

Quand on décompile le code (on le reconvertit du binaire à une forme lisible par l'homme), on finit souvent avec du code qui a des noms de variables génériques comme a1, v2, ou simplement des espaces réservés. Ça rend difficile de comprendre l'intention du code.

Récupérer ces noms avec précision peut grandement améliorer la lisibilité du code décompilé. Cela permet aux analystes en sécurité de prendre des décisions éclairées lors de l'évaluation des logiciels pour détecter des vulnérabilités ou des comportements malveillants. Le défi est de prédire ces noms significatifs à partir des binaires dépouillés.

Techniques actuelles et leurs limites

Il existe actuellement plusieurs méthodes pour récupérer les noms de variables à partir des binaires décompilés. La plupart de ces techniques utilisent des modèles d'apprentissage automatique entraînés sur de grandes quantités de code. Elles traitent typiquement la récupération de noms comme un problème de classification, où le modèle essaie de choisir le nom le plus probable pour chaque variable à partir d'une liste de noms connus. Cependant, cette approche a plusieurs inconvénients :

  1. Données déséquilibrées : Les noms de variables ne sont pas répartis de manière égale. Certains noms apparaissent très fréquemment, tandis que beaucoup d'autres apparaissent très rarement. Cela cause un biais dans les Modèles de classification qui privilégient les noms plus communs, entraînant de mauvais résultats pour les noms rares.

  2. Vocabulaire limité : Comme ces modèles ne peuvent choisir que parmi les noms qu'ils ont vus pendant l'entraînement, ils ne peuvent pas générer de nouveaux noms. Cette limitation peut être un gros inconvénient quand on traite des noms de variables uniques ou peu communs.

  3. Incapacité à capter le contexte : Analyser une fonction isolément signifie que le modèle ne peut pas tirer profit d'informations utiles provenant de fonctions apparentées, de variables adjacentes ou de contextes d'appel, ce qui entraîne des prédictions moins précises.

Ces défis soulignent le besoin de méthodes améliorées pour la récupération des noms de variables.

Une nouvelle approche pour la récupération de noms

Pour résoudre ces problèmes, une nouvelle méthode a été développée, combinant les forces de différents types de modèles d'apprentissage automatique pour récupérer les noms de variables. Cette méthode se concentre sur la génération de noms significatifs plutôt que sur leur simple classification.

Le rôle des Modèles génératifs

Les modèles génératifs peuvent créer de nouveaux noms basés sur le contexte fourni. Contrairement aux modèles de classification, qui ne peuvent que choisir parmi un ensemble fixe de noms préexistants. En utilisant des modèles génératifs, on peut créer des noms uniques qui n'ont peut-être pas été vus pendant l'entraînement. Cette flexibilité est cruciale pour récupérer des noms de variables qui apparaissent rarement dans les jeux de données existants.

Cependant, les modèles génératifs ont leurs propres défis. Ils peuvent produire des noms qui n'ont aucun sens ou qui sont incorrects, un phénomène connu sous le nom de "hallucination". Par exemple, si un modèle génératif se voit demander de nommer une variable représentant une clé partagée dans une fonction de chiffrement, il pourrait accidentellement suggérer un nom qui implique un type de chiffrement complètement différent.

Se tourner vers l'information contextuelle

Une stratégie efficace pour améliorer la précision de la récupération des noms est d'incorporer des informations du contexte d'appel. Quand une fonction appelle d'autres fonctions, elle passe souvent des informations qui peuvent aider à clarifier ce que signifient les variables. En regardant les noms utilisés dans des fonctions liées, on peut fournir aux modèles génératifs des entrées plus riches, améliorant leurs prédictions.

Par exemple, si une fonction loadKey utilise une variable d'entrée nommée filePath, et qu'elle est souvent appelée par une autre fonction openFile, on peut inférer qu'une variable dans loadKey pourrait également être liée aux opérations sur les fichiers. Ce contexte supplémentaire améliore la probabilité que les noms générés soient appropriés et significatifs.

L'approche à double modèle

Pour combiner les forces des modèles génératifs et de classification, une approche à double modèle est utilisée. Dans cette méthode, un modèle génère des noms créatifs tandis que l'autre fournit de la stabilité en classifiant les noms connus. Ensemble, ces modèles travaillent pour prédire et valider les noms des variables.

  1. Modèle génératif : Ce modèle crée des noms potentiels pour les variables en se basant sur le code décompilé et des Informations Contextuelles. Il tire parti des forces de la compréhension du langage acquises à partir de grands ensembles de données de code de programmation.

  2. Modèle de classification : Ce modèle évalue les noms connus pour fournir une base solide. Il est particulièrement utile pour les noms qui sont courants et bien compris.

En utilisant les deux modèles, nous pouvons améliorer les prédictions tout en réduisant l'incidence des hallucinations.

Mise en œuvre de la technique de récupération de noms

La technique de récupération de noms proposée implique plusieurs étapes, allant du prétraitement des données à la génération finale de noms. Ci-dessous, nous allons décomposer ces processus.

Prétraitement des données

Avant de former nos modèles, nous devons rassembler et préparer les données nécessaires. Cela inclut :

  1. Collecter des programmes binaires : On rassemble un ensemble diversifié de fichiers binaires, en s'assurant qu'ils contiennent suffisamment d'exemples des variables que nous souhaitons identifier.

  2. Décompilation : Les binaires sont décompilés pour obtenir une représentation textuelle du code. Ce processus génère des représentations de bas niveau du code avec des noms de variables souvent sans signification.

  3. Mapper les noms de variables de vérité de base : Pour chaque programme décompilé, il faut lier les noms de variables de vérité de base avec leurs emplacements dans le code décompilé. Cela signifie identifier les noms originaux avant qu'ils ne soient effacés et les associer à leurs positions en mémoire.

  4. Augmenter les données : On enrichit notre jeu de données en utilisant des informations provenant de fonctions liées, garantissant que nous capturons des noms et des contextes pertinents qui peuvent aider aux prédictions.

Entraînement des modèles

Avec le jeu de données épuré et enrichi, nous pouvons entraîner nos modèles.

  1. Affinage des modèles génératifs : Le modèle génératif est affiné pour comprendre les spécificités de la structure du code décompilé, lui permettant de générer des noms cohérents alignés sur les pratiques de programmation.

  2. Entraînement des modèles de classification : Le modèle de classification est entraîné à reconnaître et à classifier les noms connus en fonction de leur fréquence statistique dans les données d'entraînement.

  3. Entraînement double : Les deux modèles sont entraînés ensemble de manière à pouvoir partager des informations et améliorer les prédictions de l'autre.

Processus d'inférence

Une fois les modèles entraînés, ils peuvent être utilisés dans des scénarios réels pour récupérer des noms de variables à partir de nouveaux binaires.

  1. Générer des noms initiaux : Pour chaque variable, le modèle génératif tente de suggérer des noms basés sur le code décompilé et les contextes.

  2. Valider les noms : Le modèle de classification examine ensuite ces noms, évaluant leur validité par rapport aux noms connus et suggérant des corrections si nécessaire.

  3. Traitement itératif : Les modèles peuvent affiner itérativement leurs prédictions en utilisant des retours des tours précédents, augmentant leur précision avec le temps.

Résultats et efficacité

L'efficacité de cette nouvelle approche peut être mesurée en comparant ses performances à celles des techniques existantes. Non seulement elle surpasse les méthodes de classification traditionnelles, mais elle gère également beaucoup mieux les noms de variables rares.

Métriques de performance

Pour évaluer la performance, nous utilisons à la fois la correspondance exacte et la correspondance sémantique. La correspondance exacte vérifie si le nom prédit est identique au nom original, tandis que la correspondance sémantique permet une certaine variation, tant que le nom prédit véhicule un sens similaire.

Comparaison avec les techniques existantes

Mesurée par rapport aux techniques de pointe actuelles, notre approche à double modèle montre des améliorations considérables. Elle augmente significativement la précision de la récupération de noms, surtout dans les cas difficiles où un nom de variable est rare ou complexe.

Par exemple, les méthodes existantes peuvent donner une précision d'environ 31,2%, tandis que notre technique porte cela à plus de 57,9%. Cela souligne non seulement l'efficacité de la génération de nouveaux noms mais met également en avant l'importance de tirer parti d'un contexte supplémentaire.

Applications dans le monde réel

Les implications d'une meilleure récupération des noms de variables vont au-delà d'un intérêt académique. Les analystes en sécurité, par exemple, en bénéficient directement lorsqu'ils analysent des malwares. Avec des noms plus significatifs, ils peuvent plus facilement identifier des comportements suspects dans le code décompilé.

De plus, comprendre les logiciels binaires améliore la posture globale de sécurité des systèmes et des applications, permettant aux développeurs de maintenir et de renforcer leurs logiciels contre des menaces potentielles.

Conclusion

En résumé, la récupération de noms de variables significatifs à partir de binaires dépouillés est une tâche cruciale dans l'analyse logicielle, surtout dans les domaines de la sécurité et de l'ingénierie inverse. Les défis associés aux techniques actuelles peuvent être efficacement abordés en utilisant une approche à double modèle qui combine modèles génératifs et de classification. En tirant parti des informations contextuelles des fonctions d'appel, nous pouvons récupérer des noms qui sont non seulement précis mais également informatifs.

Cette innovation ouvre de nouvelles possibilités pour comprendre des systèmes logiciels complexes et améliore la capacité des analystes à identifier des vulnérabilités ou des intentions malveillantes. Alors que le paysage logiciel continue d'évoluer, des techniques comme celles-ci deviendront de plus en plus précieuses pour garantir la confidentialité, l'intégrité et la disponibilité des applications logicielles critiques.

Source originale

Titre: Symbol Preference Aware Generative Models for Recovering Variable Names from Stripped Binary

Résumé: Decompilation aims to recover the source code form of a binary executable. It has many security applications, such as malware analysis, vulnerability detection, and code hardening. A prominent challenge in decompilation is to recover variable names. We propose a novel technique that leverages the strengths of generative models while mitigating model biases. We build a prototype, GenNm, from pre-trained generative models CodeGemma-2B, CodeLlama-7B, and CodeLlama-34B. We finetune GenNm on decompiled functions and teach models to leverage contextual information. GenNm includes names from callers and callees while querying a function, providing rich contextual information within the model's input token limitation. We mitigate model biases by aligning the output distribution of models with symbol preferences of developers. Our results show that GenNm improves the state-of-the-art name recovery precision by 5.6-11.4 percentage points on two commonly used datasets and improves the state-of-the-art by 32% (from 17.3% to 22.8%) in the most challenging setup where ground-truth variable names are not seen in the training dataset.

Auteurs: Xiangzhe Xu, Zhuo Zhang, Zian Su, Ziyang Huang, Shiwei Feng, Yapeng Ye, Nan Jiang, Danning Xie, Siyuan Cheng, Lin Tan, Xiangyu Zhang

Dernière mise à jour: 2024-12-09 00:00:00

Langue: English

Source URL: https://arxiv.org/abs/2306.02546

Source PDF: https://arxiv.org/pdf/2306.02546

Licence: https://creativecommons.org/licenses/by/4.0/

Changements: Ce résumé a été créé avec l'aide de l'IA et peut contenir des inexactitudes. Pour obtenir des informations précises, veuillez vous référer aux documents sources originaux dont les liens figurent ici.

Merci à arxiv pour l'utilisation de son interopérabilité en libre accès.

Plus d'auteurs

Articles similaires