8
votes

Détecter si c ++ binaire est optimisé

existe un drapeau ou une autre méthode fiable pour détecter si un binaire C ++ compilé a été compilé avec des optimisations?

Je vais bien avec des solutions spécifiques au compilateur.


edit: Ceci est pour un système de déploiement de construction, ce qui pourrait déployer accidentellement des fichiers binaires qui n'ont pas été construits correctement. Une solution étanche à l'eau est peu probable, mais elle sauvera une douleur (et de l'argent) si cela peut être détecté une partie du temps.

Le compilateur sera souvent GCC, parfois Sun, et s'il y a une solution MSVC, je ne veux pas l'indiquer au profit de la communauté.


2 commentaires

Et qu'en avez-vous besoin? Il est possible qu'il y ait une meilleure solution à votre problème


Avez-vous la source? Êtes-vous autorisé à recompiler pour voir ce que fait le compilateur? Ou juste le binaire?


10 Réponses :


1
votes

Je suis à peu près sûr qu'il n'y a aucun moyen. Sauf si vous avez des connaissances spécifiques d'une fonction à l'intérieur que vous pouvez vérifier si la séquence de code est optimale ou non.


0 commentaires

3
votes

Vous ne mentionnez pas une plate-forme spécifique, la réponse pourrait donc être oui. Mais pour la plupart des plates-formes communes, la réponse est non.



0 commentaires

3
votes

Pour Microsoft C ++, vous pourrez peut-être supposer que l'optimisation a été désactivée si l'exécutable référencit les versions de débogage des DLL d'exécution. Ce n'est pas une garantie, cependant.


0 commentaires

12
votes

Les versions récentes de GCC ont un moyen de signaler quels drapeaux ont été utilisés pour compiler un binaire (troisième point de balle).

Il existe un commutateur de ligne de commande associé (--Fverbose-ASM) qui "enregistre uniquement les informations dans le fichier de sortie d'assembleur en tant que commentaires, les informations n'atteint jamais le fichier d'objet." L'interrupteur - FRECRECORD-GCC-SWITCHES "provoque la ligne de commande utilisée pour appeler le compilateur à enregistrer dans le fichier d'objet créé."


4 commentaires

Cela semble prometteur, max. Comment puis-je lire ces informations?


Malheureusement, les informations sont stockées de manière dépendante de la plate-forme. Je commencerais avec la ligne de commande Objdump présentée à nababeb.com/... .


Le lien du Nabble est mort. Quelqu'un sache ce que les drapeaux objdump ont besoin?


cordes foo.so | grep FPIC



2
votes

Dans mon expérience, seule une manière fiable est d'examiner le désassemblage lui-même si vous ne connaissez pas le compilateur. Essayez d'abord de jeter toutes les cordes avec votre outil préféré et de rechercher des indices dans les noms de la bibliothèque liés et des symboles exportés. À défaut, recherchez des séquences d'instructions communes qui sont principalement éloignées après des optimisations telles que le prologue de l'encadrement de la pile et l'utilisation de registres ordonnée et facile à comprendre. Si des outils tels que OLLYDBG sont confus lorsqu'une fonction commence et se termine, une bonne chance binaire est compilée avec des optimisations sur.

Examiner une sortie d'un décompiler peut également aider. La dernière fois que j'ai vérifié, ils n'étaient pas meilleurs qu'un désassembleur, mais les choses peuvent s'être améliorée depuis lors.


0 commentaires

7
votes

Solution d'heuristique possible

Si je recevais cette tâche et que cela prouverait, c'est une tâche résonable. J'effectuerais une "analyse de fréquence" des motifs observés dans le désassemblage exécutable. En tant que programmeur, je suis capable de distinguer un code optimisé et non optimisé (débogage) à première vue. J'essaierais de formaliser le processus de décision, avec Visual Studio et X86 Plateforme, les caractéristiques typiques observées dans des exe non optimisées seraient les suivantes:

  • Fonctions avec prologue complet / épilogue (cadres de pile basés sur EBP)
  • beaucoup de MOV-S de / en mémoire (toutes les variables placées dans la mémoire)

    Ce n'est certainement pas à 100%, mais avec un exe plus long, je m'attendrais à ce que les résultats soient assez fiables.

    Je suppose que les autres plates-formes X86, y compris la GCC, les règles seront similaires, sinon identiques, et pour d'autres plates-formes, des règles similaires peuvent être trouvées.

    D'autres heuristiques telles que la détection de la bibliothèque d'exécution peuvent également fonctionner, en fonction des paramètres du compilateur.

    TÂCHE SONÇONS SILDES

    Cela dit, je pense que cette tâche "sent" et dans la plupart des cas, il serait raisonnable de l'éviter complètement. Si vous fournissez la vraie raison de cette tâche, il est très probable qu'une solution sensible sera trouvée.


0 commentaires

2
votes

Je serais surpris si tu ne fais pas déjà quelque chose comme ça, mais:

Si vous "faites confiance à" le système de construction, placez les options utilisées pour construire une chaîne que vous pouvez extraire à partir d'un programme en cours d'exécution. (c.-à-d. de --Version ou une boîte de dialogue à propos de)

Cela ne détectera pas les problèmes avec des fichiers d'objet non optimisés dans la construction en raison d'un système de construction brisé, mais il vous permettra de différencier facilement une construction de développeur à partir d'une version de déverrouillage.

Votre processus de version peut alors inclure la vérification de la version pour vous assurer qu'il n'est pas débogué / non versé.


0 commentaires

0
votes

Peut-être que vous pourriez utiliser un indicateur différent pour déterminer si vous déployez le bon binaire. E.g.

  • Info de débogage: Peut-être que vos fichiers binaires de sortie diffèrent en ce qu'ils n'ont pas d'informations de débogage? Vous pouvez vérifier cela avec Elfdump ou GDB.
  • dépouillé: si vos fichiers binaires sont dépouillés, vous pouvez utiliser "Fichier" pour vérifier ce

0 commentaires

5
votes

La technique que nous utilisons est simplement de créer un symbole qui apparaît dans chaque bibliothèque uniquement si le débogage construit: xxx

puis lors du chargement de chaque module au moment de l'exécution (ou dans une gâchette de perforce) nous Peut demander au binaire s'il est débogué en recherchant simplement ce symbole: xxx


2 commentaires

C'est ce que je pensais aussi, mais cela ne répond pas directement à la question. Le binaire peut éventuellement être compilé en libération mais sans optimisation allumé.


Et le contraire, déboguer mais avec des optimisations.



4
votes

sous Windows, vous pouvez vérifier si les informations de débogage sont dépouillées du binaire. Si vous examinez l'image binaire de l'en-tête COFF, il y a un bloc de drapeau de 2 octets appelé Caractéristiques à l'octet Offset 18 de Coff En-tête. Si le drapeau

 short flag_block;

 FILE * p_image_file = fopen (...); 

 fseek(p_image_file,0x52,SEEK_SET);

 fread(&flag_block,2,1,p_image_file);

 if(flag_block & 0x0200 > 0)
    then debug info is stripped


0 commentaires