15 votes

Convertir un script bash en un exécutable binaire autonome compilé, pas en texte

Je veux rendre un script Bash exécutable par le noyau. J'ai déjà utilisé la commande chmod +x et #!/bin/bash pour le rendre exécutable et cela fonctionne, mais ce que je veux faire est le rendre exécutable sans un interprète, comme un exécutable d'une application compilée.

Y a-t-il un moyen de le faire? Tout ce dont j'ai besoin est un moyen de rendre mon script Bash exécutable depuis le noyau de macOS lui-même et je n'ai pas besoin de spécifier un shebang. Je ne veux pas non plus que quelqu'un puisse l'ouvrir avec un éditeur de texte ou similaire et voir le code.

1 votes

C'est la même question que vous avez posée qui a été fermée! apple.stackexchange.com/questions/402870/…

7 votes

Comme indiqué, c'est impossible. Les scripts bash sont, par définition, des fichiers texte qui indiquent à bash ce qu'il doit faire, et non des exécutables binaires qui seraient chargés par le noyau. Selon votre objectif réel, il pourrait y avoir un moyen d'y parvenir, mais vous devriez expliquer ce que vous essayez réellement de réaliser (voir problème XY).

2 votes

Doit-il s'agir d'un script bash? Il existe d'autres langages plus adaptés pour produire un binaire compilé ou du pseudo-code.

16voto

Jose Chavez Points 645

Je voudrais jeter un œil à un projet nommé shc (Shell script compiler).

https://github.com/neurobin/shc

Il prend un script shell et le compile en code source C. Le code source C peut ensuite être compilé avec un compilateur C standard en un exécutable binaire.

Cela vous permet d'exécuter le script que vous avez créé sans que le contenu du script shell ne soit immédiatement révélé en clair. Ce serait un exécutable binaire comme tant d'autres.

Il pourrait falloir un peu d'essais et d'erreurs pour faire analyser votre script spécifique par shc en fonction des fonctionnalités avancées que vous utilisez dans votre script bash, mais cela devrait vous mener la plupart du chemin.

Notez que le programme crypte vraiment votre script shell et l'intègre dans le binaire. Lorsque le binaire est exécuté, le script est décrypté et exécuté à nouveau à l'aide d'un shell ordinaire. Pour les programmeurs, il serait trivial de casser cela pour révéler le contenu de votre script, mais pour cacher le contenu du script à l'utilisateur domestique moyen, cela serait peut-être suffisant.

Si vous avez HomeBrew installé, vous pouvez installer shc en exécutant la commande suivante dans le Terminal :

brew install shc

Ensuite, il suffit d'exécuter shc pour convertir votre script en binaire :

shc -U -f myscript.sh -o mybinary

La commande mybinary est alors le produit fini.

9voto

David Anderson Points 30783

Comme jksoegaard l'a déjà signalé, il existe la commande shc. Ci-dessous un exemple d'installation et d'utilisation de cette commande. J'ai testé cette réponse avec macOS Big Sur.

Voici les étapes que j'ai utilisées pour installer shc.

  1. Ouvrez Terminal en appuyant sur commande+espace, puis tapez terminal et appuyez sur la touche Entrée.

  2. Installez d'abord homebrew.

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null
  3. Installez shc.

    brew install shc

Ci-dessous se trouve la liste du fichier de script de test nommé hello.sh.

#!/bin/bash
osascript -e 'display dialog "Salut"' >/dev/null'

Voici les étapes que j'ai utilisées pour créer et tester l'exécutable.

  1. Entrez la commande suivante pour compiler le script en utilisant shc.

    shc -f hello.sh
  2. Entrez la commande suivante pour renommer l'exécutable.

    mv hello.sh.x hello
  3. Entrez la commande pour tester.

    ./hello

    Ci-dessous se trouve la boîte de dialogue résultante.


Annexe

Ci-dessous se trouve la sortie de l'exécution des commandes.

Dernière connexion : jeu.  8 oct. 06:36:48 sur la console
dma@dmas-Mac-mini ~ % ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null 
Mot de passe :
==> Vous utilisez macOS 11.0.
==> Nous ne fournissons pas de support pour cette version préliminaire.
Cette installation peut ne pas réussir.
Après l'installation, vous rencontrerez des échecs de compilation avec certaines formules.
Veuillez soumettre des pull requests au lieu de demander de l'aide sur le GitHub de Homebrew,
Discourse, Twitter ou IRC. Vous êtes responsable de résoudre tous les problèmes que vous
rencontrez pendant l'exécution de cette version préliminaire.

