Last active
August 5, 2021 14:51
IOCTL decoding
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
""" | |
IOCTL decoding into an IOCTL dataclass | |
See also: | |
* https://www.osronline.com/article.cfm%5Earticle=229.htm | |
* http://www.ioctls.net/ | |
* https://github.com/h0mbre/ioctl.py | |
* https://github.com/nccgroup/DriverBuddy/blob/master/DriverBuddy/ioctl.py | |
* https://social.technet.microsoft.com/wiki/contents/articles/24653.decoding-io-control-codes-ioctl-fsctl-and-deviceiocodes-with-table-of-known-values.aspx | |
""" | |
from dataclasses import dataclass | |
from typing import Dict | |
DEVICE_TYPES = { | |
0x00000001: "DEVICE_BEEP", | |
0x00000002: "DEVICE_CD_ROM", | |
0x00000003: "DEVICE_CD_ROM_FILE_SYSTEM", | |
0x00000004: "DEVICE_CONTROLLER", | |
0x00000005: "DEVICE_DATALINK", | |
0x00000006: "DEVICE_DFS", | |
0x00000007: "DEVICE_DISK", | |
0x00000008: "DEVICE_DISK_FILE_SYSTEM", | |
0x00000009: "DEVICE_FILE_SYSTEM", | |
0x0000000A: "DEVICE_INPORT_PORT", | |
0x0000000B: "DEVICE_KEYBOARD", | |
0x0000000C: "DEVICE_MAILSLOT", | |
0x0000000D: "DEVICE_MIDI_IN", | |
0x0000000E: "DEVICE_MIDI_OUT", | |
0x0000000F: "DEVICE_MOUSE", | |
0x00000010: "DEVICE_MULTI_UNC_PROVIDER", | |
0x00000011: "DEVICE_NAMED_PIPE", | |
0x00000012: "DEVICE_NETWORK", | |
0x00000013: "DEVICE_NETWORK_BROWSER", | |
0x00000014: "DEVICE_NETWORK_FILE_SYSTEM", | |
0x00000015: "DEVICE_NULL", | |
0x00000016: "DEVICE_PARALLEL_PORT", | |
0x00000017: "DEVICE_PHYSICAL_NETCARD", | |
0x00000018: "DEVICE_PRINTER", | |
0x00000019: "DEVICE_SCANNER", | |
0x0000001A: "DEVICE_SERIAL_MOUSE_PORT", | |
0x0000001B: "DEVICE_SERIAL_PORT", | |
0x0000001C: "DEVICE_SCREEN", | |
0x0000001D: "DEVICE_SOUND", | |
0x0000001E: "DEVICE_STREAMS", | |
0x0000001F: "DEVICE_TAPE", | |
0x00000020: "DEVICE_TAPE_FILE_SYSTEM", | |
0x00000021: "DEVICE_TRANSPORT", | |
0x00000022: "DEVICE_UNKNOWN", | |
0x00000023: "DEVICE_VIDEO", | |
0x00000024: "DEVICE_VIRTUAL_DISK", | |
0x00000025: "DEVICE_WAVE_IN", | |
0x00000026: "DEVICE_WAVE_OUT", | |
0x00000027: "DEVICE_8042_PORT", | |
0x00000028: "DEVICE_NETWORK_REDIRECTOR", | |
0x00000029: "DEVICE_BATTERY", | |
0x0000002A: "DEVICE_BUS_EXTENDER", | |
0x0000002B: "DEVICE_MODEM", | |
0x0000002C: "DEVICE_VDM", | |
0x0000002D: "DEVICE_MASS_STORAGE", | |
0x0000002E: "DEVICE_SMB", | |
0x0000002F: "DEVICE_KS", | |
0x00000030: "DEVICE_CHANGER", | |
0x00000031: "DEVICE_SMARTCARD", | |
0x00000032: "DEVICE_ACPI", | |
0x00000033: "DEVICE_DVD", | |
0x00000034: "DEVICE_FULLSCREEN_VIDEO", | |
0x00000035: "DEVICE_DFS_FILE_SYSTEM", | |
0x00000036: "DEVICE_DFS_VOLUME", | |
0x00000037: "DEVICE_SERENUM", | |
0x00000038: "DEVICE_TERMSRV", | |
0x00000039: "DEVICE_KSEC", | |
0x0000003A: "DEVICE_FIPS", | |
0x0000003B: "DEVICE_INFINIBAND", | |
0x0000003E: "DEVICE_VMBUS", | |
0x0000003F: "DEVICE_CRYPT_PROVIDER", | |
0x00000040: "DEVICE_WPD", | |
0x00000041: "DEVICE_BLUETOOTH", | |
0x00000042: "DEVICE_MT_COMPOSITE", | |
0x00000043: "DEVICE_MT_TRANSPORT", | |
0x00000044: "DEVICE_BIOMETRIC", | |
0x00000045: "DEVICE_PMI", | |
0x00000046: "DEVICE_EHSTOR", | |
0x00000047: "DEVICE_DEVAPI", | |
0x00000048: "DEVICE_GPIO", | |
0x00000049: "DEVICE_USBEX", | |
0x00000050: "DEVICE_CONSOLE", | |
0x00000051: "DEVICE_NFP", | |
0x00000052: "DEVICE_SYSENV", | |
0x00000053: "DEVICE_VIRTUAL_BLOCK", | |
0x00000054: "DEVICE_POINT_OF_SERVICE", | |
0x00000055: "DEVICE_STORAGE_REPLICATION", | |
0x00000056: "DEVICE_TRUST_ENV", | |
0x00000057: "DEVICE_UCM", | |
0x00000058: "DEVICE_UCMTCPCI", | |
0x00000059: "DEVICE_PERSISTENT_MEMORY", | |
0x0000005A: "DEVICE_NVDIMM", | |
0x0000005B: "DEVICE_HOLOGRAPHIC", | |
0x0000005C: "DEVICE_SDFXHCI", | |
0x00000F60: "DEVICE_IRCLASS", | |
} | |
ACCESS_CHECKS = { | |
0x0000: "FILE_ANY_ACCESS", | |
0x0001: "FILE_READ_ACCESS", | |
0x0002: "FILE_WRITE_ACCESS", | |
0x0003: "FILE_READ_ACCESS | FILE_WRITE_ACCESS", | |
} | |
IO_METHODS = { | |
0x0: "METHOD_BUFFERED", | |
0x1: "METHOD_IN_DIRECT", | |
0x2: "METHOD_OUT_DIRECT", | |
0x3: "METHOD_NEITHER", | |
} | |
def ioctl_get_device_type( | |
io_control_code: int, device_types: Dict[int, str] = DEVICE_TYPES | |
) -> str: | |
index = (io_control_code & 0xFFFF0000) >> 16 | |
return device_types.get(index, "DEVICE_UNKNOWN") | |
def ioctl_get_function_code(io_control_code: int) -> int: | |
function_code = bin(io_control_code)[2:][-14:-2] | |
function_code = int(function_code, 2) | |
return function_code | |
def ioctl_get_access_check( | |
io_control_code: int, access_checks: Dict[int, str] = ACCESS_CHECKS | |
) -> str: | |
index = (io_control_code & 0x0000FFFF) >> 14 | |
return access_checks.get(index, "ACCESS_CHECK_UNKNOWN") | |
def ioctl_get_io_method( | |
io_control_code: int, io_methods: Dict[int, str] = IO_METHODS | |
) -> str: | |
index = bin(io_control_code)[2:][-2:] | |
index = int(index, 2) | |
return io_methods.get(index, "METHOD_UNKNOWN") | |
@dataclass(frozen=True) | |
class IOCTL: | |
io_control_code: int | |
def __post_init__(self): | |
object.__setattr__( | |
self, "device_type", ioctl_get_device_type(self.io_control_code) | |
) | |
object.__setattr__( | |
self, "function_code", ioctl_get_function_code(self.io_control_code) | |
) | |
object.__setattr__( | |
self, "access_check", ioctl_get_access_check(self.io_control_code) | |
) | |
object.__setattr__(self, "io_method", ioctl_get_io_method(self.io_control_code)) | |
def __repr__(self) -> str: | |
return ( | |
f"IOCTL(io_control_code={self.io_control_code:#08x}, " | |
f"function_code={self.function_code:#08x}, " | |
f"device_type={self.device_type}, " | |
f"access_check={self.access_check}, " | |
f"io_method={self.io_method})" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment