1212DriverBuddyReloaded.py: Entry point for IDA python plugin used in Windows driver vulnerability research.
1313Updated in 2021 by Paolo Stagno aka VoidSec: https://voidsec.com - https://twitter.com/Void_Sec
1414"""
15+ # needed GLOBALs
16+ driver_name = idaapi .get_root_filename ()
17+ path = "{}{}" .format (os .getcwd (), os .sep )
18+ ioctl_file_name = "{}-{}-{}-IOCTLs.txt" .format (driver_name , utils .today (), utils .timestamp ())
19+ analysis_file_name = "{}-{}-{}-DriverBuddyReloaded_autoanalysis.txt" .format (driver_name , utils .today (),
20+ utils .timestamp ())
21+ pool_file_name = "{}-{}-{}-pooltags.txt" .format (driver_name , utils .today (), utils .timestamp ())
1522
1623
1724class UiAction (idaapi .action_handler_t ):
@@ -147,8 +154,6 @@ def print_table(self, ioctls):
147154 :param ioctls: IOCTL to decode
148155 :return:
149156 """
150- driver_name = idaapi .get_root_filename ()
151- ioctl_file_name = "{}-{}-IOCTLs.txt" .format (driver_name , utils .today ())
152157 try :
153158 with open (ioctl_file_name , "w" ) as IOCTL_file :
154159 print ("\n Driver Buddy Reloaded - IOCTLs\n "
@@ -169,9 +174,10 @@ def print_table(self, ioctls):
169174 access_code )
170175 print ("0x%-8X | 0x%-8X | %-31s 0x%-8X | 0x%-8X | %-17s %-4d | %s (%d)" % all_vars )
171176 IOCTL_file .write ("0x%-8X | 0x%-8X | %-31s 0x%-8X | 0x%-8X | %-17s %-4d | %s (%d)\n " % all_vars )
172- print ("\n [>] Saved decoded IOCTLs to \" {}{}{} \" " .format (os . getcwd (), os . sep , ioctl_file_name ))
177+ print ("\n [>] Saved decoded IOCTLs to \" {}{}\" " .format (path , ioctl_file_name ))
173178 except IOError as e :
174- print ("ERROR #{}: Can't write to {}; {}" .format (e .errno , ioctl_file_name , e .strerror ))
179+ print ("ERROR #{}: {}\n Can't save decoded IOCTLs to \" {}{}\" " .format (e .errno , e .strerror , path ,
180+ ioctl_file_name ))
175181 print ("\n Driver Buddy Reloaded - IOCTLs\n "
176182 "-----------------------------------------------" )
177183 print ("%-10s | %-10s | %-42s | %-10s | %-22s | %s" % (
@@ -195,7 +201,7 @@ def find_all_ioctls():
195201 """
196202
197203 ioctls = []
198- # Find the currently selected function and get a list of all of it's basic blocks
204+ # Find the currently selected function and get a list of all of its basic blocks
199205 addr = idc .get_screen_ea ()
200206 f = idaapi .get_func (addr )
201207 fc = idaapi .FlowChart (f , flags = idaapi .FC_PREDS )
@@ -422,33 +428,64 @@ def run(self, args):
422428 :param args:
423429 :return:
424430 """
425- print ("\n Driver Buddy Reloaded Auto-analysis\n "
426- "-----------------------------------------------" )
427- idc .auto_wait () # Wait for IDA analysis to complete
428- file_type = idaapi .get_file_type_name ()
429- if "portable executable" not in file_type .lower ():
430- print ("[!] ERR: Loaded file is not a valid PE" )
431- else :
432- driver_entry_addr = utils .is_driver ()
433- if driver_entry_addr is False :
434- print ("[!] ERR: Loaded file is not a Driver" )
435- else :
436- print ("[+] `DriverEntry` found at: 0x{addr:08x}" .format (addr = driver_entry_addr ))
437- print ("[>] Searching for `DeviceNames`..." )
438- device_name_finder .search ()
439- print ("[>] Searching for `Pooltags`... " )
440- pool = dump_pool_tags .get_all_pooltags ()
441- if pool :
442- print (pool )
443- if utils .populate_data_structures () is True :
444- driver_type = utils .get_driver_id (driver_entry_addr )
445- print (("[+] Driver type detected: {}" .format (driver_type )))
446- if ioctl_decoder .find_ioctls_dumb () is False :
447- print ("[!] Unable to automatically find any IOCTLs" )
431+ try :
432+ with open (analysis_file_name , "w" ) as log_file :
433+ print ("\n Driver Buddy Reloaded Auto-analysis\n "
434+ "-----------------------------------------------" )
435+ log_file .write ("\n Driver Buddy Reloaded Auto-analysis\n "
436+ "-----------------------------------------------\n " )
437+ idc .auto_wait () # Wait for IDA analysis to complete
438+ file_type = idaapi .get_file_type_name ()
439+ if "portable executable" not in file_type .lower ():
440+ print ("[!] ERR: Loaded file is not a valid PE" )
441+ log_file .write ("[!] ERR: Loaded file is not a valid PE\n " )
448442 else :
449- print ("[!] ERR: Unable to enumerate functions" )
450- print ("[+] Analysis Completed!\n "
451- "-----------------------------------------------" )
443+ driver_entry_addr = utils .is_driver ()
444+ if driver_entry_addr is False :
445+ print ("[!] ERR: Loaded file is not a Driver" )
446+ log_file .write ("[!] ERR: Loaded file is not a Driver\n " )
447+ else :
448+ print ("[+] `DriverEntry` found at: 0x{addr:08x}" .format (addr = driver_entry_addr ))
449+ log_file .write ("[+] `DriverEntry` found at: 0x{addr:08x}\n " .format (addr = driver_entry_addr ))
450+ print ("[>] Searching for `DeviceNames`..." )
451+ log_file .write ("[>] Searching for `DeviceNames`...\n " )
452+ device_name_finder .search (log_file )
453+ print ("[>] Searching for `Pooltags`..." )
454+ log_file .write ("[>] Searching for `Pooltags`...\n " )
455+ pool = dump_pool_tags .get_all_pooltags ()
456+ if pool :
457+ print (pool )
458+ try :
459+ with open (pool_file_name , "w" ) as pool_file :
460+ pool_file .write (pool )
461+ except IOError as e :
462+ print (
463+ "ERROR #{}: {}\n Can't write pool file to \" {}{}\" " .format (e .errno , e .strerror , path ,
464+ pool_file_name ))
465+ if utils .populate_data_structures (log_file ) is True :
466+ driver_type = utils .get_driver_id (driver_entry_addr , log_file )
467+ print ("[+] Driver type detected: {}" .format (driver_type ))
468+ log_file .write ("[+] Driver type detected: {}\n " .format (driver_type ))
469+ if ioctl_decoder .find_ioctls_dumb (log_file , ioctl_file_name ) is False :
470+ print ("[!] Unable to automatically find any IOCTLs" )
471+ log_file .write ("[!] Unable to automatically find any IOCTLs\n " )
472+ else :
473+ print ("\n [>] Saved decoded IOCTLs log file to \" {}{}_dumb.txt\" " .format (path ,
474+ ioctl_file_name ))
475+ else :
476+ print ("[!] ERR: Unable to enumerate functions" )
477+ log_file .write ("[!] ERR: Unable to enumerate functions\n " )
478+ print ("[+] Analysis Completed!\n "
479+ "-----------------------------------------------" )
480+ log_file .write ("[+] Analysis Completed!\n "
481+ "-----------------------------------------------" )
482+ print ("\n [>] Saved Autoanalysis log file to \" {}{}\" " .format (path , analysis_file_name ))
483+ if pool :
484+ print ("[>] Saved Pooltags file to \" {}{}\" " .format (path , pool_file_name ))
485+ except IOError as e :
486+ print ("ERROR #{}: {}\n Autoanalysis aborted, can't write log file to \" {}{}\" " .format (e .errno , e .strerror ,
487+ path ,
488+ analysis_file_name ))
452489 return
453490
454491 def term (self ):
0 commit comments