Est-il possible de récupérer le contenu d'un script bash en cours d'exécution à partir de la RAM

18

J'ai accidentellement écrasé un script bash très complexe, où j'ai essayé d'implémenter la portée et le filetage de manière ordonnée.

Maintenant, le même script est toujours en cours d'exécution, mais le fichier n'est plus, la question est: est-il possible de parcourir le ram et de trouver la représentation sting du fichier lui-même?

Un autre problème est: je ne trouve pas le fichier / dev / mem ou / dev / kmem, déjà essayé de le récupérer pour le contenu.

Pour l'environnement: c'est un hostet debian / sid machine (vps) sur vpsfx.com

root @ heisenberg: ~ # ls -a / dev
. kmsg ptyp2 ptyp9 aléatoire tty1 tty5 ttyp2 ttyp9 urandom
.. log ptyp3 ptypa shm tty10 tty6 ttyp3 ttypa xconsole
.udev null ptyp4 ptypb stderr tty11 tty7 ttyp4 ttypb zero
char ptmx ptyp5 ptypc stdin tty12 tty8 ttyp5 ttypc
console pts ptyp6 ptypd stdout tty2 tty9 ttyp6 ttypd
fd ptyp0 ptyp7 ptype tty tty3 ttyp0 ttyp7 ttype
ptyp1 complet ptyp8 ptypf tty0 tty4 ttyp1 ttyp8 ttypf
Thomas Nordquist
la source

Réponses:

17

Jetez un œil à / proc / $ PID / fd. Là, vous devriez avoir tous les descripteurs de fichiers ouverts par le processus, y compris le script lui-même. Juste cat $FD > /tmp/yourscript.shdevrait être suffisant pour récupérer.

Diego Woitasen
la source
1
J'ai voté pour cette réponse malgré le fait qu'elle ne répond pas en fait à la question posée par le PO. L'OP a demandé comment récupérer le script de la RAM , pas du système de fichiers. Cette réponse utilise le système de fichiers, en s'appuyant sur le fait que le fichier de script n'est finalement pas dissocié jusqu'à ce que le décompte de références final atteigne zéro.
Jonathan Ben-Avraham
1
Le système de fichiers proc réside uniquement dans la RAM et présume que tout le monde l'a monté.
Diego Woitasen
2
Le /procfs ne réside pas dans la RAM. En fait, il ne réside nulle part . Voir unix.stackexchange.com/questions/74713/… . Bien que vous puissiez obtenir le fd /proc, catle fd lit le fichier à partir de fs, pas de RAM. Certes, vous avez supprimé le fichier, réduisant le nombre de références d'inode, et personne d'autre ne peut le voir maintenant, mais il n'est pas réellement supprimé du fs jusqu'à ce que le processus exécutant le script le ferme. Voir stackoverflow.com/questions/2028874/… .
Jonathan Ben-Avraham
Oui, tu as raison. Le fichier lui-même est lu à partir du système de fichiers du disque. / proc existe en RAM, ce n'est pas comme un disque virtuel, mais les informations sont en RAM. À l'exception de / proc / $ PID / fd et peut être autre. Quoi qu'il en soit, @Thomas Nordquist veut récupérer le fichier, et c'est le moyen le plus simple.
Diego Woitasen
A fonctionné pour moi, après quelques essais, j'ai trouvé le bon descripteur de fichier, enfin je peux fermer le processus et continuer
Thomas Nordquist
16

En supposant que l'OP signifiait vraiment à partir de la RAM et pas de toute manière possible , et en supposant que le processus dans lequel le script a été exécuté n'a aucune limite de fichier de base (qui est généralement le paramètre par défaut cat /proc/PID/limits), alors vous devez vous attacher au processus et soit définissez la limite de base sur une valeur suffisamment grande pour inclure l'image de processus et utiliser le signal ABRT pour générer le fichier de base, ou utilisez un outil tel que gdbcelui-ci peut se joindre à un processus et générer une image de base du processus à partir de la RAM.

  1. Installer gdb

Dans certains shell avec la même propriété que le script en cours d'exécution ou la propriété root:

  1. Faire ps axpour trouver l'ID de processus (PID)
  2. gdb -p PID

Notez que cela empêchera l'exécution du processus de continuer mais ne la supprimera pas de la table de processus.

  1. Dans gdb, lancez la commande generate-core-file

gdb devrait répondre avec quelque chose comme Saved corefile core.15113, en supposant que le PID est 15113.

  1. Dans gdb, lancez la commande detach

Votre script continuera (reprendra) à fonctionner.

  1. Dans gdb, lancez la commande quit
  2. En shell, exécutez strings core.15113 > my_script.sh

Ouvrez le my_script.shdans un éditeur. Le texte de votre script doit être vers la fin du fichier avant la section environnement. Utilisez l'éditeur pour gratter les sections avant et après le script.

Testez cette solution sur un autre script avant de l'utiliser sur votre script de prix. YMMV.

La séquence ressemble à ceci:

yba@tavas:~$ gdb -p 15113
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 15113
Reading symbols from /bin/bash...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libtinfo.so.5...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libtinfo.so.5
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libdl.so.2
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007feaf4b4c7be in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) generate-core-file
Saved corefile core.15113
(gdb) detach
Detaching from program: /bin/bash, process 15113
(gdb) quit
yba@tavas:~$ 
Jonathan Ben-Avraham
la source
Cette solution fonctionne aussi, mais voici quelques recherches, merci pour votre aide
Thomas Nordquist
C'est la solution qui a fonctionné pour moi! J'avais écrasé le fichier d'origine et j'espérais qu'il serait toujours en mémoire. Le fd ouvert (autre réponse) pointait vers le fichier mis à jour. Cela m'a sauvé!
saveman71
0

dd la partition du disque dur en morceaux se chevauchant et binaire grep pour des parties du script. si vous êtes chanceux, écrivez ces morceaux dans un répertoire temporaire dans ram pour y accéder pour sauvegarder votre disque dur ou les cycles d'écriture de ssd. non, ce n'est pas une solution «de bélier». soyez conscient du fait que lors de la lecture du disque octet par octet, les scripts peuvent être au format utf-8 (ou similaire) charset, de sorte que les paramètres grep devront également être adaptés.

Michael Grieswald
la source