【问题标题】:Getting the source code of a running Python script externally从外部获取正在运行的 Python 脚本的源代码
【发布时间】:2016-11-26 15:09:01
【问题描述】:

原问题

我最近编写了一个类似于服务器的小型 Python 脚本,它有 +/- 200 行长,并且没有分成多个文件。原始文件已被删除且没有备份,但进程本身仍在运行。

我知道下面的代码会读出当前脚本的源代码,但是这是假设文件仍然存在(并且该代码必须在包含的脚本中)。 source

with open(__file__) as f:
    print f.read()

我想知道的是,是否有可能在不再拥有原始文件的情况下获得无限运行脚本的源代码。我目前正在使用基于 Ubuntu Linux 的服务器,但我将不胜感激跨平台解决方案。谢谢


编辑

到目前为止,我只能读取脚本的反汇编字节码,或直接读取变量。我需要该脚本的主要原因主要是为了在删除脚本后丢失数据库密码。

为此,我必须安装使用gdbpyrasite。 以下是我用来为 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


【解决方案1】:

您是否有权访问正在运行该进程的服务器?

那你可以试试http://pyrasite.readthedocs.io/en/latest/CLI.html

(免责声明:我自己从未使用过)

HTH,

【讨论】:

  • 我拥有服务器的完全访问权限(根级别),谢谢,我会检查一下
  • 我认为这是个好主意。一旦获得了 pyrasite shell,您可以按照dir(sys.modules[__name__]) 的方式运行一些东西来获取作用域中定义的函数和变量并反编译前者的代码,但是您如何获得句柄在模块范围的代码上?
【解决方案2】:

Pyrasite 可能是您最好的选择,但这里有一个完全不了解的情况:尝试检查目录 /proc/<pid>/fd/ 中的文件,其中 pid 是您正在运行的脚本的进程 ID。如果你很幸运,你可以恢复一个pyc,然后你可以反编译它。

【讨论】:

  • Python 不会打开源文件或字节码文件。
猜你喜欢
  • 2015-10-01
  • 2018-08-14
  • 1970-01-01
  • 2011-05-26
  • 2022-11-10
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多