成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

將任意Bytecode注入運(yùn)行中的Python進(jìn)程

endiat / 2005人閱讀

摘要:在調(diào)試程序的時(shí)候,一般我們只能通過以下幾種方式進(jìn)行調(diào)試程序中已經(jīng)有的日志在代碼中插入但是以上的方法也有不方便的地方,比如對(duì)于已經(jīng)在運(yùn)行中的程序,就不可能停止程序后加入調(diào)試代碼和增加新的日志從的項(xiàng)目得到靈感,嘗試對(duì)正在運(yùn)行的進(jìn)程插入代碼,在程

在調(diào)試 Python 程序的時(shí)候,一般我們只能通過以下幾種方式進(jìn)行調(diào)試:

程序中已經(jīng)有的日志

在代碼中插入 import pdb; pdb.set_trace()

但是以上的方法也有不方便的地方, 比如對(duì)于已經(jīng)在運(yùn)行中的程序, 就不可能停止程序后加入 調(diào)試代碼和增加新的日志.

從 JAVA 的 BTrace(https://kenai.com/projects/btrace) 項(xiàng)目得到靈感,嘗試對(duì)正在運(yùn)行的 Python 進(jìn)程插入代碼,在程序運(yùn)行到指定的函數(shù)后,自動(dòng)連接遠(yuǎn)程主機(jī)進(jìn)行調(diào)試

首先介紹三個(gè)開源的項(xiàng)目, 本實(shí)驗(yàn)需要用到這三個(gè)項(xiàng)目

Pyasite https://github.com/lmacken/pyrasite Tools for injecting code into running Python processes

Byteplay https://github.com/serprex/byteplay 一個(gè)字節(jié)碼維護(hù)項(xiàng)目,類似 java的asm/cglib

Rpdb-Shell https://github.com/alex8224/Rpdb-Shell

待注入的代碼, 用官方的 tornado hello demo 做例子

import tornado.ioloop
import tornado.web
import os

class 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()

注入以下代碼(testinject.py)到 get

import sys
import dis
import inspect
from 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_FAST, "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, "192.168.1.1"), (CALL_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":
        return

    if func_name == "get":
        import tornado.web
        args = inspect.getargvalues(frame)
        if "self" in args.locals:
            if isinstance(args.locals["self"], tornado.web.RequestHandler):
                getmethod = args.locals["self"].get
                code = getmethod.__func__.__code__
                getmethod.__func__.__code__ = wearedcode(code)
        return

sys.settrace(trace)
環(huán)境

ubuntu 14.04 64bit LTS

Python 2.7.6

步驟

在機(jī)器上安裝上面需要用到的三個(gè)項(xiàng)目

python server.py

192.168.1.1 執(zhí)行 nc -l 4444

pyrasite $(ps aux |grep server.py |grep -v grep|awk "{print $2}") testinject.py

執(zhí)行 curl http://localhost:8000 兩次, 在第二次請(qǐng)求時(shí)替換的 bytecode 才會(huì)生效

結(jié)果

在執(zhí)行上面的步驟后, 在執(zhí)行第二次 curl http://127.0.0.1:8000 后, 應(yīng)該能夠看到控制臺(tái)輸入 injected 的字樣,并且 nc -l 4444 監(jiān)聽的終端會(huì)出現(xiàn) (pdb)> 的字樣, 這樣就能夠?qū)φ谶\(yùn)行中的程序進(jìn)行調(diào)試了.

原理

Pyasite 可以注入代碼到運(yùn)行中的 Python 進(jìn)程,它利用了 Python 的 PyRun_SimpleString 這個(gè)API插入代碼, 至于進(jìn)程注入應(yīng)該是使用了 ptrace
Byteplay 是一個(gè)可以維護(hù) Python bytecode的工具, 這部分跟 cglib/asm類似

Pyasite 只能把代碼注入到進(jìn)程中并運(yùn)行,不能定位到具體的函數(shù)并注入 bytecode, 在 testinject.py 中結(jié)合 Byteplay 完成了函數(shù)定位和替換 get 函數(shù)字節(jié)碼的功能.

函數(shù)的定位用到了 sys.settrace 這個(gè)API,他提供了 call, line, return, exception事件,在合適的時(shí)機(jī)調(diào)用用戶提供的函數(shù), 具體可以參考 https://docs.python.org/2/library/sys.html#sys.settrace 的解釋

理論上可以插入任意字節(jié)碼到程序中的任意位置, 實(shí)現(xiàn)對(duì)現(xiàn)有進(jìn)程中代碼的任意修改.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37537.html

相關(guān)文章

  • 淺談Python多線程

    摘要:進(jìn)程可創(chuàng)建多個(gè)線程來執(zhí)行同一程序的不同部分。就緒等待線程調(diào)度。運(yùn)行線程正常運(yùn)行阻塞暫停運(yùn)行,解除阻塞后進(jìn)入狀態(tài)重新等待調(diào)度。消亡線程方法執(zhí)行完畢返回或者異常終止。多線程多的情況下,依次執(zhí)行各線程的方法,前頭一個(gè)結(jié)束了才能執(zhí)行后面一個(gè)。 淺談Python多線程 作者簡(jiǎn)介: 姓名:黃志成(小黃)博客: 博客 線程 一.什么是線程? 操作系統(tǒng)原理相關(guān)的書,基本都會(huì)提到一句很經(jīng)典的話: 進(jìn)程...

    zsirfs 評(píng)論0 收藏0
  • 如何編寫快速且線程安全的Python代碼

    摘要:其次,解釋器的主循環(huán),一個(gè)名為的函數(shù),讀取字節(jié)碼并逐個(gè)執(zhí)行其中的指令。所有線程都運(yùn)行相同的代碼,并以相同的方式定期從它們獲取鎖定。無論如何,其他線程無法并行運(yùn)行。 概述 如今我也是使用Python寫代碼好多年了,但是我卻很少關(guān)心GIL的內(nèi)部機(jī)制,導(dǎo)致在寫Python多線程程序的時(shí)候。今天我們就來看看CPython的源代碼,探索一下GIL的源碼,了解為什么Python里要存在這個(gè)GIL,...

    B0B0 評(píng)論0 收藏0
  • 一個(gè) Reentrant Error 引發(fā)的對(duì) Python 信號(hào)機(jī)制的探索和思考

    摘要:倘若該回答是正確的,則立即有如下推論在處理信號(hào)的過程中,字節(jié)碼具有原子性。因此,除了在兩個(gè)字節(jié)碼之間,應(yīng)該還有其他時(shí)機(jī)喚起了。行的是信號(hào)處理函數(shù)的最外層包裝,由系統(tǒng)調(diào)用或注冊(cè)至內(nèi)核,并在信號(hào)發(fā)生時(shí)被內(nèi)核回調(diào),是異??刂屏鞯娜肟凇? 寫在前面 前幾天工作時(shí)遇到了一個(gè)匪夷所思的問題。經(jīng)過幾次嘗試后問題得以解決,但問題產(chǎn)生的原因卻仍令人費(fèi)解。查找 SO 無果,我決定翻看 Python 的源碼。...

    shiguibiao 評(píng)論0 收藏0
  • 高嚴(yán)重代碼注入漏洞影響Yamale Python包 超過200個(gè)項(xiàng)目使用

    摘要:軟件包存儲(chǔ)庫正成為供應(yīng)鏈攻擊的熱門目標(biāo),和等流行存儲(chǔ)庫已經(jīng)受到惡意軟件攻擊,研究人員稱。當(dāng)應(yīng)用程序中的第三代碼方庫不能保持在最新狀態(tài)時(shí),對(duì)企業(yè)來說后果可能很嚴(yán)重。 .markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}...

    PascalXie 評(píng)論0 收藏0
  • JavaScript深入淺出第4課:V8引擎是如何工作的?

    摘要:摘要性能彪悍的引擎。深入淺出系列深入淺出第課箭頭函數(shù)中的究竟是什么鬼深入淺出第課函數(shù)是一等公民是什么意思呢深入淺出第課什么是垃圾回收算法深入淺出第課是如何工作的最近,生態(tài)系統(tǒng)又多了個(gè)非常硬核的項(xiàng)目。 摘要: 性能彪悍的V8引擎。 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? JavaScript深入淺出第2課:函數(shù)是一...

    hsluoyz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<