IRP-talk of chaos: JIURL Home: http://jiurl.yeah.net
IRP is an abbreviation for I / O Request Packet, ie I / O request packages. Communication between the drive and the drive is communicated via IRP. And using functions such as CreatFile, ReadFile, Writefile, DeviceIoControl, and so on, using the driven application layer, saying that the end is also communicating with IRP and driver. An IRP consists of two parts. The first is the fixed portion of the head or the package, is an IRP structure. After following this head, I / O Stack Locations, this is an array of IO_STACK_LOCATION structures, and the number of elements in this array is based on the situation, by IOALLOCATEIRP (IN CCHAR Stacksize, In Boolean Chargequota). Parameter stacksize decisions. Stacksize is usually determined by the 30 char stacksize of the target_Object of IRP. This stacksize is based on the device object in the device object, is determined according to the position in the device stack. Let's first look at the definition of the IRP structure and the IO_STACK_LOCATION structure.
IRP structure is defined as struct _IRP (sizeof = 112) 00 int16 Type 02 uint16 Size 04 struct _MDL * MdlAddress 08 uint32 Flags 0c union __unnamed14 AssociatedIrp 0c struct _IRP * MasterIrp 0c int32 IrpCount 0c void * SystemBuffer 10 struct _LIST_ENTRY ThreadListEntry 10 struct _LIST_ENTRY * Flink 14 struct _LIST_ENTRY * Blink 18 struct _IO_STATUS_BLOCK IoStatus 18 int32 Status 18 void * Pointer 1c uint32 Information 20 char RequestorMode 21 byte PendingReturned 22 char StackCount 23 char CurrentLocation 24 byte Cancel 25 byte CancelIrql 26 char ApcEnvironment 27 byte AllocationFlags 28 struct _IO_STATUS_BLOCK * UserIosb 2c struct _KEVENT * UserEvent 30 union __unnamed15 Overlay 30 struct __unnamed16 AsynchronousParameters 30 function * UserApcRoutine 34 void * UserApcContext 30 union _LARGE_INTEGER AllocationSize 30 uint32 LowPart 34 int32 HighPart 30 struct __unnamed3 u 30 uint32 LowPart 34 int32 HighPart 30 int64 QuadPart 38 function * CancelRoutine 3c void * UserBuffer 40 union __unnamed17 Tail 40 struct __unname d18 Overlay 40 struct _KDEVICE_QUEUE_ENTRY DeviceQueueEntry 40 struct _LIST_ENTRY DeviceListEntry 40 struct _LIST_ENTRY * Flink 44 struct _LIST_ENTRY * Blink 48 uint32 SortKey 4c byte Inserted 40 void * DriverContext [4] 50 struct _ETHREAD * Thread 54 char * AuxiliaryBuffer 58 struct _LIST_ENTRY ListEntry 58 struct _LIST_ENTRY * Flink 5c struct _LIST_ENTRY * Blink 60 struct _IO_STACK_LOCATION * CurrentStackLocation 60 uint32 PacketType 64 struct _FILE_OBJECT * OriginalFileObject 40 struct _KAPC Apc 40 int16 Type
42 int16 Size 44 uint32 Spare0 48 struct _KTHREAD * Thread 4c struct _LIST_ENTRY ApcListEntry 4c struct _LIST_ENTRY * Flink 50 struct _LIST_ENTRY * Blink 54 function * KernelRoutine 58 function * RundownRoutine 5c function * NormalRoutine 60 void * NormalContext 64 void * SystemArgument1 68 void * SystemArgument2 6c char ApcStateIndex 6d char ApcMode 6e byte Inserted 40 void * CompletionKeyIO_STACK_LOCATION structure is defined as struct _IO_STACK_LOCATION (sizeof = 36) 00 byte MajorFunction 01 byte MinorFunction 02 byte Flags 03 byte Control 04 union __unnamed19 Parameters 04 struct __unnamed20 Create 04 struct _IO_SECURITY_CONTEXT * SecurityContext 08 uint32 Options 0c uint16 FileAttributes 0e uint16 ShareAccess 10 uint32 EaLength 04 struct __unnamed21 CreatePipe 04 struct _IO_SECURITY_CONTEXT * SecurityContext 08 uint32 Options 0c uint16 Reserved 0e uint16 ShareAccess 10 struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters 04 struct __unnamed22 CreateMailslot 04 struct _IO_SECURITY_CONTEXT * SecurityContext 08 uint32 O ptions 0c uint16 Reserved 0e uint16 ShareAccess 10 struct _MAILSLOT_CREATE_PARAMETERS * Parameters 04 struct __unnamed23 Read 04 uint32 Length 08 uint32 Key 0c union _LARGE_INTEGER ByteOffset 0c uint32 LowPart 10 int32 HighPart 0c struct __unnamed3 u 0c uint32 LowPart 10 int32 HighPart 0c int64 QuadPart 04 struct __unnamed23 Write 04 uint32 Length 08 uint32 Key 0c union _LARGE_INTEGER ByteOffset 0c uint32 LowPart 10 int32 HighPart 0c struct __unnamed3 u 0c uint32 LowPart 10 int32 HighPart 0c int64 QUADPART
04 struct __unnamed24 QueryDirectory 04 uint32 Length 08 struct _STRING * FileName 0c int32 FileInformationClass 10 uint32 FileIndex 04 struct __unnamed25 NotifyDirectory 04 uint32 Length 08 uint32 CompletionFilter 04 struct __unnamed26 QueryFile 04 uint32 Length 08 int32 FileInformationClass 04 struct __unnamed27 SetFile 04 uint32 Length 08 int32 FileInformationClass 0c struct _FILE_OBJECT * FileObject 10 byte ReplaceIfExists 11 byte AdvanceOnly 10 uint32 ClusterCount 10 void * DeleteHandle 04 struct __unnamed28 QueryEa 04 uint32 Length 08 void * EaList 0c uint32 EaListLength 10 uint32 EaIndex 04 struct __unnamed29 SetEa 04 uint32 Length 04 struct __unnamed30 QueryVolume 04 uint32 Length 08 int32 FsInformationClass 04 struct __unnamed30 SetVolume 04 uint32 Length 08 int32 FsInformationClass 04 struct __unnamed31 FileSystemControl 04 uint32 OutputBufferLength 08 uint32 inputbufferlength 0c uint32 fscontrolcode 10 void * type3inputbuffer 04 struct __unnamed32 lockcontrol 04 union _large_inte GER * Length 08 uint32 Key 0c union _LARGE_INTEGER ByteOffset 0c uint32 LowPart 10 int32 HighPart 0c struct __unnamed3 u 0c uint32 LowPart 10 int32 HighPart 0c int64 QuadPart 04 struct __unnamed33 DeviceIoControl 04 uint32 OutputBufferLength 08 uint32 InputBufferLength 0c uint32 IoControlCode 10 void * Type3InputBuffer 04 struct __unnamed34 QuerySecurity 04 uint32 SecurityInformation 08 uint32 Length 04 struct __unnamed35 SetSecurity 04 uint32 SecurityInformation 08 void * SecurityDescriptor
04 struct __unnamed36 MountVolume 04 struct _VPB * Vpb 08 struct _DEVICE_OBJECT * DeviceObject 04 struct __unnamed36 VerifyVolume 04 struct _VPB * Vpb 08 struct _DEVICE_OBJECT * DeviceObject 04 struct __unnamed37 Scsi 04 * Srb 04 struct __unnamed38 QueryQuota 04 uint32 Length 08 void * StartSid 0c struct _FILE_GET_QUOTA_INFORMATION * sidList 10 uint32 SidListLength 04 struct __unnamed29 setQuota 04 uint32 Length 04 struct __unnamed39 QueryDeviceRelations 04 int32 Type 04 struct __unnamed40 QueryInterface 04 struct _GUID * InterfaceType 08 uint16 Size 0a uint16 Version 0c struct _INTERFACE * Interface 10 void * InterfaceSpecificData 04 struct __unnamed41 DeviceCapabilities 04 struct _DEVICE_CAPABILITIES * Capabilities 04 struct __unnamed42 FilterResourceRequirements 04 struct _IO_RESOURCE_REQUIREMENTS_LIST * IoResourceRequirementList 04 struct __unnamed51 ReadWriteConfig 04 uint32 WhichSpace 08 void * Buffer 0c uint32 offset 10 uint32 Length 04 struct __unnamed52 setlock 04 byte lock 04 struct __unn amed53 QueryId 04 int32 IdType 04 struct __unnamed54 QueryDeviceText 04 int32 DeviceTextType 08 uint32 LocaleId 04 struct __unnamed55 UsageNotification 04 byte InPath 05 byte Reserved [3] 08 int32 Type 04 struct __unnamed56 WaitWake 04 int32 PowerState 04 struct __unnamed57 PowerSequence 04 struct _POWER_SEQUENCE * PowerSequence 04 struct __unnamed58 Power 04 uint32 SystemContext 08 int32 Type 0c union _POWER_STATE State 0c int32 SystemState 0c int32 DeviceState 10 int32 ShutdownType 04 struct __unnamed59 StartDevice
04 struct _CM_RESOURCE_LIST * AllocatedResources 08 struct _CM_RESOURCE_LIST * AllocatedResourcesTranslated 04 struct __unnamed60 WMI 04 uint32 ProviderId 08 void * DataPath 0c uint32 BufferSize 10 void * Buffer 04 struct __unnamed61 Others 04 void * Argument1 08 void * Argument2 0c void * argument3 10 void * Argument4 14 struct _DEVICE_OBJECT * DeviceObject 18 struct _FILE_OBJECT * FileObject 1c function * CompletionRoutine 20 void * ContextIO_STACK_LOCATION structure size is fixed, between 16 bytes 04 to 14 It is a public body. Let's take an example, perhaps you can make you a little concept of a driver for IO_STACK_LOCATION, call Deviceiocontrol, let drivers complete a task. A IRP will be applied in DeviceioControl, initialize it, then use this IRP to call IocallDriver to send the highest layer to the device stack. IocallDriver calls the corresponding function in the drive belonging to the device object according to the 00 Byte Majorfunction in the current IO_STACK_LOCATION in the IRP.
We look to be passed to the top of irp device stack, kd> irp fe403968Irp is active with 6 stacks 6 is current (= 0xfe403a8c) No Mdl System buffer = fe3d6068 Thread fe427960:!. Irp stack trace cmd flg cl Device File Completion -Context [0] 0 00000000-00000000 000000000 000,000 [0, 0] 0 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000-00000000 args: 00000000 00000000 00000000 00000000 [0, 0] 0 0 00000000 00000000 00000000-00000000 args: 00000000 00000000 00000000 00000000 [0, 0] 0 0 00000000 00000000 00000000-00000000 args: 00000000 00000000 00000000 00000000> [e, 0] 0 0 fe4f5df0 fe426688 00000000-00000000 / Driver / KbdclassArgs:! 00000000 00000004 000b0008 00000000WinDbg of irp command, will show some formatting information IO_STACK_LOCATION array of a Irp can see incoming Irp this, its final IO_STACK_LOCATION is the current IO_STACK_LOCATION, There are some parameters that are incoming.
> [E, 0] 0 0 fe4f5df0 fe426688 00000000-00000000 / Driver / KbdclassArgs:!. 00000000 00000004 000b0008 00000000kd> strct io_stack_location fe403a8cstruct _IO_STACK_LOCATION (sizeof = 36) 00 byte MajorFunction = 0e 01 byte MinorFunction = 00 02 byte. Flags = 00. 03 byte Control = 00. 04 union __unnamed19 Parameters 04 struct __unnamed33 DeviceIoControl 04 uint32 OutputBufferLength = 00000000 08 uint32 InputBufferLength = 00000004 0c uint32 IoControlCode = 000b0008 10 void * Type3InputBuffer = 00000000 14 struct _DEVICE_OBJECT * DeviceObject = FE4F5DF0 18 struct _FILE_OBJECT * FileObject = FE426688 1c function * CompletionRoutine = 00000000 20 void * Context = 00000000 which is the current IO_STACK_LOCATION, there are what the parameters, so that this layer driver can according IRP and current IO_STACK_LOCATION in The content knows what to do. In this example, this layer is driven according to this IRP, and the discovery requires the lower-layer driver to do more processing, set the next layer drive to use IO_STACK_LOCATION, then call IOCALLDRIVER, send this IRP to the next layer.
The next layer handler, we take a look at Irpkd received> irp fe403968Irp is active with 6 stacks 5 is current (= 0xfe403a68) No Mdl System buffer = fe3d6068 Thread fe427960:!. Irp stack trace cmd flg cl Device File Completion -Context [0] 0 00000000-00000000 000000000 000,000 [0, 0] 0 0 000000000000000000000000000000000000000000000000000000000000000000000000000000000000-00000000 args: 00000000 00000000 00000000 00000000 [0, 0] 0 0 00000000 00000000 00000000-00000000 args: 00000000 00000000 00000000 00000000> [f, 0] 0 0 fe4f5020 fe426688 00000000-00000000 / Driver / i8042prtArgs: 00000000 00000004 000b0008 00000000 [e, 0 ] 0 0 FE4F5DF0 Fe426688 00000000-00000000 / driver / kbdclassargs: 00000000 00000004 000B0008 000000 00000004 000B0008 000000 We saw the current IO_STACK_LOCATION for IRP to become the second IO_STACK_LOCATION, which is the parameters set in the last driver, tell this floor drive What is it. In this example, this layer drives the read and write port, operating the hardware, and completes the corresponding function. IocallDriver first we look at the most important function of understanding IRP, but also the functions used by IRP to drive inter-communication communication, IOCALLDRIVER. This function is not big, nor complicated, we will see its assembly code in detail. NTSTATUS IOCALLDRIVER (IN PDEvice_Object DeviceObject, in Out PIRP); IRP is the object being sent to the device. Parameters DeviceObject indicate the device target object object.
nt IoCallDriver:! 80421417 8b542408 mov edx, [esp 0x8] / * [esp 0x8] ecx as IN OUT PIRP Irp * / 8042141b 8b4c2404 mov, [esp 0x4] / * [esp 0x4] as IN PDEVICE_OBJECT DeviceObject * ! / 8042141f e82ae1ffff call nt IofCallDriver (8041f54e) 80421424 c20800 ret 0x8nt IofCallDriver:! 8041f54e ff25d01a4780 jmp dword ptr [nt pIofCallDriver (80471ad0)!] nt IopfCallDriver:! 8041f516 56 push esi8041f517 8bf2 mov esi, edx / * edx is IN OUT PIRP Irp * / 8041f519 57 push edi8041f51a 8bf9 mov edi, ecx / * ecx of IN PDEVICE_OBJECT DeviceObject * / 8041f51c fe4e23 dec byte ptr [esi 0x23] / * esi as IN OUT PIRP Irp * // * struct _IRP (sizeof = 112) * // * 23 char CurrentLocation * / 8041f51f 8a4623 mov al, [esi 0x23] 8041f522 33c9 xor ecx, ecx8041f524 3ac1 cmp al, cl8041f526 7f0b jg nt! IopfCallDriver 0x1d (8041f533) / * If Irp-> CurrentLocation greater than 0 , jump * / 8041f528 51 push ecx8041f529 51 push ecx8041f52a 51 push ecx8041f52b 56 push esi8041f52c 6a35 push 0x358041f52e e8e1c90000 call nt! KeBugCheckEx (8042bf14) 8041f533 8b4660 mov eax, [esi 0x60] / * esi as IN OUT P IRP Irp * // * struct _IRP (sizeof = 112) * // * 60 struct _IO_STACK_LOCATION * CurrentStackLocation * / 8041f536 56 push esi / * esi as IN OUT PIRP Irp * / 8041f537 83e824 sub eax, 0x24 / * eax is Irp -> CurrentStackLocation * // * 0x24 is sizeof (IO_STACK_LOCATION) * / 8041f53a 57 push edi / * edi as IN PDEVICE_OBJECT DeviceObject * / 8041f53b 894660 mov [esi 0x60], eax / * [esi 0x60] to Irp-> CurrentStackLocation * / 8041f53e 897814 mov [eax 0x14], edi / * eax new current IO_STACK_LOCATION * // * struct _IO_STACK_LOCATION (sizeof = 36) * // * 14 struct _DEVICE_OBJECT * DeviceObject * // * edi as iN PDEVICE_OBJECT DeviceObject * / 8041F541 8B4F08 MOV ECX, [EDI
0x8] / * edi as IN PDEVICE_OBJECT DeviceObject * // * struct _DEVICE_OBJECT (sizeof = 184) * // * 08 struct _DRIVER_OBJECT * DriverObject * / 8041f544 0fb600 movzx eax, byte ptr [eax] / * eax new current IO_STACK_LOCATION * // * struct _IO_STACK_LOCATION (sizeof = 36) * // * 00 byte MajorFunction * / 8041f547 ff548138 call dword ptr [ecx eax * 4 0x38] / * ecx is DeviceObject-> DriverObject * // * struct _DRIVER_OBJECT ( SizeOf = 168) * // * 38 function * majorfunction [28] * // * eax is IRP-> currentStackLocation-> Majorfunction * // * [ECX EAX * 4 0x38] is * // * deviceObject-> DriverObject.MajorFunction [Irp-> CurrentStackLocation-> MajorFunction] * / 8041f54b 5f pop edi8041f54c 5e pop esi8041f54d c3 retIoCallDriver Irp parameters of 23 char CurrentLocation by 1 and then checks whether this time is greater than 0 CurrentLocation. If it is not more than 0, it will be blue screen. Then, the 60 struct _io_stacklocation * CurrentStackLocation of the parameter IRP is then reduced by 0x24. Here is the address of an IO_STACK_LOCATION, 0x24 is a size of an IO_STACK_LOCATION structure. This reduction of 0x24 is equal to the front IO_STACK_LOCATION to point 60 struct _io_stacklocation. Then the new CurrentStackLocation 14 struct _Device_object * deviceObject assigns the value of the incoming parameter deviceBject. DeviceObject obtained from the parameters passed in the DeviceObject DriverObject, call the corresponding new CurrentStackLocation MajorFunction of 00 byte MajorFunction the DriverObject, the two parameters passed with IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp as parameters. Simply put, put the IRP's CurrentLocation 1, CurrentStackLocation points to IO_STACK_LOCATION of the forward (smaller place). Then, according to the value of Majorfunction, the drive of the DriverObject to which the DRIRRIROBJECT belonging to the DeviceObject is called according to the value referred to by the current CurrentStackLocation referred to. Majorfunction [28] in DriverObject is initialized in DriveREntry. IRP generated IRP said that the end is generated by IOAllocateIRP.