==> Ce script installera :
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> Les répertoires existants suivants seront rendus accessibles en écriture par le groupe :
/usr/local/bin
==> Les répertoires existants suivants auront leur propriétaire défini sur dma :
/usr/local/bin
==> Les répertoires existants suivants auront leur groupe défini sur admin :
/usr/local/bin
==> Les nouveaux répertoires suivants seront créés :
/usr/local/etc
/usr/local/include
/usr/local/lib
/usr/local/sbin
/usr/local/share
/usr/local/var
/usr/local/opt
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var/homebrew
/usr/local/var/homebrew/linked
/usr/local/Cellar
/usr/local/Caskroom
/usr/local/Homebrew
/usr/local/Frameworks
==> Les outils de ligne de commande Xcode seront installés.
==> /usr/bin/sudo /bin/chmod u+rwx /usr/local/bin
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/bin
==> /usr/bin/sudo /usr/sbin/chown dma /usr/local/bin
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/bin
==> /usr/bin/sudo /bin/mkdir -p /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /usr/local/Cellar /usr/...
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked /u...
==> /usr/bin/sudo /usr/sbin/chown dma /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/linked ...
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/etc /usr/local/include /usr/local/lib /usr/local/sbin /usr/local/share /usr/local/var /usr/local/opt /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew /usr/local/var/homebrew/link...
==> /usr/bin/sudo /bin/mkdir -p /Users/dma/Library/Caches/Homebrew
==> /usr/bin/sudo /bin/chmod g+rwx /Users/dma/Library/Caches/Homebrew
==> /usr/bin/sudo /usr/sbin/chown dma /Users/dma/Library/Caches/Homebrew
==> Recherche en ligne des Outils de ligne de commande
==> /usr/bin/sudo /usr/bin/touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
==> Installation des Outils de ligne de commande pour Xcode-12.0
==> /usr/bin/sudo /usr/sbin/softwareupdate -i Outils\ de\ ligne\ de\ commande\ pour\ Xcode-12.0
Software Update Tool

Recherche des logiciels disponibles

Téléchargement des Outils de ligne de commande pour Xcode
Outils de ligne de commande pour Xcode téléchargés
Installation des Outils de ligne de commande pour Xcode
Terminé avec les Outils de ligne de commande pour Xcode
Terminé.
==> /usr/bin/sudo /bin/rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
Mot de passe :
==> /usr/bin/sudo /usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
==> Téléchargement et installation de Homebrew...
HEAD est maintenant à f84b9a027 Fusionner la demande de tirage #8878 de reitermarkus/upgrade-casks
==> Homebrew est entièrement géré par des bénévoles non rémunérés. Merci de penser à faire un don :
  https://github.com/Homebrew/brew#donations
Déjà à jour.
==> Installation réussie !

==> Homebrew a activé l'analyse anonyme agrégée des formules et casks.
Consultez la documentation sur l'analyse (et comment la désactiver) ici :
  https://docs.brew.sh/Analytics
Aucune donnée d'analyse n'a encore été envoyée (ou ne le sera pendant cette exécution de `install`).

==> Homebrew est entièrement géré par des bénévoles non rémunérés. Merci de penser à faire un don :
  https://github.com/Homebrew/brew#donations

==> Étapes suivantes :
- Exécutez `brew help` pour commencer
- Documentation supplémentaire : 
    https://docs.brew.sh
dma@dmas-Mac-mini ~ % brew install shc
Mise à jour de Homebrew...
==> Mise à jour automatique de Homebrew !
Mise à jour de 1 tonneau (homebrew/core).
==> Formules mises à jour
Mise à jour de 4 formules.

Attention : Vous utilisez macOS 11.0.
Nous ne fournissons pas de support pour cette version préliminaire.
Vous rencontrerez des échecs de compilation avec certaines formules.
Veuillez soumettre des pull requests au lieu de demander de l'aide sur GitHub d'Homebrew,
Discourse, Twitter ou IRC. Vous êtes responsable de résoudre tous les problèmes que vous
rencontrez pendant l'utilisation de cette version préliminaire.

