Création d’un binaire multiplateforme
Signature : | Mis en ligne le : 08/10/2008
Catégorie(s) :
  • Misc
  • | Domaine :
    Commentez

    Retrouvez cet article dans : Misc 20

    Depuis quelques temps, nous voyons apparaître ça et là quelques virus multiplateformes. Nous citerons par exemple Winux, virus qui a pour cible les OS Linux et Windows... Bien entendu, les virus ne sont pas les seuls binaires (car on parle ici de binaires, et non de scripts) à pouvoir profiter de cette avantageuse programmation. Bien qu’ils soient peu répandus, il peut s'avérer intéressant de proposer de tels binaires dans le cas par exemple d'un programme d'installation ou autre. En effet, les utilisateurs n'ont alors plus à se préoccuper de savoir à quel OS est destiné le programme, le binaire détectant automatiquement son environnement d'installation. Ceci n'est qu'un exemple parmi tant d'autres et les possibilités d'utilisation sont multiples. Les virus multiplateformes semblent toutefois être un des " débouchés " les plus évidents. Nous verrons ainsi au cours de l'article comment créer un tel binaire. Toute l'astuce repose sur une manipulation des en-têtes du binaire et sur les aspects de relocation du segment de code. Cette étude s'appuie sur un travail préalable de Kuno Woudt (warp-tmt@dds.nl) et Rafal Skoczylas (nils@secprog.org).

    I. Linux

    Il existe plusieurs formats d'exécutables sous Linux. Nous nous intéresserons plus particulièrement au format ELF, le plus répandu sous cet OS. Nous ne reviendrons pas en détail sur ce format, toute la documentation étant largement accessible par Internet. Rappelons juste que tout binaire ELF présente un en-tête qui renseigne sur le fonctionnement du binaire (format, type de binaire, point d'entrée, taille des sections et autres). Nous commençons par créer un programme en assembleur tout simple qui affichera un message type Hello Strange World... pour ne pas faillir à la tradition. Nous implémenterons nous-mêmes le header ELF, de manière à pouvoir le changer par la suite (pas de linker). Voici donc le corps tout simple d'un programme de ce type : Après assemblage, le programme fonctionne de la manière escomptée et nous affiche le message voulu, avant de quitter. Intéressons-nous maintenant aux programmes destinés aux environnements tels que Windows et DOS.

    II. DOS

    Dans le cas précis d'un binaire DOS, nous codons un .COM. Les fichiers .COM n'ont aucun header et exécutent tout simplement les instructions depuis les premiers octets du fichier. Nous programmons, toujours en assembleur, un mini binaire qui affiche un texte sous DOS pour commencer. Il est possible de faire coexister deux formats dans un même exécutable en exploitant les propriétés de ces formats. Voyons cela...

    III. Faire coexister ces formats...

    À la différence d'un .COM, un binaire ELF commence toujours par un header qui détermine les paramètres propres au fichier : Ce header comporte certaines données indispensables au bon fonctionnement du binaire ELF qu'il nous faut impérativement conserver dans notre binaire généraliste. D'autres données pourront en revanche être écrasées (version ABI notamment, fin du champ e_ident de l'en-tête ELF cf. elf(5)). À ce point, nous pourrions nous dire que cela risque d'empêcher la coexistence avec un format .COM, qui, lui, exécute les instructions en commençant par le début de l'exécutable, c'est-à-dire notre en-tête ELF. Il n'en est rien, car les octets du header se traduisent en instructions tout à fait valides : La première instruction est un saut conditionnel, pour lequel nous ne contrôlons pas le résultat. Il faut donc prendre en compte les 2 possibilités :
    • Le saut est exécuté et il faut qu'à 0x47 octets de là se retrouvent nos instructions DOS valides pour qu'elles soient immédiatement exécutées.
    • Le saut n'est pas exécuté et les octets suivants vont être lus. Nous allons donc devoir compenser (annuler) toutes les instructions induites par l'existence du header. Par exemple, la séquence dec sp; inc si sera annulée par dec si; inc sp. Nous profitons du fait que tout l'en-tête n'est pas indispensable (version ABI...) au bon fonctionnement pour insérer un saut dans l'en-tête (qui ne sera pas exécuté dans le ELF, mais le sera dans le .COM.
    Traduisons cela en assembleur :

    IV. Diversification OS

    Une fois que cette coexistence des formats ELF et COM est rendue possible, nous pouvons nous pencher sur la diversification de l'exécutable vers d'autres OS utilisant ces mêmes formats. Il est en effet possible d'identifier les versions d'OS (DOS, Win 3.x, Win9x, WinNT, Linux, BSD, OS/2...). Pour ce faire, il convient d'effectuer quelques tests.

    1/ DOS/Windows

    Une fois que le programme se situe dans la partie propre à DOS/Windows (c'est-à-dire _start_dos), il nous est possible de distinguer entre les différentes versions de Windows grâce à l'insertion dans la partie DOS/Windows du code ci-après : Ensuite, il suffit d'examiner le registre AX pour déterminer l'OS plus précisément :
    • Si AL = 0x80, alors l'OS n'est pas du type Windows.
    • Si AL = 1 ou AL = 0xFF, alors l'OS est un Windows 2.x.
    • Si AL = 0 ou AL = 0x16, alors l'OS est un Windows NT/XP.
    • Sinon, si AL comporte une valeur différente, AL désigne le numéro de version (major) et ah, le minor de la version (ex : 3.1).
    Le code complet pour distinguer les différents cas est donc : Il nous suffirait donc à présent d'insérer de nouvelles fonctions plus spécifiques à chacun de ces cas dans le code, avant le bloc de données par exemple, pour les traiter séparément.

    2/ Unix-Flavor

    Enfin, dans la partie de code dédiée aux Unix-like (_start_unx), pour distinguer Linux et les *BSD, il nous suffit de vérifier le contenu des registres fs et gs. Si ces deux registres sont à 0, alors, nous sommes sur un Linux, sinon c'est BSD.

    V. Conclusion

    Il est bien entendu qu'une partie du code doit être réécrit, les appels système n'étant pas les mêmes selon les différents environnements. Toutefois, pour un programme relativement simple, il pourrait être intéressant de dresser un tableau de pointeurs sur nos principales fonctions selon l'environnement (du type 'print(LINUX)(stdout, "Hello")' / 'print(DOS)(stdout, "Hello dos")'...). Un registre contenant l'index tout au long du programme ferait en somme office d'une sorte de wrapper. Il n'est donc pas impossible de faire un programme (binaire) assemblé et non scripté tournant sous différents OS sans besoin de modification. Après, les limites de votre programme sont celles de votre imagination... Références

    Retrouvez cet article dans : Misc 20

    Vous souhaitez commenter cet article ?
    Brèves Flux RSS
    Édito : GNU/Linux Magazine 149
    Édito : GNU/Linux Magazine HS N°60
    Édito : Misc 61
    Édito : Linux Pratique 71
    Édito : Linux Essentiel N°25
    Communication RSS Com. RSS Presse
    Lancement de la plateforme de vente en ligne de PDF des Éditions Diamond ! Un...
    Misc N°61 – Communiqué de presse
    GNU/Linux Magazine N°149 – Communiqué de presse
    GNU/Linux Magazine HS N°60 – Communiqué de presse
    Linux Pratique N°71 – Communiqué de presse
    prochainement moteur de recherches des articles
     
    :
    :
    Jours heures minutes secondes
    En kiosque Flux RSS

    Le tout nouveau GNU/Linux Magazine est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Pratique est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau GNU/Linux Magazine HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Linux Essentiel est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...

    Le tout nouveau Misc HS est disponible dès maintenant chez votre marchand de journaux et sur notre site marchand.

    Découvrez le sommaire de ce numéro et un aperçu de ce magazine...

    Lire la suite...