You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pwndbg/pwndbg/qemu.py

99 lines
2.2 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Determine whether the target is being run under QEMU.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import os
import gdb
import psutil
import pwndbg.events
import pwndbg.remote
@pwndbg.memoize.reset_on_stop
def is_qemu():
if not pwndbg.remote.is_remote():
return False
response = gdb.execute('maintenance packet Qqemu.sstepbits',
to_string=True,
from_tty=False)
return 'ENABLE=' in response
@pwndbg.memoize.reset_on_stop
def is_usermode():
if not pwndbg.remote.is_remote():
return False
# If we had QEMU 2.4 or better, we could use
#
# maintenance packet QAttached:
#
# However, Ubuntu 14 still has QEMU 2.2, so we have to use
# a different command as a heuristic.
response = gdb.execute('maintenance packet QOffsets',
to_string=True,
from_tty=False)
return 'Text=' in response
@pwndbg.memoize.reset_on_stop
def is_qemu_usermode():
"""Returns ``True`` if the target remote is being run under
QEMU usermode emulation."""
return is_qemu() and is_usermode()
@pwndbg.events.start
@pwndbg.memoize.reset_on_stop
def root():
global root
if not is_qemu_usermode():
return
binfmt_root = '/etc/qemu-binfmt/%s/' % pwndbg.arch.qemu
if not os.path.isdir(binfmt_root):
return
gdb.execute('set sysroot ' + binfmt_root,
from_tty=False)
return binfmt_root
@pwndbg.memoize.reset_on_start
def pid():
"""Find the PID of the qemu usermode binary which we are
talking to.
"""
# Find all inodes in our process which are connections.
targets = set(c.raddr for c in psutil.Process().connections())
# No targets? :(
if not targets:
return 0
for process in psutil.process_iter():
if not process.name().startswith('qemu'):
continue
try:
connections = process.connections()
except Exception:
continue
for c in connections:
if c.laddr in targets:
return process.pid