3 REPL Client
snare edited this page 2016-04-29 21:51:20 +10:00

The REPL client provides a way to interrogate Voltron from within a Python REPL.

First, start your debugger and load Voltron:

$ lldb tests/inferior
Voltron loaded.
(lldb) target create "/tmp/inferior"
Current executable set to '/tmp/inferior' (x86_64).
(lldb) b main
Breakpoint 1: where = inferior`main, address = 0x0000000100000d20
(lldb) run
Process 29539 launched: '/tmp/inferior' (x86_64)
Process 29539 stopped
* thread #1: tid = 0x2bf0b0, 0x0000000100000d20 inferior`main, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000d20 inferior`main
inferior`main:
->  0x100000d20 <+0>: push   rbp
    0x100000d21 <+1>: mov    rbp, rsp
    0x100000d24 <+4>: sub    rsp, 0x50
    0x100000d28 <+8>: mov    dword ptr [rbp - 0x4], 0x0

Now start a Python REPL in another terminal and import the REPL client:

$ python
Python 2.7.10 (default, Oct 23 2015, 18:05:06)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from voltron.repl import V

We can now use V (an instance of the REPLClient class) to interrogate the Voltron back end:

>>> V
<voltron.repl.REPLClient object at 0x106771dd0>

Registers can be retrieved by treating them as attributes:

>>> V.rip
4294970656
>>> V.rsp
140734799804552

Memory can be retrieved by using the index operators. For example, reading a byte at the value of the RSP register:

>>> V[V.rsp]
'\xad'

Or reading a range of bytes:

>>> V[V.rsp:V.rsp+8]
'\xad\x95*\x8c\xff\x7f\x00\x00'

Debugger commands can be executed using the call syntax:

>>> V("version")
u'lldb-350.0.21.3'
>>> print V("reg read")
General Purpose Registers:
       rax = 0x0000000100000d20  inferior`main
       rbx = 0x0000000000000000
       rcx = 0x00007fff5fbff990
       rdx = 0x00007fff5fbff890
       rdi = 0x0000000000000001
       rsi = 0x00007fff5fbff880
       rbp = 0x00007fff5fbff870
       rsp = 0x00007fff5fbff868
        r8 = 0x0000000000000000
        r9 = 0x00007fff7164b0c8  atexit_mutex + 24
       r10 = 0x00000000ffffffff
       r11 = 0xffffffff00000000
       r12 = 0x0000000000000000
       r13 = 0x0000000000000000
       r14 = 0x0000000000000000
       r15 = 0x0000000000000000
       rip = 0x0000000100000d20  inferior`main
    rflags = 0x0000000000000246
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000

Other Voltron API requests can be performed using the Client class's perform_request method:

>>> V.perform_request('targets')
<<class 'targets.APITargetsResponse'>: success = True, error = False, body: {'status': u'success', 'type': u'response', 'targets': [{u'byte_order': u'little', u'addr_size': 8, u'state': u'stopped', u'file': u'/tmp/inferior', u'arch': u'x86_64', u'id': 0}]}>