Created
June 5, 2018 13:48
-
-
Save Wenzel/efd9d6f4a0e0577e4ce7afe5d3ddf400 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Usage: | |
bug_sstep.py [options] <vm_name> <symbol> | |
Options: | |
-h --help Show this screen. | |
--sstep Use singlestepping instead of emulation | |
""" | |
import sys | |
import signal | |
from pprint import pprint | |
from docopt import docopt | |
from libvmi import Libvmi, INIT_DOMAINNAME, INIT_EVENTS | |
from libvmi.event import MemEvent, MemAccess, SingleStepEvent, EventResponse | |
from utils import dtb_to_pname, pause | |
# catch SIGINT | |
# we cannot rely on KeyboardInterrupt when we are in | |
# the vmi.listen() call | |
interrupted = False | |
def signal_handler(signal, frame): | |
global interrupted | |
interrupted = True | |
def cb_mem_event(vmi, event): | |
# pprint(event.to_dict()) | |
if event.cffi_event.x86_regs.rip != event.data['target_vaddr']: | |
# page hit, but we are not at the right address | |
if event.data['sstep']: | |
# lift page permissions | |
print("lift page permissions") | |
vmi.clear_event(event.data['mem_event']) | |
# toogle singlestep ON | |
return EventResponse.TOGGLE_SINGLESTEP | |
else: | |
# emulate this instruction and continue | |
return EventResponse.EMULATE | |
else: | |
# hit | |
pname = dtb_to_pname(vmi, event.cffi_event.x86_regs.cr3) | |
print('At {}: {}'.format(event.data['symbol'], pname)) | |
vmi.pause_vm() | |
event.data['interrupted'] = True | |
return EventResponse.EMULATE | |
def cb_ss_event(vmi, event): | |
# out of the frame ? | |
if event.cffi_event.ss_event.gfn != event.data['target_gfn']: | |
print("reregister event") | |
# reregister mem event | |
vmi.register_event(event.data['mem_event']) | |
# toggle singlestep OFF | |
return EventResponse.TOGGLE_SINGLESTEP | |
def cb_ss_event_userland(vmi, event): | |
print("cb_ss_event_test, rip: {}".format( | |
hex(event.cffi_event.x86_regs.rip) | |
)) | |
def main(args): | |
vm_name = args['<vm_name>'] | |
symbol = args['<symbol>'] | |
sstep_enabled = args['--sstep'] | |
# register SIGINT | |
signal.signal(signal.SIGINT, signal_handler) | |
with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS) as vmi: | |
vaddr = vmi.translate_ksym2v(symbol) | |
paddr = vmi.translate_kv2p(vaddr) | |
frame = paddr >> 12 | |
print("symbol: {} vaddr: {} paddr: {} frame: {}".format( | |
symbol, hex(vaddr), hex(paddr), hex(frame))) | |
user_data = { | |
'symbol': symbol, | |
'target_vaddr': vaddr, | |
'target_gfn': frame, | |
'mem_event': None, | |
'sstep': sstep_enabled, | |
'interrupted': False | |
} | |
num_vcpus = vmi.get_num_vcpus() | |
ss_event = SingleStepEvent(range(num_vcpus), cb_ss_event, data=user_data, enable=False) | |
mem_event = MemEvent(MemAccess.X, cb_mem_event, gfn=frame, data=user_data) | |
user_data['mem_event'] = mem_event | |
with pause(vmi): | |
vmi.register_event(ss_event) | |
vmi.register_event(mem_event) | |
# listen | |
while not user_data['interrupted']: | |
print("Waiting for events ({} events pending)".format(vmi.are_events_pending())) | |
vmi.listen(1000) | |
print("Stop listening") | |
# clear buffer | |
vmi.listen(0) | |
# clear events | |
vmi.clear_event(mem_event) | |
vmi.clear_event(ss_event) | |
print("single stepping until userland...") | |
# create a new ss_event | |
ss_event = SingleStepEvent(range(num_vcpus), cb_ss_event_userland, | |
data=user_data) | |
vmi.register_event(ss_event) | |
vmi.resume_vm() | |
interrupted = False | |
while not interrupted: | |
print("Waiting for events ({} events pending)".format(vmi.are_events_pending())) | |
vmi.listen(1000) | |
if __name__ == '__main__': | |
args = docopt(__doc__) | |
ret = main(args) | |
sys.exit(ret) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
sudo ./venv/bin/python examples/bug_sstep.py xenwin7 KiStartUserThread --sstep