Ist es möglich, den Inhalt eines laufenden Bash-Skripts aus dem RAM abzurufen?

18

Ich habe versehentlich ein sehr komplexes Bash-Skript überschrieben, in dem ich versucht habe, Scoping und Threading auf saubere Weise zu implementieren.

Jetzt läuft noch dasselbe Skript, aber die Datei ist nicht mehr vorhanden. Die Frage lautet: Ist es möglich, den RAM zu durchsuchen und die Stichdarstellung der Datei selbst zu finden?

Ein weiteres Problem ist: Ich kann die Datei / dev / mem oder / dev / kmem nicht finden und habe bereits versucht, nach Inhalten zu suchen.

Für die Umwelt: Es ist ein Debian / Sid-Rechner (VPS) -Hostet auf vpsfx.com

root @ heisenberg: ~ # ls -a / dev
. kmsg ptyp2 ptyp9 zufällig tty1 tty5 ttyp2 ttyp9 zufällig
.. 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
Konsolenpunkte ptyp6 ptypd stdout tty2 tty9 ttyp6 ttypd
fd ptyp0 ptyp7 ptype tty tty3 ttyp0 ttyp7 ttype
voll ptyp1 ptyp8 ptypf tty0 tty4 ttyp1 ttyp8 ttypf
Thomas Nordquist
quelle

Antworten:

17

Schauen Sie sich / proc / $ PID / fd an. Dort sollten Sie alle vom Prozess geöffneten Dateideskriptoren haben, einschließlich des Skripts selbst. Sollte cat $FD > /tmp/yourscript.shgerade ausreichen, um es wiederherzustellen.

Diego Woitasen
quelle
1
Ich habe diese Antwort positiv bewertet, obwohl sie die vom OP gestellte Frage nicht beantwortet. Das OP fragte, wie das Skript aus dem RAM wiederhergestellt werden könne , nicht aus dem Dateisystem. Bei dieser Antwort wird das Dateisystem verwendet, wobei die Verknüpfung der Skriptdatei erst dann endgültig aufgehoben wird, wenn die endgültige Referenzzahl Null erreicht.
Jonathan Ben-Avraham
1
Das proc-Dateisystem befindet sich nur im RAM und fast jeder hat es gemountet.
Diego Woitasen
2
Das /procfs befindet sich nicht im RAM. Tatsächlich befindet es sich nirgendwo . Siehe unix.stackexchange.com/questions/74713/… . Obwohl Sie die fd von erhalten können /proc, catliest die fd die Datei von fs, nicht von RAM. Richtig, Sie haben die Datei gelöscht, wodurch die Anzahl der Inode-Refs verringert wurde, und niemand anderes kann sie jetzt sehen. Sie wird jedoch erst dann aus dem fs gelöscht, wenn der Prozess, der das Skript ausführt, es schließt. Siehe stackoverflow.com/questions/2028874/… .
Jonathan Ben-Avraham
Ja, du hast recht. Die Datei selbst wird aus dem Dateisystem der Festplatte gelesen. / proc existiert im RAM, es ist nicht wie eine Ramdisk, aber die Informationen befinden sich im RAM. Mit Ausnahme von / proc / $ PID / fd und kann auch anders sein. Wie auch immer, @Thomas Nordquist möchte die Datei wiederherstellen, und das ist der einfache Weg.
Diego Woitasen
Arbeitete für mich, nach ein paar Versuchen fand ich den richtigen Dateideskriptor schließlich kann ich den Prozess schließen und fortfahren
Thomas Nordquist
16

Unter der Annahme, dass das OP wirklich RAM bedeutet und auf keine Weise möglich ist , und dass der Prozess, in dem das Skript ausgeführt wurde, keine Kerndateibeschränkung aufweist (dies ist normalerweise die Standardeinstellung cat /proc/PID/limits), müssen Sie eine Verbindung zum Prozess herstellen und beides Setzen Sie die Kernbeschränkung auf einen Wert, der groß genug ist, um das Prozessabbild einzuschließen und das ABRT-Signal zum Generieren der Kerndatei zu verwenden, oder verwenden Sie ein Tool gdb, das sich an einen Prozess anfügen lässt und ein Kernabbild des Prozesses aus dem RAM generiert.

  1. Installieren gdb

In einer Shell mit demselben Besitz wie das ausgeführte Skript oder Root-Besitz:

  1. Tun ps ax, um die Prozess-ID (PID) zu finden
  2. gdb -p PID

Beachten Sie, dass dadurch die Prozessausführung nicht fortgesetzt, aber nicht aus der Prozesstabelle entfernt wird.

  1. Geben Sie in gdb den Befehl aus generate-core-file

gdb sollte mit so etwas wie antworten Saved corefile core.15113, vorausgesetzt die PID ist 15113.

  1. Geben Sie in gdb den Befehl aus detach

Ihr Skript wird weiterhin ausgeführt (fortgesetzt).

  1. Geben Sie in gdb den Befehl aus quit
  2. In der Schale laufen strings core.15113 > my_script.sh

Öffne den my_script.shin irgendeinem Editor. Ihr Skripttext sollte sich am Ende der Datei vor dem Umgebungsabschnitt befinden. Verwenden Sie den Editor, um die Abschnitte vor und nach dem Skript zu entfernen.

Testen Sie diese Lösung in einem anderen Skript, bevor Sie sie in Ihrem Gewinnskript verwenden. YMMV.

Die Sequenz sieht folgendermaßen aus:

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
quelle
Diese Lösung funktioniert auch, aber hier ist etwas Graben beteiligt, danke für Ihre Hilfe
Thomas Nordquist
Dies ist die Lösung, die bei mir funktioniert hat! Ich hatte die ursprüngliche Datei überschrieben und hoffte, dass sie sich noch im Speicher befand. Das offene fd (andere Antwort) zeigte auf die aktualisierte Datei. Das hat mich gerettet!
Saveman71
0

dd die Festplattenpartition in überlappenden Blöcken und grep binary für Teile des Skripts. Wenn Sie Glück haben, schreiben Sie diese Chunks in ein temporäres Verzeichnis im RAM, um darin zu suchen und die Schreibzyklen Ihrer Festplatte oder SSD zu speichern. Nein, es ist keine From-Ram-Lösung. Beachten Sie, dass beim Lesen von disk byte byte Skripten möglicherweise das Zeichensatzformat utf-8 (oder ein ähnliches Format) verwendet wird. Daher müssen möglicherweise auch die grep-Parameter angepasst werden.

Michael Grieswald
quelle