""" A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA Copyright (c) 1990-2025 Hex-Rays ALL RIGHTS RESERVED. """ from __future__ import print_function import re import ida_idaapi import ida_expr import ida_kernwin import ida_dbg # ----------------------------------------------------------------------- def WinDbg_command(cmd): ok, s = ida_dbg.send_dbg_command(cmd) return s if ok else False # ----------------------------------------------------------------------- def CmdDriverList(): return WinDbg_command("lm o") # ----------------------------------------------------------------------- def CmdDrvObj(drvname, flag=2): return WinDbg_command("!drvobj %s %d" % (drvname, flag)) # ----------------------------------------------------------------------- def CmdReloadForce(): return WinDbg_command(".reload /f") # ----------------------------------------------------------------------- # class to hold dispatch entry information class DispatchEntry: def __init__(self, addr, name): self.addr = addr self.name = name def __repr__(self): return "%08X: %s" % (self.addr, self.name) # ----------------------------------------------------------------------- def GetDriverDispatch(): # return a list of arrays of the form: [addr, name] ret_list = [] # build the RE for parsing output from the "lm o" command re_drv = re.compile('^[a-f0-9]+\s+[a-f0-9]+\s+(\S+)', re.I) # build the RE for parsing output from the "!drvobj DRV_NAME 2" command re_tbl = re.compile('^\[\d{2}\]\s+IRP_MJ_(\S+)\s+([0-9a-f]+)', re.I) # force reloading of module symbols if not CmdReloadForce(): print("Could not communicate with WinDbg, make sure the debugger is running!") return None # get driver list lm_out = CmdDriverList() if not lm_out: return "Failed to get driver list!" # for each line for line in lm_out.split("\n"): # parse r = re_drv.match(line) if not r: continue # extract driver name drvname = r.group(1).strip() # execute "drvobj" command tbl_out = CmdDrvObj(drvname) if not tbl_out: print("Failed to get driver object for", drvname) continue # for each line for line in tbl_out.split("\n"): # parse r = re_tbl.match(line) if not r: continue disp_addr = int(r.group(2), 16) # convert hex string to number disp_name = "Dispatch" + r.group(1) ret_list.append(DispatchEntry(disp_addr, drvname + "_" + disp_name)) return ret_list # ----------------------------------------------------------------------- # Chooser class class DispatchChoose(ida_kernwin.Choose): def __init__(self, title, items): ida_kernwin.Choose.__init__( self, title, [["Address", 30]], width=250) self.items = items def OnGetSize(self): return len(self.items) def OnGetLine(self, n): return [str(self.items[n])] def OnSelectLine(self, n): ida_kernwin.jumpto(self.items[n].addr) # ----------------------------------------------------------------------- # main r = GetDriverDispatch() if r: c = DispatchChoose("Dispatch table browser", r) c.Show(True) else: print("Failed to retrieve dispatchers list!")