Можно ли извлечь содержимое запущенного скрипта bash из ОЗУ?

18

Я случайно переписал очень сложный сценарий bash, в котором я попытался аккуратно реализовать область видимости и потоки.

Теперь тот же сценарий все еще выполняется, но файла больше нет, вопрос: можно ли сканировать через оперативную память и найти строковое представление самого файла?

Другая проблема: я не могу найти файл / dev / mem или / dev / kmem, уже пытался найти его для поиска.

К среде: это хост машины Debian / sid (vps) на vpsfx.com

root @ heisenberg: ~ # ls -a / dev
, kmsg ptyp2 ptyp9 случайный tty1 tty5 ttyp2 ttyp9 urandom
.. журнал ptyp3 ptypa shm tty10 tty6 ttyp3 ttypa xconsole
.udev null ptyp4 ptypb stderr tty11 tty7 ttyp4 ttypb ноль
char ptmx ptyp5 ptypc stdin tty12 tty8 ttyp5 ttypc
консоль pts ptyp6 ptypd stdout tty2 tty9 ttyp6 ttypd
fd ptyp0 ptyp7 ptype tty tty3 ttyp0 ttyp7 ttype
полный ptyp1 ptyp8 ptypf tty0 tty4 ttyp1 ttyp8 ttypf
Томас Нордквист
источник

Ответы:

17

Посмотрите на / proc / $ PID / fd. Там у вас должны быть все файловые дескрипторы, открытые процессом, включая сам скрипт. Просто cat $FD > /tmp/yourscript.shдолжно быть достаточно, чтобы восстановить его.

Диего Войтасен
источник
1
Я проголосовал за этот ответ, несмотря на то, что на самом деле он не отвечает на вопрос, заданный ОП. ОП спросил, как восстановить скрипт из оперативной памяти , а не из файловой системы. Этот ответ использует файловую систему, полагаясь на тот факт, что файл сценария не будет окончательно отключен, пока окончательный счетчик ссылок не достигнет нуля.
Джонатан Бен-Авраам
1
Файловая система proc находится только в оперативной памяти, и почти все ее смонтировали.
Диего Войтасен
2
В /procфс не находится в оперативной памяти. На самом деле, он не находится в любом месте . См. Unix.stackexchange.com/questions/74713/… . Несмотря на то, что вы можете получить fd от /proc, catfd читает файл из fs, а не из RAM. Правда, вы удалили файл, сократив количество ссылок на узлы, и теперь никто не может его увидеть, но он фактически не удаляется из fs, пока процесс, выполняющий скрипт, не закроет его. См. Stackoverflow.com/questions/2028874/… .
Джонатан Бен-Авраам
Да ты прав. Сам файл читается из файловой системы диска. / proc существует в RAM, это не похоже на виртуальный диск, но информация находится в RAM. За исключением / proc / $ PID / fd и может быть другим. В любом случае @Thomas Nordquist хочет восстановить файл, и это простой способ.
Диего Войтасен
Работая на меня, после нескольких попыток я нашел правильный дескриптор файла, наконец, я могу закрыть процесс и продолжить
Томас Нордквист
16

Если предположить, что OP действительно имел в виду оперативную память, а не каким-либо возможным способом , и предположить, что процесс, в котором выполнялся сценарий, имеет нулевое ограничение файла ядра (что обычно является настройкой по умолчанию cat /proc/PID/limits), то вам необходимо присоединиться к процессу и либо установите ограничение ядра на достаточно большое значение, чтобы включить образ процесса и использовать сигнал ABRT для генерации файла ядра, или использовать такой инструмент, gdbкоторый может подключаться к процессу и генерировать образ ядра процесса из ОЗУ.

  1. устанавливать gdb

В некоторых оболочках с тем же владельцем, что и у запущенного скрипта или владельца root:

  1. Есть ли ps axнайти идентификатор процесса (PID)
  2. gdb -p PID

Обратите внимание, что это остановит выполнение процесса от продолжения, но не удалит его из таблицы процессов.

  1. В gdb введите команду generate-core-file

GDB должен ответить с чем-то вроде Saved corefile core.15113, предполагая, что PID 15113.

  1. В gdb введите команду detach

Ваш скрипт будет продолжать (возобновлять) работу.

  1. В gdb введите команду quit
  2. В оболочку беги strings core.15113 > my_script.sh

Откройте my_script.shв каком-то редакторе. Текст вашего скрипта должен быть ближе к концу файла перед разделом среды. Используйте редактор, чтобы соскрести разделы до и после сценария.

Протестируйте это решение на другом скрипте, прежде чем использовать его в своем призовом скрипте. YMMV.

Последовательность выглядит так:

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:~$ 
Джонатан Бен-Авраам
источник
Это решение тоже работает, но здесь есть кое-какие вопросы, спасибо за вашу помощь
Томас Нордквист,
Это решение, которое сработало для меня! Я перезаписал оригинальный файл и надеялся, что он все еще будет в памяти. Открытый fd (другой ответ) указал на обновленный файл. Это спасло меня!
saveman71
0

dd раздел жесткого диска в перекрывающихся чанках и бинарный файл grep для частей скрипта. если вам повезет, запишите эти куски во временную директорию в оперативной памяти, чтобы они появились в ней, чтобы сохранить цикл записи жесткого диска или ssd. нет, это не решение "от оперативной памяти". помните о том, что при чтении байтовых скриптов на диске может использоваться формат кодировки utf-8 (или аналогичный), поэтому параметры grep также могут быть адаптированы.

Майкл Грисвальд
источник