简体   繁体   中英

Getting the source code of a running Python script externally

Original question

I recently wrote a small Python script which acted like a server, it was +/- 200 lines long and wasn't separated into multiple files. The original file has since been removed and has no backup, however the process itself is still running.

I know the following code will read out the source code of the current script, however that's assuming the file still exists (and that code must be in the containing script). source

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

What I would like to know, is if it's possible to get the source code of an infinitely running script without having the original file anymore. I'm currently using an Ubuntu Linux based server, but a cross platform solution would be appreciated. Thank you


Edit

So far I've only been able to read the disassembled bytecode of my scripts, or read out variables directly. The main reason I needed the script was mainly to get my database passwords back after losing them when the script was removed.

To do this, I had to install pyrasite which uses gdb . Here's a list of commands I used to install all required libraries for 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

Once I installed everything, I used pyrasite to inject a Python IDLE shell into the running process, so I could interact with the code.

# 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)

>>> 

Since I needed my database credentials back, I simply echoed them out by writing them to the shell:

# There we go
>>> DB_USER
'root'

>>> DB_PASS
'********'

>>> DB_NAME
'SomeDatabase'

>>> DB_HOST
'127.0.0.1'

Altough the source code of the script is gone, we can still decompile the object that is in memory using dis and passing our methods we want to it. I also attempted to use the inspect module, but trying to call inspect.getsourcelines() would simply lead to an 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

If you had any text in the method you wanted back, you can find it in there. I was unable to convert this code back into usable python but I managed to get what I needed.

Do you have access to the server where the process is running?

Then maybe you could try http://pyrasite.readthedocs.io/en/latest/CLI.html

(Disclaimer: I've never used it myself)

HTH,

Pyrasite is probably your best bet but here's a total shot in the dark: Try checking for files in the directory /proc/<pid>/fd/ , where pid is the process id of your running script. If you're very lucky you could recover a pyc which you could then decompile.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM