Inject any bytecode into a running Python process

Source: Internet
Author: User

When debugging a Python program, generally we can only debug in the following ways:


1. Logs already in the program
2. Insert the import PDB in the code; Pdb.set_trace ()


However, the above methods also have inconvenient places, such as the already running program, it is impossible to stop the program after adding debugging code and add new log.


Inspired by the JAVA BTrace(https://kenai.com/projects/btrace) project, try to insert code into the running Python process, after the program runs to the specified function, Automatic connection to remote host for debugging


First of all, we introduce three open source projects, this experiment needs to use these three projects

1. Pyasite https://github.com/lmacken/pyrasite Tools for injecting code into running Python processes
2. Byteplay https://github.com/serprex/byteplay A byte-code maintenance project, similar to Java asm/cglib
3. Rpdb-shell Https://github.com/alex8224/Rpdb-Shell


The code to be injected, using the official ' Tornado Hello Demo ' as an example

Import Tornado.ioloopimport tornado.webimport osclass MainHandler (tornado.web.RequestHandler):    def get (self):                self.write ("Hello, World")        application = Tornado.web.Application ([    (R "/", MainHandler),]) if __name__ = = "__main__":    application.listen (8888)    print (Os.getpid ())    tornado.ioloop.IOLoop.instance (). Start ()




Inject the following code (' testinject.py ') into the **get**

Import sysimport disimport inspectfrom byteplay import *def wearedcode (fcode): c = Code.from_code (FCode) if c.code[1 ] = = (Load_const, ' injected '): return fcode c.code[1:1] = [(Load_const, Injected '), (store_f                    AST, ' name '), (load_fast, ' name '), (Print_item, none), (Print_newline, none),                     (Load_const,-1), (Load_const, None), (Import_name, ' rpdb '), (Store_fast, ' rpdb '), (Load_fast, ' rpdb '), (load_attr, ' Trace_to_remote '), (Load_const, ' 10.86.11.116 '), (CAL     L_function, 1), (Pop_top, None)] return C.to_code () def trace (frame, event, Arg): If event! = ' call ': return CO = Frame.f_code Func_name = Co.co_name if func_name = = "Write": RE turn if Func_name = = "Get": import tornado.web args = Inspect.getargvalues (frame) if ' self ' in arg S.locals:ifIsinstance (args.locals[' self ", tornado.web.RequestHandler): GetMethod = args.locals[' self '].get Code = getmethod.__func__.__code__ getmethod.__func__.__code__ = wearedcode (code) returnsys.set Trace (Trace)





# #环境


1. Ubuntu 14.04 64bit LTS
2. Python 2.7.6


# #步骤


1. Install the three items needed on the machine
2. Python server.py
4. Execute ' nc-l 4444 ' in ' 192.168.1.1 '
3. Pyrasite $ (PS aux |grep server.py |grep-v grep|awk ' {print $} ') testinject.py
4. Perform Curl http://localhost:8000 two times and replace "bytecode" on second request to take effect


# #结果


After performing the above steps, after performing the second Curl http://127.0.0.1:8000, you should be able to see the console input injected, and nc-l 4444 listening terminal will appear "(PDB) >" Words, so that the positive Debugging in a running program.


# #原理


' **pyasite** ' can inject code into the running Python process, which takes advantage of Python's ' pyrun_simplestring ' API to insert code, as the process injection should use ' ptrace '
' Byteplay ' is a tool that can maintain Python bytecode, which is similar to Cglib/asm


' **pyasite** ' can only inject code into the process and run, cannot navigate to a specific function and inject bytecode, and in ' testinject.py ' combines byteplay to complete function positioning and replacing the function of the GET function bytecode.


function is used to locate the Sys.settrace API, he provides the following events, at the right time to invoke the user-provided functions, specifically can refer to https://docs.python.org/2/library/sys.html#sys.settrace explanation


In theory, arbitrary bytecode can be inserted anywhere in the program, enabling arbitrary modifications to the code in the existing process.



Inject any bytecode into a running Python process

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.