Reputation: 4708
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
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.
Upvotes: 5
Views: 2847
Reputation: 4691
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.
Upvotes: 0
Reputation: 1286
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,
Upvotes: 3