mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
196 lines
7.4 KiB
Python
196 lines
7.4 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
|
|
#
|
|
|
|
import sys, threading, unittest, socket, time
|
|
|
|
sys.path.append("..")
|
|
from qiling import Qiling
|
|
from qiling.const import QL_VERBOSE
|
|
|
|
class SimpleGdbClient:
|
|
DELAY = 0.6
|
|
|
|
def __init__(self, host: str, port: int):
|
|
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
|
txtf = sock.makefile('w')
|
|
|
|
sock.connect((host, port))
|
|
|
|
self.__sock = sock
|
|
self.__file = txtf
|
|
|
|
def __enter__(self):
|
|
return self
|
|
|
|
def __exit__(self, ex_type, ex_value, ex_traceback):
|
|
self.__sock.close()
|
|
|
|
@staticmethod
|
|
def checksum(data: str) -> int:
|
|
return sum(ord(c) for c in data) & 0xff
|
|
|
|
def send(self, msg: str):
|
|
time.sleep(SimpleGdbClient.DELAY)
|
|
|
|
self.__file.write(f'${msg}#{SimpleGdbClient.checksum(msg):02x}')
|
|
self.__file.flush()
|
|
|
|
class DebuggerTest(unittest.TestCase):
|
|
|
|
def test_gdbdebug_file_server(self):
|
|
ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_hello"], "../examples/rootfs/x8664_linux", verbose=QL_VERBOSE.DEBUG)
|
|
ql.debugger = True
|
|
|
|
# some random command test just to make sure we covered most of the command
|
|
def gdb_test_client():
|
|
# yield to allow ql to launch its gdbserver
|
|
time.sleep(1.337 * 2)
|
|
|
|
with SimpleGdbClient('127.0.0.1', 9999) as client:
|
|
client.send('qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386')
|
|
client.send('vMustReplyEmpty')
|
|
client.send('QStartNoAckMode')
|
|
client.send('Hgp0.0')
|
|
client.send('qXfer:auxv:read::0, 1000')
|
|
client.send('?')
|
|
client.send('qXfer:threads:read::0,fff')
|
|
client.send(f'qAttached:{ql.os.pid}')
|
|
client.send('qC')
|
|
client.send('g')
|
|
client.send('m555555554040, 1f8')
|
|
client.send('m555555554000, 100')
|
|
client.send('m200, 100')
|
|
client.send('p10')
|
|
client.send('Z0,555555554ada, 1')
|
|
client.send('c')
|
|
client.send('k')
|
|
|
|
# yield to make sure ql gdbserver has enough time to receive our last command
|
|
time.sleep(1.337)
|
|
|
|
threading.Thread(target=gdb_test_client, daemon=True).start()
|
|
|
|
ql.run()
|
|
del ql
|
|
|
|
def test_gdbdebug_mips32(self):
|
|
ql = Qiling(["../examples/rootfs/mips32_linux/bin/mips32_hello"], "../examples/rootfs/mips32_linux", verbose=QL_VERBOSE.DEBUG)
|
|
ql.debugger = True
|
|
|
|
# some random command test just to make sure we covered most of the command
|
|
def gdb_test_client():
|
|
# yield to allow ql to launch its gdbserver
|
|
time.sleep(1.337 * 2)
|
|
|
|
with SimpleGdbClient('127.0.0.1', 9999) as client:
|
|
client.send('qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386')
|
|
client.send('vMustReplyEmpty')
|
|
client.send('QStartNoAckMode')
|
|
client.send('Hgp0.0')
|
|
client.send('qXfer:auxv:read::0, 1000')
|
|
client.send('?')
|
|
client.send('qXfer:threads:read::0,fff')
|
|
client.send(f'qAttached:{ql.os.pid}')
|
|
client.send('qC')
|
|
client.send('g')
|
|
client.send('m47ccd10,4')
|
|
client.send('qXfer:threads:read::0,1000')
|
|
client.send('m56555620,4')
|
|
client.send('m5655561c,4')
|
|
client.send('m56555620,4')
|
|
client.send('m5655561c,4')
|
|
client.send('m56555620,4')
|
|
client.send('qTStatus')
|
|
client.send('qTfP')
|
|
client.send('m56555600,40')
|
|
client.send('m56555620,4')
|
|
client.send('Z0,47ccd10,4')
|
|
client.send('QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;97;')
|
|
client.send('vCont?')
|
|
client.send('vCont;c:pa410.-1')
|
|
client.send('c')
|
|
client.send('k')
|
|
|
|
# yield to make sure ql gdbserver has enough time to receive our last command
|
|
time.sleep(1.337)
|
|
|
|
threading.Thread(target=gdb_test_client, daemon=True).start()
|
|
|
|
ql.run()
|
|
del ql
|
|
|
|
def test_gdbdebug_armeb(self):
|
|
ql = Qiling(["../examples/rootfs/armeb_linux/bin/armeb_hello"], "../examples/rootfs/armeb_linux", verbose=QL_VERBOSE.DEBUG)
|
|
ql.debugger = True
|
|
|
|
# some random command test just to make sure we covered most of the command
|
|
def gdb_test_client():
|
|
# yield to allow ql to launch its gdbserver
|
|
time.sleep(1.337 * 2)
|
|
|
|
with SimpleGdbClient('127.0.0.1', 9999) as client:
|
|
client.send('qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386')
|
|
client.send('vMustReplyEmpty')
|
|
client.send('QStartNoAckMode')
|
|
client.send('Hgp0.0')
|
|
client.send('qXfer:auxv:read::0, 1000')
|
|
client.send('?')
|
|
client.send('qXfer:threads:read::0,fff')
|
|
client.send(f'qAttached:{ql.os.pid}')
|
|
client.send('qC')
|
|
client.send('g')
|
|
client.send('m47ccd10,4')
|
|
client.send('qXfer:threads:read::0,1000')
|
|
client.send('z0,47ca5fc,4')
|
|
client.send('m0,4')
|
|
client.send('mfffffffc,4')
|
|
client.send('m0,4')
|
|
client.send('mfffffffc,4')
|
|
client.send('m0,4')
|
|
client.send('p1d')
|
|
client.send('qTStatus')
|
|
client.send('c')
|
|
client.send('k')
|
|
|
|
# yield to make sure ql gdbserver has enough time to receive our last command
|
|
time.sleep(1.337)
|
|
|
|
threading.Thread(target=gdb_test_client, daemon=True).start()
|
|
|
|
ql.run()
|
|
del ql
|
|
|
|
def test_gdbdebug_shellcode_server(self):
|
|
X8664_LIN = bytes.fromhex('31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05')
|
|
|
|
ql = Qiling(code=X8664_LIN, archtype='x8664', ostype='linux')
|
|
ql.debugger = 'gdb:127.0.0.1:9998'
|
|
|
|
def gdb_test_client():
|
|
# yield to allow ql to launch its gdbserver
|
|
time.sleep(1.337 * 2)
|
|
|
|
with SimpleGdbClient('127.0.0.1', 9998) as client:
|
|
client.send('qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386')
|
|
client.send('vMustReplyEmpty')
|
|
client.send('QStartNoAckMode')
|
|
client.send('Hgp0.0')
|
|
client.send('?')
|
|
client.send('qC')
|
|
client.send('g')
|
|
client.send('p10')
|
|
client.send('c')
|
|
client.send('k')
|
|
|
|
# yield to make sure ql gdbserver has enough time to receive our last command
|
|
time.sleep(1.337)
|
|
|
|
threading.Thread(target=gdb_test_client, daemon=True).start()
|
|
|
|
ql.run()
|
|
del ql
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main() |