==> Téléchargement https://homebrew.bintray.com/bottles/shc-4.0.3.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Versement de shc-4.0.3.catalina.bottle.tar.gz
  /usr/local/Cellar/shc/4.0.3: 17 fichiers, 101,2 Ko
dma@dmas-Mac-mini ~ % pwd
/Users/dma
dma@dmas-Mac-mini ~ % cd Documents 
dma@dmas-Mac-mini Documents % shc -f hello.sh
dma@dmas-Mac-mini Documents % mv hello.sh.x hello
dma@dmas-Mac-mini Documents % ./hello

3 votes

Pas besoin d'installer homebrew en premier lieu: shc compile facilement à partir de la source

2 votes

Peut-être, mais je n'avais pas de compilateur installé. L'installation de Brew l'a fait pour moi. Voir la partie Annexe de ma réponse. Je pourrais me tromper, mais je suppose que cela a pris moins d'espace que l'installation de tout Xcode.

2 votes

Tout ce dont on a besoin d'avoir installé est Outils en ligne de commande pour Xcode pour compiler directement à partir du code source et installer comme indiqué sous Installer sur github.com/neurobin/shc, ce qui est fait lors de l'installation de Homebrew si ce n'est pas déjà installé.

6voto

Douglas Points 10417

Bash est techniquement un langage interprété, il n'est pas compilé; il n'est pas possible de le compiler.

Bash est le shell, ou interpréteur de commandes, pour le système d'exploitation GNU.

Cependant, il est possible de l'obfusquer pour que les regards curieux ne puissent pas lire votre script.

Utilisez openssl pour encoder le fichier.

J'ai créé un simple fichier script Zsh appelé arraytest.sh qui s'exécutera dans Zsh (c'est ce que j'avais disponible à ce moment-là). Je ne vais pas poster le script shell réel, à la place, je vais poster l'encodage en base64.

Sur mon ordinateur, j'exécute la commande suivante sur mon script et obtiens les résultats suivants:

% openssl base64 < arraytest.sh

IyEvYmluL3pzaAoKZGVjbGFyZSAtQSBwcm9ncz0oW2dzXT0iR2hvc3RzY3JpcHQi
IFtic109IkJ1bGxzaGl0IiBbYWJdPSJWb2RrYSIpCgoKbGV0IGFzaXplPSR7I3By
b2dzW0BdfQpsZXQgYnNpemU9JGFzaXplLTEKbGV0IGk9MQpmb3IgeCBpbiAiJHtw
cm9nc1tAXX0iOwpkbwogIGlmIFsgJGkgLWVxICRic2l6ZSBdICAgCiAgdGhlbgog
ICBwcmludGYgIiR4IGFuZCAiCiAgZWxpZiBbICRpIC1sZSAkYnNpemUgXSAmJiBb
ICRpIC1nZSAxIF0KICB0aGVuCiAgICBwcmludGYgIiR4LCAiCiAgZWxzZQogICAg
cHJpbnRmICIkeCIKICBmaQogICgoaSsrKSkKZG9uZQoKcHJpbnRmICIuXG4iCmVj
aG8gRG9uZS4KCg==

Cet sortie doit être enregistrée dans un fichier. Appelons-le monscriptencodé. Vous pouvez le copier et le coller dans un nouveau fichier. Vous n'avez pas besoin de le rendre exécutable. Une fois que vous avez copié ce script dans votre presse-papiers, exécutez la commande suivante

% pbpaste > monscriptencodé

Maintenant, vous devriez avoir un fichier appelé monscriptencodé. Ensuite, pour l'exécuter, vous devez renvoyer cet encodage via openssl pour le décoder, puis le rediriger vers votre shell.

% cat monscriptencodé | openssl base64 -d | zsh

Cela devrait exécuter le script et générer une sortie à partir d'un tableau associatif.

Alors, comment pouvez-vous rendre cela autonome?

#!/bin/zsh
#
#Nom du Script:  script_encodé.sh

