Czy można pobrać zawartość działającego skryptu bash z pamięci RAM

18

Przez przypadek nadpisałem bardzo skomplikowany skrypt bash, w którym próbowałem zaimplementować scoping i wątki w uporządkowany sposób.

Teraz ten sam skrypt nadal działa, ale pliku już nie ma, pytanie brzmi: czy można skanować ram i znaleźć reprezentację żądań samego pliku?

Kolejny problem: nie mogę znaleźć pliku / dev / mem lub / dev / kmem, już próbowałem go grepować dla zawartości.

Do środowiska: Hostet maszyny debian / sid (vps) na stronie vpsfx.com

root @ heisenberg: ~ # ls -a / dev
. kmsg ptyp2 ptyp9 losowy 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
konsola pts ptyp6 ptypd stdout tty2 tty9 ttyp6 ttypd
fd ptyp0 ptyp7 ptype tty tty3 ttyp0 ttyp7 ttype
pełny ptyp1 ptyp8 ptypf tty0 tty4 ttyp1 ttyp8 ttypf
Thomas Nordquist
źródło

Odpowiedzi:

17

Spójrz na / proc / $ PID / fd. Tam powinieneś mieć wszystkie deskryptory plików otwarte przez proces, w tym sam skrypt. Wystarczy cat $FD > /tmp/yourscript.sh, aby go odzyskać.

Diego Woitasen
źródło
1
Poparłem tę odpowiedź, mimo że w rzeczywistości nie odpowiada ona na pytanie zadane przez PO. OP zapytał, jak odzyskać skrypt z pamięci RAM , a nie z systemu plików. Ta odpowiedź korzysta z systemu plików, opierając się na fakcie, że plik skryptu nie jest ostatecznie odłączany, dopóki końcowa liczba odwołań nie osiągnie zera.
Jonathan Ben-Avraham,
1
System plików proc znajduje się tylko w pamięci RAM i prawie wszyscy go zainstalowali.
Diego Woitasen
2
W /procfs nie rezydują w pamięci RAM. W rzeczywistości, to nie ma miejsca zamieszkania w dowolnym miejscu . Zobacz unix.stackexchange.com/questions/74713/… . Chociaż możesz pobrać fd z /proc, cating odczytuje plik z fs, a nie RAM. To prawda, że ​​usunąłeś plik, zmniejszając liczbę odwołań do i-węzłów i nikt już go nie widzi, ale tak naprawdę nie jest usuwany z fs, dopóki proces uruchamiający skrypt nie zamknie go. Zobacz stackoverflow.com/questions/2028874/… .
Jonathan Ben-Avraham
Tak masz rację. Sam plik jest odczytywany z systemu plików dysku. / proc istnieje w pamięci RAM, nie jest jak ramdysk, ale informacje są w pamięci RAM. Z wyjątkiem / proc / $ PID / fd i może być inny. W każdym razie @ Thomas Nordquist chce odzyskać plik, i to jest ten prosty sposób.
Diego Woitasen
Pracowałem dla mnie, po kilku próbach znalazłem właściwy deskryptor pliku, w końcu mogę zamknąć proces i kontynuować
Thomas Nordquist
16

Zakładając, że OP naprawdę znaczył z pamięci RAM, a nie w żaden możliwy sposób , i zakładając, że proces, w którym skrypt został wykonany, ma zerowy limit plików podstawowych (co zwykle jest ustawieniem domyślnym cat /proc/PID/limits), wtedy musisz dołączyć do procesu i albo ustaw limit rdzenia na wystarczająco dużą wartość, aby uwzględnić obraz procesu i użyj sygnału ABRT do wygenerowania pliku rdzenia, lub użyj takiego narzędzia, gdbktóre może dołączyć do procesu i wygenerować obraz rdzenia procesu z pamięci RAM.

  1. zainstalować gdb

W niektórych powłokach z taką samą własnością jak uruchomiony skrypt lub własność root:

  1. Czy ps axznaleźć identyfikator procesu (PID)
  2. gdb -p PID

Zauważ, że zatrzyma to kontynuowanie wykonywania procesu, ale nie usunie go z tabeli procesów.

  1. W gdb wydaj polecenie generate-core-file

gdb powinien odpowiedzieć na coś podobnego Saved corefile core.15113, zakładając, że PID to 15113.

  1. W gdb wydaj polecenie detach

Twój skrypt będzie kontynuował (wznawianie) działania.

  1. W gdb wydaj polecenie quit
  2. W powłoce biegnij strings core.15113 > my_script.sh

Otwórz my_script.shw jakimś edytorze. Tekst skryptu powinien znajdować się na końcu pliku przed sekcją środowiska. Użyj edytora, aby zeskrobać sekcje przed i po skrypcie.

Przetestuj to rozwiązanie na innym skrypcie, zanim użyjesz go w skrypcie nagrody. YMMV.

Sekwencja wygląda następująco:

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
źródło
To rozwiązanie również działa, ale tutaj jest trochę kopania, dziękuję za pomoc
Thomas Nordquist
To rozwiązanie działało dla mnie! Zastąpiłem oryginalny plik i miałem nadzieję, że nadal będzie w pamięci. Otwarty fd (inna odpowiedź) wskazywał na zaktualizowany plik. To mnie uratowało!
saveman71
0

dd partycję dysku twardego w nakładających się fragmentach i grep binary dla części skryptu. jeśli masz szczęście, wypisz te fragmenty do tymczasowego katalogu w pamięci RAM, aby się w nim zapisać i zapisać cykle zapisu na dysku twardym lub ssd. nie, to nie jest rozwiązanie „z pamięci RAM”. pamiętaj o tym, że podczas odczytu dysku bajty po bajcie skrypty mogą być w formacie zestawu znaków utf-8 (lub podobnym), więc parametry grep mogą również wymagać dostosowania.

Michael Grieswald
źródło