Aujourd'hui, je vous parle d'une classe d'erreurs que vous rencontrerez peut-être, si vous n'avez pas de chance, en jouant a des jeux sous GNU/Linux qui n'ont pas été mis à jour depuis longtemps.

Suivre les exemples demandera de savoir ouvrir votre terminal et copier/coller des choses dedans, mais je pars de principe que si vous êtes tombés sur ce type d'erreur c'est que vous savez déjà faire ça.

Prenons un exemple, ça sera plus parlant. Récemment j'ai fait l'acquisition de «The Red Strings Club», un court jeu d'aventure cyberpunk dans lequel on incarne un barman (jouez-y, il est bien).

J'installe le jeu normalement, avec l'installeur GOG, sous /home/<moi>/Games/The Red Strings Club, me rends dans ce dossier avec cd, puis découvre avec stupeur qu'au lancement (./game/runner), rien ne se passe.

J'obtiens une erreur:

Running The Red Strings Club
./runner: error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory

Hmmm… c'est curieux… quand ce genre de trucs arrivent, vous pouvez regarder si vous trouvez le fichier manquant dont parle l'erreur dans les bibliothèques de votre système, comme ça:

cd /usr/lib && find ./ | grep libcrypto

(remplacer «libcrypto» par le nom du fichier non trouvé)

Si vous avez le fichier que vous cherchez dans vos bibliothèques système, il apparaîtra sous la forme d'une liste comme celle-ci:

./x86_64-linux-gnu/android/libcrypto_utils.so.0
./x86_64-linux-gnu/android/libcrypto.so.0
./x86_64-linux-gnu/libcrypto.a
./x86_64-linux-gnu/pkgconfig/libcrypto.pc
./x86_64-linux-gnu/libcrypto.so.1.1
./x86_64-linux-gnu/libcrypto.so

Si il n'est pas trouvé, il ne se passera rien. Et c'est une bonne nouvelle ! Allez voir si vous pouvez l'installer avec apt, ou le store de votre distribution Linux, enfin comme vous faites d'habitude quoi.

Dans notre cas, c'est un peu plus compliqué. Il existe, mais pas à la bonne version. Vous pouvez chercher si la version que vous voulez existe dans les dépôts de votre distribution, mais ce ne sera pas toujours le cas.

En l'ocurrence, libcrypto fait partie de libSSL (merci les moteurs de recherche encore une fois), et la version 1.0.0 n'est plus disponible facilement en raison de failles de sécurité découvertes dans les anciennes versions.

Heureusement, sur internet, il y a plein d'archives de tout et n'importequoi.

Une simple recherche google, et le premier résultat est exactement ce qu'on cherche.

Le premier lien, c'est une source fiable: les dépôts debian officiels. Peu importe votre distribution, pour la solution qu'on va utiliser vous pouvez utiliser les dépôts de Debian.

On trouve la version 32 bits de libSSL (en général, les jeux sont compilés pour 32 bits, vous pouvez vérifier en faisant `file chemin/du/jeu`).

Lien de la version 32 bits de libSSL 1.0.0

La version 32 bits est encadrée en rouge, en bas de la page.

Le lien pointe vers une archive compressée qui contient la bonne version de libcrypto.

Mais maintenant qu'on a ce fichier… comment qu'on s'en sert en fait ?

Les bibliothèques logicielles et ld

Pour comprendre la manipulation qui va suivre, je vais vous faire une petite explication technique, vous pouvez sauter cette partie si ça vous gave.

Donc les fichiers .so dont on entend parler depuis tout à l'heure, ce sont des bibliothèques de code sous une forme pratique à partager. Par exemple, quand beaucoup de logiciels ont besoin d'une seule et même fonction, développée par Jean-Dev, c'est bien plus efficace d'installer une seule fois ladite fonction sur votre ordinateur plutôt que de l'installer avec chaque programme dont vous avez besoin.

Donc Jean-Dev fait un fichier .so (.dll si il est sous Windows, le vil), le fournit à tout le monde, et les hackers qui créent votre distribution Linux favorite vont en faire un paquet que vous pourrez installer.

Comme ça, quand vous téléchargez et lancez des logiciels, ils n'ont pas besoin de contenir la fonction de Jean-Dev !

Ils disent juste à un programme dit «linker» (qui s'appelle ld sous Linux) «Hey camarade, j'ai besoin du code de Jean-Dev». Et le linker leur dit: ok, il est là.

Un autre truc super pratique avec ce système, c'est que Jean-Dev peut faire des mises à jour de son code, et si il ne fait pas trop de changements structurels, c'est possible de mettre à jour son code sans mettre à jour les logiciels et programmes qui en ont besoin.

C'est vraiment le turfu (non ça a été inventé dans les années 60).

Les soucis que ça peut provoquer

Par contre si Jean-Dev fait des gros changements, typiquement du genre qui nécessite de publier une nouvelle version majeure de sa bibliothèque de code, alors les logiciels qui en ont besoin peuvent ne plus s'y retrouver. Des noms de fonctions ont changé, certaines ne font plus la même chose, c'est le bordel.

Là il faut quand même publier une mise à jour des logiciels. C'est le problème qu'on rencontre actuellement avec notre jeu.

Parce que nous, on a juste la nouvelle version de libcrypto, et on aurait besoin de l'ancienne. Parce que «The Red Strings Club» il veut l'ancienne.

Par défaut, si vous le laissez fonctionner comme il veut, ld va aller chercher les bibliothèques qui ont été installées normalement sur votre système, dans les sous-dossiers de /usr/lib.

Sauf que là aujourd'hui, on ne peut pas installer cette bibliothèque (et mettre manuellement le fichier qu'on vient de télécharger dans /usr/lib serait une super mauvaise idée, parce que pour rappel il est vieux et bourré de failles, donc on ne veut pas que les autres logiciels de notre système y aient accès à loisir).

