Skip to content

Instantly share code, notes, and snippets.

@herrcore
Created August 14, 2016 02:53
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save herrcore/b3143dde185cecda7c1dee7ffbce5d2c to your computer and use it in GitHub Desktop.
Save herrcore/b3143dde185cecda7c1dee7ffbce5d2c to your computer and use it in GitHub Desktop.
IDA Python plugin - Decode IOCTL Codes
############################################################################################
##
## Quick IOCTL Decoder!
##
## All credit for actual IOCTL decode logic:
## http://www.osronline.com/article.cfm?article=229
##
##
## To install:
## Copy script into plugins directory, i.e: C:\Program Files\IDA 6.8\plugins
##
## To run:
## Highlight IOCTL then right click and select "Decode IOCTL" or press PLUGIN_HOTKEY
## The decoded IOCTL data will be added as a comment and displayed in the IDA cli
##
############################################################################################
__VERSION__ = '0.1'
__AUTHOR__ = '@herrcore'
PLUGIN_NAME = "Quick IOCTL Decoder"
PLUGIN_HOTKEY = 'Ctrl-Alt-I'
import idaapi
class IOCTL_Decoder():
DEVICE = [None]*55
DEVICE[1]="BEEP"
DEVICE[2]="CD_ROM"
DEVICE[3]="CD_ROM_FILE_SYSTEM"
DEVICE[4]="CONTROLLER"
DEVICE[5]="DATALINK"
DEVICE[6]="DFS"
DEVICE[7]="DISK"
DEVICE[8]="DISK_FILE_SYSTEM"
DEVICE[9]="FILE_SYSTEM"
DEVICE[10]="INPORT_PORT"
DEVICE[11]="KEYBOARD"
DEVICE[12]="MAILSLOT"
DEVICE[13]="MIDI_IN"
DEVICE[14]="MIDI_OUT"
DEVICE[15]="MOUSE"
DEVICE[16]="MULTI_UNC_PROVIDER"
DEVICE[17]="NAMED_PIPE"
DEVICE[18]="NETWORK"
DEVICE[19]="NETWORK_BROWSER"
DEVICE[20]="NETWORK_FILE_SYSTEM"
DEVICE[21]="NULL"
DEVICE[22]="PARALLEL_PORT"
DEVICE[23]="PHYSICAL_NETCARD"
DEVICE[24]="PRINTER"
DEVICE[25]="SCANNER"
DEVICE[26]="SERIAL_MOUSE_PORT"
DEVICE[27]="SERIAL_PORT"
DEVICE[28]="SCREEN"
DEVICE[29]="SOUND"
DEVICE[30]="STREAMS"
DEVICE[31]="TAPE"
DEVICE[32]="TAPE_FILE_SYSTEM"
DEVICE[33]="TRANSPORT"
DEVICE[34]="UNKNOWN"
DEVICE[35]="VIDEO"
DEVICE[36]="VIRTUAL_DISK"
DEVICE[37]="WAVE_IN"
DEVICE[38]="WAVE_OUT"
DEVICE[39]="8042_PORT"
DEVICE[40]="NETWORK_REDIRECTOR"
DEVICE[41]="BATTERY"
DEVICE[42]="BUS_EXTENDER"
DEVICE[43]="MODEM"
DEVICE[44]="VDM"
DEVICE[45]="MASS_STORAGE"
DEVICE[46]="SMB"
DEVICE[47]="KS"
DEVICE[48]="CHANGER"
DEVICE[49]="SMARTCARD"
DEVICE[50]="ACPI"
DEVICE[51]="DVD"
DEVICE[52]="FULLSCREEN_VIDEO"
DEVICE[53]="DFS_FILE_SYSTEM"
DEVICE[54]="DFS_VOLUME"
def __init__(self, control_code):
self.control_code = control_code
def decode(self):
out={}
device_val = (self.control_code >> 16) & 0xFFF
funcVal = (self.control_code >> 2) & 0xFFF
if (device_val <= 54) and (device_val != 0):
device_string = self.DEVICE[device_val]+ " ("+hex(device_val)+")"
else:
device_string = hex(device_val)
function_string = hex(funcVal)
out["device"] = device_string
out["function"] = function_string
access = (self.control_code >> 14) & 3
method = self.control_code & 3
access_string = ""
if access == 0:
access_string = "FILE_ANY_ACCESS"
elif access == 1:
access_string = "FILE_READ_ACCESS"
elif access == 2:
access_string = "FILE_WRITE_ACCESS"
elif access == 3:
access_string = "Read and Write"
method_string = ""
if method == 0:
method_string = "METHOD_BUFFERED"
elif method == 1:
method_string = "METHOD_IN_DIRECT"
elif method == 2:
method_string = "METHOD_OUT_DIRECT"
elif method == 3:
method_string = "METHOD_NEITHER"
out["access"] = access_string
out["method"] = method_string
return out
class IDAIOCTLDecoder():
@staticmethod
def decode():
ea = ScreenEA()
if ea == idaapi.BADADDR:
idaapi.msg(PLUGIN_NAME + " ERROR: Could not get get_screen_ea()")
return
str_id = idaapi.get_highlighted_identifier()
if not str_id:
idaapi.msg(PLUGIN_NAME + " ERROR: No Ioctl Code highlighted!")
return
try:
if str_id[-1] == 'h':
code = int(str_id[:-1], 16)
elif str_id[-1] == 'o':
code = int(str_id[:-1], 8)
elif str_id[-1] == 'b':
code = int(str_id[:-1], 2)
else:
code = int(str_id)
except ValueError:
idaapi.msg(PLUGIN_NAME + " ERROR: Not a valid Ioctl Code: " + str(str_id))
return
try:
decoder = IOCTL_Decoder(code)
ioctl_data = decoder.decode()
#print decoded IOCTL to cli
msg_string = "That IOCTL decodes to: \n\tDevice: %s \n\tFunction: %s \n\tAccess: %s \n\tMethod: %s"
idaapi.msg(msg_string % (ioctl_data["device"], ioctl_data["function"], ioctl_data["access"], ioctl_data["method"]))
#add decoded IOCTL as comment
comment_string = "dwIoControlCode: \n\t\tDevice: %s \n\t\tFunction: %s \n\t\tAccess: %s \n\t\tMethod: %s"
idaapi.set_cmt(ea, comment_string % (ioctl_data["device"], ioctl_data["function"], ioctl_data["access"], ioctl_data["method"]), 0)
except Exception as e:
idaapi.msg(PLUGIN_NAME + " ERROR: " + str(e))
return
class IOCTLDecodeHandler(idaapi.action_handler_t):
def activate(self, ctx):
IDAIOCTLDecoder.decode()
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
class QuickIOCTLDecoderHooks(idaapi.UI_Hooks):
def finish_populating_tform_popup(self, form, popup):
tft = idaapi.get_tform_type(form)
if tft == idaapi.BWN_DISASM:
# Note the 'None' as action name (1st parameter).
# That's because the action will be deleted immediately
# after the context menu is hidden anyway, so there's
# really no need giving it a valid ID.
desc = idaapi.action_desc_t(None, 'Decode IOCTL', IOCTLDecodeHandler())
idaapi.attach_dynamic_action_to_popup(form, popup, desc, None)
class QuickIOCTLDecoder(idaapi.plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "Decode IOCTL codes!"
help = "Highlight IOCTL and right-click 'Decode IOCTL'"
wanted_name = PLUGIN_NAME
wanted_hotkey = PLUGIN_HOTKEY
def init(self):
idaapi.msg("Initializing: %s\n" % PLUGIN_NAME)
global hooks
hooks = QuickIOCTLDecoderHooks()
re = hooks.hook()
return idaapi.PLUGIN_OK
def run(self, arg):
IDAIOCTLDecoder.decode()
pass
def term(self):
pass
def PLUGIN_ENTRY():
return QuickIOCTLDecoder()
@herrcore
Copy link
Author

herrcore commented Aug 14, 2016

Sigh. There is already a decent IOCTL decoder plugin for IDA

It doesn't have the right-click-decode option that my script has (or the inline comments) but it has more IOCTL codes... you should probably just use it. I guess this is what I get for not googling first.

Sad panda.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment