【发布时间】:2016-11-26 15:09:01
【问题描述】:
原问题
我最近编写了一个类似于服务器的小型 Python 脚本,它有 +/- 200 行长,并且没有分成多个文件。原始文件已被删除且没有备份,但进程本身仍在运行。
我知道下面的代码会读出当前脚本的源代码,但是这是假设文件仍然存在(并且该代码必须在包含的脚本中)。 source
with open(__file__) as f:
print f.read()
我想知道的是,是否有可能在不再拥有原始文件的情况下获得无限运行脚本的源代码。我目前正在使用基于 Ubuntu Linux 的服务器,但我将不胜感激跨平台解决方案。谢谢
编辑
到目前为止,我只能读取脚本的反汇编字节码,或直接读取变量。我需要该脚本的主要原因主要是为了在删除脚本后丢失数据库密码。
为此,我必须安装使用gdb 的pyrasite。 以下是我用来为 Ubuntu 安装所有必需库的命令列表:
# Installing GDB and the libraries I had to use
root@hostname:~# apt-get install glibc-source
root@hostname:~# apt-get install libc6-dbg
root@hostname:~# apt-get install gdb
# Installing pyrasite
root@hostname:~# pip install pyrasite
root@hostname:~# echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
安装完所有东西后,我使用 pyrasite 将 Python IDLE shell 注入到正在运行的进程中,这样我就可以与代码进行交互了。
# Injecting a python IDLE shell into our process and retrieving variable values
root@hostname:~# ps aux | grep python
root 7589 0.0 1.3 230544 13296 pts/1 S 12:16 0:00 python main.py
root 7610 0.0 0.1 11284 1088 pts/0 S+ 12:19 0:00 grep --color=auto python
root@hostname:~# pyrasite-shell 7589
Pyrasite Shell 2.0
Connected to 'python main.py'
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(DistantInteractiveConsole)
>>>
由于我需要我的数据库凭据,我只是通过将它们写入 shell 来回显它们:
# There we go
>>> DB_USER
'root'
>>> DB_PASS
'********'
>>> DB_NAME
'SomeDatabase'
>>> DB_HOST
'127.0.0.1'
尽管脚本的源代码已经消失,我们仍然可以使用dis 反编译内存中的对象并将我们想要的方法传递给它。我也尝试使用inspect 模块,但尝试调用inspect.getsourcelines() 只会导致IOError
>>> import dis
>>> dis.dis(foo)
Disassembly of foo:
7 0 LOAD_CONST 1 ('Hello world')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
如果您想要返回的方法中有任何文本,您可以在其中找到它。我无法将此代码转换回可用的 python,但我设法得到了我需要的东西。
【问题讨论】:
-
如果您使用的是cpython,它将是内存中的字节码(.pyc),据我了解,原始源已消失
-
按照 wim 的建议:尝试将进程内存转储到磁盘,在转储中找到字节码并在其上运行 pycdc?只是大声思考......
标签: python