Heureusement, il existe un mécanisme sympa pour nous aider. On va dire à ld, au moyen d'une variable d'environnement (LD_LIBRARY_PATH, je vous explique tout ça dans la partie suivante), d'aller chercher notre bibliothèque toute vieille à l'endroit que l'on souhaite sur notre disque.

Comme ça, quand notre programme demandera la bibliothèque, ld saura où la trouver.

La pratique: LD_LIBRARY_PATH

Allez, on passe à la pratique. Vous allez extraire dans le dossier du jeu l'archive que vous avez téléchargé (le lien encadré en rouge dans la deuxième capture d'écran). Ensuite vous copierez le fichier libcrypto.so.1.0.0 qui est quelquepart dedans dans un dossier de votre choix, pas loin de l'exécutable du jeu si possible, comme ça vous vous rappellerez pourquoi il est là en retombant dessus dans le futur (ici si vous voulez faire comme moi, mettez-le dans le dossier game).

Je vous donne un exemple en ligne de commande mais vous pouvez le faire avec vous outils habituels:

moi@linux:~/Games/The Red Strings Club$ 7z x libssl1.0.0_1.0.1t-1+deb8u12_i386.deb
moi@linux:~/Games/The Red Strings Club$ tar -xf data.tar 
moi@linux::~/Games/The Red Strings Club$ mv ./usr/lib/i386-linux-gnu/libcrypto.so.1.0.0 game/

Voilà, maintenant le dossier d'installation du jeu ressemble à ça:

./
├── data.tar
├── deps.txt
├── docs
│   ├── End User License Agreement.txt
│   └── installer_readme.txt
├── game
│   ├── assets
│   ├── libcrypto.so.1.0.0
│   ├── runner
│   └── usr
├── gameinfo
├── start.sh
├── support
│   ├── gog_com.shlib
│   ├── gog-system-report.sh
│   ├── icon.png
│   ├── postinst.sh
│   ├── preuninst.sh
│   ├── support_notice.txt
│   ├── xdg-utils
│   └── yad
├── uninstall-The Red Strings Club.sh
└── usr
    ├── lib
    └── share

Ensuite, en ligne de commande, depuis le dossier du jeu, préparez-vous à la magie:

cheapseth@pop-os:~/Games/The Red Strings Club$ LD_PRELOAD=game/libcrypto.so.1.0.0 game/runner 
game/runner: error while loading shared libraries: libssl.so.1.0.0: cannot open shared object file: No such file or directory

Ah. Oui. Merde. Il a besoin de libssl.so aussi. Mais tout va bien ! Ce fichier est aussi dans l'archive qu'on vient de télécharger. On le déplace dans le dossier game avec l'autre .so, et c'est reparti:

moi@linux:~/Games/The Red Strings Club$ mv usr/lib/i386-linux-gnu/libssl.so.1.0.0 game
moi@linux:~/Games/The Red Strings Club$ LD_LIBRARY_PATH="./game:$LD_LIBRARY_PATH" game/runner

Et BOUM !

L'écran titre de «The Red Strings Club»
L'écran titre de «The Red Strings Club»

Voilà, vous pouvez supprimer data.tar et ./usr (attention, mettez bien le point avant, vous ne voulez surtout pas supprimer /usr, déjà vous n'aurez pas le droit et ensuite si vous l'aviez ça serait un désastre).

Je vous explique un peu la magie

Donc, la partie LD_LIBRARY_PATH="./game:$LD_LIBRARY_PATH" qu'on a mis avant d'appeller l'exécutable du jeu (game/runner), sert à rajouter le dossier game qui se trouve dans le dossier courant aux endroits où LD ira chercher des bibliothèques.

Comme ça quand l'exécutable runner demandera où sont libcrypto et libssl, ld ira aussi chercher dans le dossier où on les a copiés.

Cette méthode est assez propre pour le long terme, car comme la variable est créée directement avec l'appel de l'exécutable, elle ne persiste pas après la fin de l'exécution du jeu (pas de risque qu'un autre programme aille chercher nos bibliothèques de code obsolètes), et on n'a pas eu a mettre les fichiers dans un endroit où ld va chercher par défaut. Donc on limite un maximum les risques liés à l'utilisation de vieilles bibliothèques (qui restent présent, alors renseignez-vous toujours avant de faire cette manipulation avec des programmes que vous ne connaissez-pas !)

En conclusion

Je l'admets volontiers, le sujet d'aujourd'hui était plus technique que d'habitude. Mais c'est aussi une leçon intéressante sur la résolution de problèmes techniques sur la plateforme GNU/Linux. Il y a plusieurs solutions, elles nécessitent toutes d'apprendre au moins une petite partie du fonctionnement de votre système d'exploitation, mais au moins vous pouvez réparer vous-même.

C'est mon opinion, mais c'est quelquechose d'important aujourd'hui, à l'heure où l'utilisateur d'un ordinateur ou d'un smartphone est perçu comme un simple consommateur, de pouvoir encore explorer le fonctionnement de nos systèmes.

En plus, ça fait développer ses connaissances et sons sens technique, ce qui est rarement du temps perdu.

Si vous avez trouvé certains concepts abordés un peu flou et que vous aimeriez comprendre comment faire, vous aussi, de la magie noire, voici quelques liens qui vous permettront de vous documenter:

J'espère que ça vous a plu, n'hésitez pas à me faire des retours sur le twitter du site, et surtout jouez à plein de jeux vidéo, c'est important.