code="IyEvYmluL3pzaAoKZGVjbGFyZSAtQSBwcm9ncz0oW2dzXT0iR2hvc3RzY3JpcHQi
IFtic109IkJ1bGxzaGl0IiBbYWJdPSJWb2RrYSIpCgoKbGV0IGFzaXplPSR7I3By
b2dzW0BdfQpsZXQgYnNpemU9JGFzaXplLTEKbGV0IGk9MQpmb3IgeCBpbiAiJHtw
cm9nc1tAXX0iOwpkbwogIGlmIFsgJGkgLWVxICRic2l6ZSBdICAgCiAgdGhlbgog
ICBwcmludGYgIiR4IGFuZCAiCiAgZWxpZiBbICRpIC1sZSAkYnNpemUgXSAmJiBb
ICRpIC1nZSAxIF0KICB0aGVuCiAgICBwcmludGYgIiR4LCAiCiAgZWxzZQogICAg
cHJpbnRmICIkeCIKICBmaQogICgoaSsrKSkKZG9uZQoKcHJpbnRmICIuXG4iCmVj
aG8gRG9uZS4KCg=="

echo "$code" | openssl base64 -d | zsh

Enregistrez ce script sous le nom de script_encodé.sh, rendez-le exécutable puis exécutez-le avec la commande ./script_encodé.sh

Bonus...

(Cela suppose un scénario où un administrateur doit exécuter un script discrètement sur une ou plusieurs machines sous sa responsabilité.)

Si vous voulez vraiment cacher cela aux "regards curieux", utilisez cette commande en une seule ligne:

% openssl base64 < script.sh | ssh utilisateur@hôte.domaine ' openssl base64 -d | bash'

Cela va encoder le script, le rediriger à travers une connexion SSH où il décode le script et le passe à l'interpréteur de commandes.

