avatar

Catalog
初探IRP(代码&程序演示)

由于篇幅太长了,一篇没法装下,所以程序的完整代码和程序演示放到这篇来。程序演示部分需要结合前一篇文章一起看。这里不再赘述具体过程。

完整代码

Ring3部分

c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "stdafx.h"
#include "Windows.h"
#include "winioctl.h"

#define OPCODE1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define OPCODE2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define SYM_LINK_NAME L"\\\\.\\MyRing3Device"

int main(int argc, char* argv[])
{
//Call IRP_MJ_CREATE
getchar();
HANDLE hDevice = CreateFileW(
SYM_LINK_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

if (hDevice == INVALID_HANDLE_VALUE){
printf("Create File Failed!");
getchar();
return -1;
} else {
printf("Create File Success!");
}

//Call IRP_MY_DEVICE_CONTROL
getchar();
char pInputBuffer[20] = {1, 2, 4, 8, 16, 32, 64, 0};
char pOutputBuffer[20] = {0};
DWORD dwReturnSize = 0;
BOOL bDIC = DeviceIoControl(hDevice, OPCODE2, pInputBuffer, 8, pOutputBuffer, 20, &dwReturnSize, NULL);
if(bDIC != 0){
printf("ReturnSize: %x\n", dwReturnSize);
printf("OutputBuffer: ");
for(int i = 0; i < dwReturnSize; i++){
printf("%x ", pOutputBuffer[i]);
}
}
else {
printf("Communicate Failed!\n");
return -1;
}
printf("\nRing3 And Ring0 Communicate Success!\n");

//Call IRP_MJ_CLOSE
getchar();
BOOL bCH = CloseHandle(hDevice);
if(bCH != 0){
printf("Close File Success!");
}
getchar();
return 0;
}

Ring0部分

c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "ntifs.h"

#define DEVICE_NAME L"\\Device\\MyDevice"
#define SYM_LINK_NAME L"\\??\\MyRing3Device"
#define OPCODE1 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define OPCODE2 CTL_CODE(FILE_DEVICE_UNKNOWN,0x900,METHOD_BUFFERED,FILE_ANY_ACCESS)

VOID Drvier_Unload(PDRIVER_OBJECT pDriverObj);
NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp);
NTSTATUS IrpCloseProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp);
NTSTATUS IrpDeviceControlProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp);

//Driver Entry
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING RegistryPath) {
DbgPrint("Driver is running!\n");

PDEVICE_OBJECT pDeviceObj = NULL;
NTSTATUS status = 0;

//Create Deivce Object
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&DeviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDeviceObj);

if (status != STATUS_SUCCESS) {
DbgPrint("Device Create Failed!\n");
return status;
}
else {
DbgPrint("Device Create Success!\n");
}

//Set Communicate Ways
//注意这里一定要用"|=", 而不能直接用"=",因为在创建Device时会给Fllags赋上一个初值
pDeviceObj->Flags |= DO_BUFFERED_IO;

//Create Symbollic Link
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&SymbolicLinkName, SYM_LINK_NAME);
IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);

//Set Dispatch Function
pDriverObj->MajorFunction[IRP_MJ_CREATE] = IrpCreateProc;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = IrpCloseProc;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlProc;

//Set Unload Function
pDriverObj->DriverUnload = Drvier_Unload;

return STATUS_SUCCESS;
}

NTSTATUS IrpCreateProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp) {
DbgPrint("Irp Create Dispatch Function...\n");

pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}


NTSTATUS IrpCloseProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp) {
DbgPrint("Irp Close Dispatch Function...\n");

pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

NTSTATUS IrpDeviceControlProc(PDEVICE_OBJECT pDeviceObj, PIRP pIrp) {
DbgPrint("Irp DeviceControl Dispatch Function...\n");

//获取缓冲区数据
PVOID pSystemBuffer = pIrp->AssociatedIrp.SystemBuffer;

//获取IO_STACK_LOCATION
PIO_STACK_LOCATION pStackLocation = IoGetCurrentIrpStackLocation(pIrp);
ULONG InputBufferLength = pStackLocation->Parameters.DeviceIoControl.InputBufferLength;
ULONG FsControlCode = pStackLocation->Parameters.DeviceIoControl.IoControlCode;

//判断操作码
switch (FsControlCode)
{
case OPCODE1:
DbgPrint("不打印操作码");
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 2;
break;
case OPCODE2:
DbgPrint("操作码:%x\n", FsControlCode);
for (UINT32 i = 0; i < InputBufferLength; i++) {
DbgPrint("Ring3 Data: %x\n", ((PUCHAR)pSystemBuffer)[i]);
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 5;
break;
}
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

VOID Drvier_Unload(PDRIVER_OBJECT pDriverObj) {
//Delete SymbolicLink
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&SymbolicLinkName, SYM_LINK_NAME);
IoDeleteSymbolicLink(&SymbolicLinkName);

//Delete Deivce
IoDeleteDevice(pDriverObj->DeviceObject);

DbgPrint("Unload Success!\n");
}

程序演示

操作码1

操作码2

Author: cataLoc
Link: http://cata1oc.github.io/2020/04/14/IRP%E4%BB%A3%E7%A0%81%E9%83%A8%E5%88%86/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