通风后门检查 运行 代码
Gevent backdoor inspect running code
我正在使用 gevent
及其 Backdoor
功能。
这是我的代码的简化版本:
from gevent import backdoor, event
class App(object):
def __init__(self):
self.stop_event = event.Event()
self.servers = []
self.servers.append(backdoor.BackdoorServer((localhost, 6666))
# There is a tcp stream server using gevent configured too
def start(self):
for server in self.servers:
if not server.started:
server.start()
self.stop_event.wait()
for server in self.servers:
if server.started:
server.stop()
def run(*args, **kw):
app = App()
app.start()
run
方法在从我的 setup.py
中的 entry_points
创建的 console_scripts
中调用
我想用我的后门检查 run
函数中的 app
局部变量。
我连接到后门,运行命令inspect.stack()
。这就是我得到的:
[
(<frame object at 0x7fa49ea0b3a0>, '<console>', 1, '<module>', None, None),
(<frame object at 0x7fa49ce727f0>, '/usr/lib/python2.7/code.py', 103, 'runcode', [' exec code in self.locals\n'], 0),
(<frame object at 0x7fa49ce70250>, '/usr/lib/python2.7/code.py', 87, 'runsource', [' self.runcode(code)\n'], 0),
(<frame object at 0x7fa49ced7d38>, '/usr/lib/python2.7/code.py', 265, 'push', [' more = self.runsource(source, self.filename)\n'], 0),
(<frame object at 0x3569a40>, '/usr/lib/python2.7/code.py', 243, 'interact', [' more = self.push(line)\n'], 0),
(<frame object at 0x7fa49ced39b0>, 'path_to_project/venv/local/lib/python2.7/site-packages/gevent-1.0.2-py2.7-linux-x86_64.egg/gevent/backdoor.py', 75, '_run', [' console.interact(banner=self.banner)\n'], 0),
(<frame object at 0x7fa49ced3b90>, 'path_to_project/venv/local/lib/python2.7/site-packages/gevent-1.0.2-py2.7-linux-x86_64.egg/gevent/greenlet.py', 327, 'run', [' result = self._run(*self.args, **self.kwargs)\n'], 0)
]
如你所见,gevent似乎在重写堆栈。启动程序的模块中的 run
函数不在其中。它在执行后门的 greenlet 的 运行 方法处停止。
是否有任何方法可以访问启动程序的 运行ning run
方法,以便检查它并访问其本地 app
变量?
好的,我找到了解决办法。 greenlet
对象有一个 parent
属性来查找是哪一个生成了您当前正在查看的对象。然后greenlet有一个属性gr_frame
来存储stacktrace。
所以在我的例子中,一旦我连接到后门服务器,它就会是这样的:
>>> import greenlet, inspect
>>> greenlet.getcurrent()
<SocketConsole at 0x7fca7122d190>
>>> greenlet.getcurrent().parent
<Hub at 0x7fca71560050 epoll default pending=0 ref=4 fileno=3 resolver=<gevent.resolver_thread.Resolver at 0x7fca7126a510 pool=<ThreadPool at 0x7fca7127fe10 0/1/10>> threadpool=<ThreadPool at 0x7fca7127fe10 0/1/10>>
>>> greenlet.getcurrent().parent.parent
<greenlet.greenlet object at 0x7fca7d9be690>
>>> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)
[
...
(<frame object at 0x174ac40>, 'path_to_project/endpoints/app.py', 238, 'run', [' app.start()\n'], 0),
...
]
>>> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]
<frame object at 0x174ac40>
>>> inspect.getargvalues(inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]).locals
{'args': [], 'app': <endpoints.app.App object at 0x7fca71360190>, 'kw': {}}
>>> inspect.getargvalues(inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]).locals['app']
<endpoints.app.App object at 0x7fca71360190>
我现在可以访问 运行 函数 run
中的本地对象 app
以检查其其他属性的值并调试我的实时 gevent 应用程序。
我正在使用 gevent
及其 Backdoor
功能。
这是我的代码的简化版本:
from gevent import backdoor, event
class App(object):
def __init__(self):
self.stop_event = event.Event()
self.servers = []
self.servers.append(backdoor.BackdoorServer((localhost, 6666))
# There is a tcp stream server using gevent configured too
def start(self):
for server in self.servers:
if not server.started:
server.start()
self.stop_event.wait()
for server in self.servers:
if server.started:
server.stop()
def run(*args, **kw):
app = App()
app.start()
run
方法在从我的 setup.py
entry_points
创建的 console_scripts
中调用
我想用我的后门检查 run
函数中的 app
局部变量。
我连接到后门,运行命令inspect.stack()
。这就是我得到的:
[
(<frame object at 0x7fa49ea0b3a0>, '<console>', 1, '<module>', None, None),
(<frame object at 0x7fa49ce727f0>, '/usr/lib/python2.7/code.py', 103, 'runcode', [' exec code in self.locals\n'], 0),
(<frame object at 0x7fa49ce70250>, '/usr/lib/python2.7/code.py', 87, 'runsource', [' self.runcode(code)\n'], 0),
(<frame object at 0x7fa49ced7d38>, '/usr/lib/python2.7/code.py', 265, 'push', [' more = self.runsource(source, self.filename)\n'], 0),
(<frame object at 0x3569a40>, '/usr/lib/python2.7/code.py', 243, 'interact', [' more = self.push(line)\n'], 0),
(<frame object at 0x7fa49ced39b0>, 'path_to_project/venv/local/lib/python2.7/site-packages/gevent-1.0.2-py2.7-linux-x86_64.egg/gevent/backdoor.py', 75, '_run', [' console.interact(banner=self.banner)\n'], 0),
(<frame object at 0x7fa49ced3b90>, 'path_to_project/venv/local/lib/python2.7/site-packages/gevent-1.0.2-py2.7-linux-x86_64.egg/gevent/greenlet.py', 327, 'run', [' result = self._run(*self.args, **self.kwargs)\n'], 0)
]
如你所见,gevent似乎在重写堆栈。启动程序的模块中的 run
函数不在其中。它在执行后门的 greenlet 的 运行 方法处停止。
是否有任何方法可以访问启动程序的 运行ning run
方法,以便检查它并访问其本地 app
变量?
好的,我找到了解决办法。 greenlet
对象有一个 parent
属性来查找是哪一个生成了您当前正在查看的对象。然后greenlet有一个属性gr_frame
来存储stacktrace。
所以在我的例子中,一旦我连接到后门服务器,它就会是这样的:
>>> import greenlet, inspect
>>> greenlet.getcurrent()
<SocketConsole at 0x7fca7122d190>
>>> greenlet.getcurrent().parent
<Hub at 0x7fca71560050 epoll default pending=0 ref=4 fileno=3 resolver=<gevent.resolver_thread.Resolver at 0x7fca7126a510 pool=<ThreadPool at 0x7fca7127fe10 0/1/10>> threadpool=<ThreadPool at 0x7fca7127fe10 0/1/10>>
>>> greenlet.getcurrent().parent.parent
<greenlet.greenlet object at 0x7fca7d9be690>
>>> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)
[
...
(<frame object at 0x174ac40>, 'path_to_project/endpoints/app.py', 238, 'run', [' app.start()\n'], 0),
...
]
>>> inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]
<frame object at 0x174ac40>
>>> inspect.getargvalues(inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]).locals
{'args': [], 'app': <endpoints.app.App object at 0x7fca71360190>, 'kw': {}}
>>> inspect.getargvalues(inspect.getouterframes(greenlet.getcurrent().parent.parent.gr_frame)[4][0]).locals['app']
<endpoints.app.App object at 0x7fca71360190>
我现在可以访问 运行 函数 run
中的本地对象 app
以检查其其他属性的值并调试我的实时 gevent 应用程序。