vérification verte Obfusque le code
vérification verte Aucun outil tiers nécessaire
vérification verte Multiplateforme (testé de l'hôte macOS au distant FreeBSD)
vérification verte Pas besoin de définir le bit exécutable (chmod +x)
vérification verte Gatekeeper sur macOS est rendu inopérant car ce n'est pas une application qui doit être notariée ou explicitement autorisée par l'utilisateur.

Évidemment, vous avez besoin d'un compte sur le distant et, bien que pratique, mais pas obligatoire, des clés SSH activées pour ne pas avoir à entrer un mot de passe, surtout si vous exécutez ceci sur un lot de machines.


Note: Cela a été fait en Zsh avec un tableau associatif. Cela peut fonctionner en Bash mais vous aurez besoin d'au moins la version 4 de Bash pour fonctionner correctement. Il n'y a rien de malveillant dans le script. Il affichera 3 mots et ensuite, sur une nouvelle ligne, le mot "Terminé" pour indiquer que le script est terminé.

Si vous voulez vérifier que le code vient vraiment de moi, créez un fichier appelé monscriptencodé dans vi, collez le code (sans guillemets), assurez-vous d'appuyer sur "I" pour "Insérer" avant de coller, enregistrez-le et exécutez la commande et vérifiez le hachage ci-dessous

% shasum -a 256 monscriptencodé
d4fc6ce35480b0ace6ed0e1c910f1f40079a106b1914d767fa17ada02a422f88  monscriptencodé

Cela fonctionnera uniquement si vous utilisez le même nom de fichier. J'ai testé ceci sur plusieurs plates-formes sur macOS et sur FreeBSD. Si vous n'obtenez pas le même hachage, faites-le moi savoir.

3 votes

Le OP, entre autres choses, déclare : "Je ne veux pas non plus que quiconque puisse l'ouvrir avec un éditeur de texte ou similaire et être capable de voir le code." et ce que vous proposez ne couvre pas vraiment car, non seulement on peut ouvrir le p. ex. encoded_script.sh, on peut aussi voir ce qu'il y a dedans et aussi facilement décoder le texte encodé pour voir ce qu'il dit également.

2 votes

@user3439894 Je suppose que dire ce qu'il veut n'est pas possible mais dire "Cependant, il est possible de obscurcir pour que les regards curieux ne puissent pas voir votre script" n'a pas d'importance ?

2 votes

Techniquement, ce n'est pas parce qu'une langue est "une langue interprétée" en ce moment, qu'elle ne peut pas devenir une langue compilée plus tard. Donc dire que ce n'est pas possible en se basant là-dessus est un peu léger.

3voto

Natsfan Points 12853

Je ne sais pas si cela fera ce que vous voulez mais l'application gratuite Platypus prendra un script en ligne de commande et le convertira en une application Mac. Fonctionne également avec Python, Perl et d'autres scripts. Vous pouvez en savoir plus en suivant le lien que j'ai fourni pour voir si cela fera ce que vous voulez. Remarque : En utilisant ma méthode, il est possible de voir le script original.

0 votes

Le PO, entre autres choses, déclare "Je ne veux pas non plus que quiconque puisse l'ouvrir avec un éditeur de texte ou similaire et voir le code. " et bien que Platypus crée un paquet d'application, néanmoins, le script shell passé à celui-ci reste sous forme lisible par l'homme dans le paquet d'application à par exemple nom.app/Contents/Resources/$script.

0 votes

J'ai essayé de regarder le code mais je n'ai pas pu trouver le fichier lisible par l'homme. Je ne dis pas qu'il n'est pas là, juste que je n'ai pas pu le trouver et j'ai bien pris cela en considération. Je vais vérifier à nouveau. Merci.

0 votes

Je suis retourné dans l'application mais je n'ai toujours pas pu trouver le fichier du script original. Si vous savez où il pourrait se trouver dans le répertoire des fichiers de l'application, veuillez me le faire savoir. J'ai vérifié ccontents/MacOS et le seul fichier présent est le fichier exécutable qui semble être en format binaire ou dans un format illisible. J'ai également vérifié Contents/Resources et il n'y était pas non plus.

3voto

user3439894 Points 52496

Tant que ce n'est pas complètement clair ce que vous recherchez réellement, voici ce que je suggère :

  • Crée à partir d'un bash script une structure de bundle d'application avec un seul exécutable binaire qui ne contient pas sous une forme lisible par l'homme le code du script utilisé pour le créer.
  • Se lance comme un bundle d'application macOS ordinaire tournant sous le nom du bundle d'application.
  • N'ouvre pas de Terminal pendant son exécution.

Cela dit, cela peut quand même être interprété car si vous regardez les Fichiers et Ports Ouverts dans le Monitor d'activité pour par exemple le nom.app bundle d'application, /bin/bash est répertorié.

Il existe un projet GitHub nommé bashapp qui indique :

bashapp prend en entrée un script bash et génère un exécutable binaire ainsi qu'une structure de répertoire d'application OS X. Cela permet aux développeurs de fournir des scripts bash cliquables dans Finder sans que des terminaux apparaissent, etc. Utile pour les scripts de lancement, de service, etc.

Il fournit également un simple cryptage source comme moyen d'obscurcir le script bash. Vous pouvez spécifier votre propre clé, ou laisser bashapp générer une clé aléatoire de taille aléatoire pour vous, au moins 32 octets de long.

Vous devrez avoir les Outils en Ligne de Commande pour Xcode installés afin de compiler l'exécutable bashapp qui crée le bundle d'application. Voir : Comment Installer les Outils en Ligne de Commande dans Mac OS X (Sans Xcode) Ou dans Terminal exécutez : xcode-select --install

Cela dit, il y avait une chose ennuyeuse en cela : la Icône Dock pour l'application rebondit dans le Dock pendant son exécution. Une solution de contournement est de ne pas l'afficher dans le Dock en exécutant ce qui suit dans Terminal:

defaults write '/chemin/vers/$nom.app/Contents/Info.plist' LSUIElement -bool oui

Changer /chemin/vers/$nom.app selon votre besoin.

0 votes

C'est un outil très intéressant, cependant il y a un problème lorsque vous essayez de distribuer l'application - Gatekeeper. Cette application ne s'exécutera pas sur macOS 10.14+ sans une certaine forme d'intervention.

0 votes

@Allan, RE: "Cette application ne fonctionnera pas sur macOS 10.14+ sans une certaine forme d'intervention." -- Je trouve que cette déclaration n'est pas vraie car j'ai testé une application créée avec bashapp sur macOS High Sierra et elle s'est exécutée sur macOS Catalina sans problème. Cela dit, il n'y avait aucune mention explicite de la distribution du fichier dans le message d'origine, donc ce n'est pas un problème pour le moment.

0 votes

Comment votre réponse améliore-t-elle le commentaire que vous avez laissé sous les autres réponses ici qui dit, entre autres, "Je ne veux pas non plus que quelqu'un puisse l'ouvrir avec un éditeur de texte ou similaire et voir le code." :-)

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X