-
Notifications
You must be signed in to change notification settings - Fork 96
Command Line Interface
Accessing IRPMon functionality through the GUI IRPMon.exe
application is nice for those who like the manual approach, or are just used to programs like Process Monitor from SysInternals. Others may take advantage of the command-line interface implemented as the irpmonc.exe
console application. Its functionality matches the GUI application with exception of request filters; they are simply not present.
More precisely, the console application is capable of the following tasks:
- hooking and unhooking drivers and devices,
- registering and unregistering driver name watches,
- reading and modifying global driver settings,
- retrieving requests (from the driver or a file) and sending them to other places (standard output or a file) in different formats (binary, text or JSON),
- loading and unloading the driver,
- stopping another
irpmonc
instances, - alter debug symbol settings.
The input is a place from where the application can retrieve requests in order to process them further. This can be a control device of the IRPMon driver (usually named \\.\IRPMon
), an IP address and port where the IRPMon server service listents, or a binary log file generated previously. In the first two cases, it is also possible to hook or unhook drivers and devices, register or unregister driver name watches etc. If the file is specified, irpmonc
just reads requests stored there and processes them.
Exactly one input must be specified. To do that, use the --input
argument in one of the following ways:
-
--input=D:\\.\IRPMon
connects to the IRPMon driver running on the local machine. -
--input=N:IP:port
attempts to connect to an instance of the IRPMon server listening atIP:port
. Both IPv4 and IPv6 are protocols supported. -
--input=L:C:\log\irpmon.log
opens a log fileC:\log\irpmon.log
.
irpmonc
is capable of writting processed requests into multiple areas, called outputs
, at the same time. Use the --output
argument repeatedly to define all outputs. The syntax is
--output=B:<filename>
--output=J:<filename>
--output=T:<filename>
The output format is determined by the letter before the colon:
-
B
stands for the IRPMon binary request format. Such a file can later be specified either as an input to anotherirpmonc
instance, or can be opened in the IRPMon graphics application. No other format can do that. -
T
is a simple text format where each line contains one name-value pair. This format is easily readable by human users, however, is hardly useful for anything also. -
J
instructsirpmonc
to output each request as a JSON object. One request is printed per line. This format is expected to be useful in some automatic post-processing.
To output to the standard output, specify -
as file name. If no output is specified, irpmonc
just does operations, such as driver (un)hooking and driver name watch (un)registration; it does not processes requests from the input.
Hooking drivers can be done via the --hook-driver
commands. As shown below, its capabilities are rather broad.
--hook-driver=[I][C][F][A][S][U][N][D][W][E][a]:<drivername>
Drivers are always hooked by their object names. Multiple letters may be specified before the colon, allowing to alter the following monitoring options:
-
IRPs (
I
), - IRP completions (
C
), -
Fast I/O callbacks (
F
), -
AddDevice callbacks for PnP drivers (
A
), -
StartIo callback (
S
), - driver unload (
U
). - associate extra data with requests, i,e. bytes being read or written (
D
).
Use a
to hook all devices currently managed by the target driver. To monitor only devices newly created by the driver in the future, specify N
. The E
character causes a device extension-based hook, rather than standard IRP one which may bypass Patchguard.
If the target driver is not loaded yet, you may specify W
. In that case, a driver name watch is registered and the driver is hooked when its presence is detected.
Use the --unhook-driver
command to unhook a driver. To unregister a driver name watch, specify the W
character.
--unhook-driver=[W]:<drivername>
Commands for hooking and unhooking individual devices have the same syntax. You must specify either A
or N
to determine whether irpmonc
should search for the target device by its name or address.
--hook-device=<A|N>:<devicename|address>
--unhook-device=<A|N>:<devicename|address>
Keep in mind that it is possible to hook a device object only if its parent driver is also hooked. irpmonc
always hooks drivers before attempting to hook any device directly. Also, when a driver is unhooked, all its devices are automatically unhooked as well.
Most of the global settings are of boolean type. To change a setting, specify the following on the command line:
--setting=<0|no|false|1|yes|true>
Use 1, yes or true to change the boolean value to true and 0, no or false to set it to false. The following table lists all available settings. They are specified without the --
prefix.
Setting | Description |
---|---|
clear-on-disconnect |
Clear the driver event queue after disconnecting it. |
collect-disconnected |
Instruct the driver to collect events even if no one is connected ti its device. |
process-events |
Report process creating, terminating and PE image loads. |
snapshot-events |
Report new driver and device objects detected by the driver. |
file-object-events |
Report mappings between file objects and their names in order to track file names accross multiple operations. |
process-emulate |
Emulate process creation and image load events after successful connection to the driver. This allows the appplication to enumerate running processes and their modules |
snapshot-emulate |
Emulate driver and device detection events in order to comforably enumerate all existing device and driver objects. |
strip-data |
Truncate data associated with individual requests up to a limit specified by the --strip-threshold=<sizeinbytes> parameter. |
boot-log |
Enable boot logging. You also may need to change the start type of the driver service (irpmndrv ) to appropriate value. irpmonc does not do that. |
save-settings |
Instructs the driver to save new settings into registry to preserve them accross system reboots or driver unloads. |
It is also possible to change the maximum amount of data that can be associated with each request. Use --strip-threshold=<number>
to do that. By default, the threshold is set to 1024 (bytes).
Global driver settings are automatically displayed by irpmonc
on the standard error output during its startup, unless a file-based input is specified.
irpmonc
is also capable of loading or unloading the IRPMon driver through starting or stopping its service. The load attempt is made just after the command-line is parsed (thus, before any other action); the driver may be then unloaded as one of the last actions performed by the application before its termination.
Use one of the following switches to manipulate with the driver:
-
--load[=<service>]
to load the driver on application startup. You may optionally specify driver service name,irpmndrv
is the default. -
--unload[=<service>]
to unload the driver on application exit. You may optionally specify driver service name,irpmndrv
is the default.
When an instance of irpmonc
is connected to the driver (either locally, or via a network), it starts collecting events in sort of an infinite loop. Since irpmonc
is a console application, the CTRL+C
key combination can be used to stop it. The application handles the signal, so it exits in an orderlz fashion.
Another possibility of a nice termination is implemented through the --stop[=<PID>]
command. When irpmonc
sees it on its command-line, it either
- sends a termination signal to all existing
irpmonc
instances if no PID is specified, or - sends the termination signal to an instance specified by the PID argument.
For example, to sniff the driver \Driver\iaLPSS2_UART2_ADL
during the boot procedure, we would run the following:
irpmonc.exe --input=D:\\.\irpmndrv --hook-driver=ICD:\Driver\iaLPSS2_UART2_ADL --boot-log=1 --save-settings=1
The --input=D:\\.\irpmndrv
denotes we'll use the local instance of the driver. The --hook-driver=ICD:\Driver\iaLPSS2_UART2_ADL
section specifies the driver of interest and sets up recording of IRP, IRPComplete, with Data for the driver called \Driver\iaLPSS2_UART2_ADL
. Finally, the --boot-log=1
setting specifies that we want to record during the boot procedure and --save-settings=1
writes the settings to the registry. The logs are written to C:\Windows\
, named like IRPMon-2023-12-08 05-34-35.log
. The log is written periodically, but may appear to be zero length shortly after the boot procedure. To ensure this log is flushed to the disk, it's best to reboot.
The above command will set up a log that begins recoring at each boot, to disable the logging run the command:
irpmonc.exe --input=D:\\.\irpmndrv --unhook-driver=\Driver\iaLPSS2_UART2_ADL --boot-log=0 --save-settings=1
This does not prevent any currently unwritten events from being written to the disk.
- IRPMonDllClassWatchEnum
- IRPMonDllClassWatchEnumFree
- IRPMonDllClassWatchRegister
- IRPMonDllClassWatchUnregister
- IRPMonDllCloseHookedDeviceHandle
- IRPMonDllCloseHookedDriverHandle
- IRPMonDllConnect
- IRPMonDllDisconnect
- IRPMonDllDriverHooksEnumerate
- IRPMonDllDriverHooksFree
- IRPMonDllDriverNameWatchEnum
- IRPMonDllDriverNameWatchEnumFree
- IRPMonDllDriverNameWatchRegister
- IRPMonDllDriverNameWatchUnregister
- IRPMonDllDriverSetInfo
- IRPMonDllDriverStartMonitoring
- IRPMonDllDriverStopMonitoring
- IRPMonDllEmulateDriverDevices
- IRPMonDllEmulateProcesses
- IRPMonDllFinalize
- IRPMonDllGetRequest
- IRPMonDllHookDeviceByAddress
- IRPMonDllHookDeviceByName
- IRPMonDllHookDriver
- IRPMonDllHookedDeviceGetInfo
- IRPMonDllHookedDeviceSetInfo
- IRPMonDllHookedDriverGetInfo
- IRPMonDllInitialize
- IRPMonDllInitialized
- IRPMonDllOpenHookedDevice
- IRPMonDllOpenHookedDriver
- IRPMonDllQueueClear
- IRPMonDllSettingsQuery
- IRPMonDllSettingsSet
- IRPMonDllSnapshotFree
- IRPMonDllSnapshotRetrieve
- IRPMonDllUnhookDevice
- IRPMonDllUnhookDriver
- CLASS_WATCH_RECORD
- DRIVER_MONITOR_SETTINGS
- DRIVER_NAME_WATCH_RECORD
- EFastIoOperationType
- EIRPMonConnectorType
- ERequestHeaderFlags
- ERequestResultType
- ERequestType
- HOOKED_DEVICE_INFO
- HOOKED_DEVICE_UMINFO
- HOOKED_DRIVER_INFO
- HOOKED_DRIVER_UMINFO
- HOOKED_OBJECTS_INFO
- IRPMNDRV_SETTINGS
- IRPMON_DEVICE_INFO
- IRPMON_DEVICE_INIT_INFO
- IRPMON_DRIVER_INFO
- IRPMON_INIT_INFO
- IRPMON_INIT_INFO_DATA
- IRPMON_NETWORK_INIT_INFO
- PCLASS_WATCH_RECORD
- PDRIVER_MONITOR_SETTINGS
- PDRIVER_NAME_WATCH_RECORD
- PEFastIoOperationType
- PEIRPMonConnectorType
- PERequestHeaderFlags
- PERequestResultType
- PERequestType
- PHOOKED_DEVICE_INFO
- PHOOKED_DEVICE_UMINFO
- PHOOKED_DRIVER_INFO
- PHOOKED_DRIVER_UMINFO
- PHOOKED_OBJECTS_INFO
- PIRPMNDRV_SETTINGS
- PIRPMON_DEVICE_INFO
- PIRPMON_DEVICE_INIT_INFO
- PIRPMON_DRIVER_INFO
- PIRPMON_INIT_INFO
- PIRPMON_INIT_INFO_DATA
- PIRPMON_NETWORK_INIT_INFO
- PREQUEST_ADDDEVICE
- PREQUEST_FASTIO
- PREQUEST_HEADER
- PREQUEST_IRP
- PREQUEST_STARTIO
- PREQUEST_UNLOAD
- REQUEST_ADDDEVICE
- REQUEST_FASTIO
- REQUEST_HEADER
- REQUEST_IRP
- REQUEST_STARTIO
- REQUEST_UNLOAD
- _CLASS_WATCH_RECORD
- _DRIVER_MONITOR_SETTINGS
- _DRIVER_NAME_WATCH_RECORD
- _EFastIoOperationType
- _EIRPMonConnectorType
- _ERequestHeaderFlags
- _ERequestResultType
- _ERequestType
- _HOOKED_DEVICE_INFO
- _HOOKED_DEVICE_UMINFO
- _HOOKED_DRIVER_INFO
- _HOOKED_DRIVER_UMINFO
- _HOOKED_OBJECTS_INFO
- _IRPMNDRV_SETTINGS
- _IRPMON_DEVICE_INFO
- _IRPMON_DEVICE_INIT_INFO
- _IRPMON_DRIVER_INFO
- _IRPMON_INIT_INFO
- _IRPMON_INIT_INFO_DATA
- _IRPMON_NETWORK_INIT_INFO
- _REQUEST_ADDDEVICE
- _REQUEST_FASTIO
- _REQUEST_HEADER
- _REQUEST_IRP
- _REQUEST_STARTIO
- _REQUEST_UNLOAD