드라이버 코드
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
#include <ntifs.h>
#include <ntddk.h> // NT Legacy Style 드라이버를 개발하려는 경우
// - 디바이스 스택을 사용하지 않는 드라이버
// - 커널단에서 동작하는 애플리케이션으로 이해
#include <wdm.h> // WDM Style 디바이스 스택을 사용하는 드라이버
// - ntddk 보다 세련됨
#include <ntstrsafe.h> // RtlStringCbPrintfW() 함수를 사용하기 위해 선언
#define NTDEVICE_NAME_STRING L"\\Device\\GF_sys_driver"
#define SYMBOLIC_NAME_STRING L"\\DosDevices\\MY_GF_sys_driver"
#define IOCTL_MESSAGE CTL_CODE(FILE_DEVICE_UNKNOWN,0x888,METHOD_BUFFERED,FILE_ANY_ACCESS)
NTSTATUS MyCreateDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS MyCloseDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS MyDeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID DriverUnload(
_In_ PDRIVER_OBJECT driverObject
)
{
UNREFERENCED_PARAMETER(driverObject);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "[WJ_mft_DriverUnload()]\n");
UNICODE_STRING SymbolicLinkName;
// 심볼릭링크 삭제
RtlInitUnicodeString(&SymbolicLinkName, SYMBOLIC_NAME_STRING);
IoDeleteSymbolicLink(&SymbolicLinkName);
// DeviceObject 삭제 Delete the user-mode symbolic link and deviceobjct.
IoDeleteDevice(driverObject->DeviceObject);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "==>Unload\n");
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT driverObject,
IN PUNICODE_STRING registryPath
)
{
driverObject->DriverUnload = DriverUnload;
//사용하지 않는 파라미터는 에러처리
UNREFERENCED_PARAMETER(registryPath); // registryPath = registryPath 이렇게 해도 됨.
UNREFERENCED_PARAMETER(driverObject);
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING ntDeviceName;
UNICODE_STRING SymbolicLinkName;
// Set up dispatch entry points for the driver.
driverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateDispatch;
driverObject->MajorFunction[IRP_MJ_CLOSE] = MyCloseDispatch;
driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControlDispatch; // IOCTL 명령어를 받을 수 있도록 합니다
// DeviceObject 생성
RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "==> CreateDeviceObject [%ls]\n", ntDeviceName.Buffer);
status = IoCreateDevice(
driverObject, // DriverObject
0, // DeviceExtensionSize
&ntDeviceName, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
FILE_DEVICE_SECURE_OPEN, // DeviceCharacteristics
FALSE, // Not Exclusive
&DeviceObject // DeviceObject
);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "\tIoCreateDevice returned 0x%x\n", status);
return(status);
}
// 심볼릭생성 Create a symbolic link for userapp to interact with the driver.
RtlInitUnicodeString(&SymbolicLinkName, SYMBOLIC_NAME_STRING);
status = IoCreateSymbolicLink(&SymbolicLinkName, &ntDeviceName);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, " Create a symbolic link [%ls]\n", SymbolicLinkName.Buffer);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(DeviceObject);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "\tIoCreateSymbolicLink returned 0x%x\n", status);
return(status);
}
if (!NT_SUCCESS(status)) {
DriverUnload(driverObject);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "DriverUnload\n");
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "DriverUnload\n");
return status;
}
NTSTATUS MyCreateDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pDevObj = pDevObj;
pIrp = pIrp;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "\n[%s]\n", "MyCreateDispatch()");
IoCompleteRequest(pIrp, 0); // 0 -> IO_NO_INCREMENT
pIrp->IoStatus.Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NTSTATUS MyCloseDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, 0); // 0 -> IO_NO_INCREMENT
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "==> MyCloseDispatch!!\n");
return STATUS_SUCCESS;
}
// Win32 API DeviceIoControl()함수와 연결됩니다
NTSTATUS MyDeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "\n[%s]\n", "MyDeviceIoControlDispatch()");
PIO_STACK_LOCATION pStack = NULL;
NTSTATUS Status = STATUS_INVALID_PARAMETER;
NTSTATUS retStatus = STATUS_SUCCESS;
ULONG ControlCode;
PWCHAR InBuf;
PWCHAR OutBuf;
ULONG InBufLength, OutBufLength;
pStack = IoGetCurrentIrpStackLocation(pIrp); // IRP의 파라미터중에 현재 드라이버를 위한 영역을 찾습니다
InBufLength = pStack->Parameters.DeviceIoControl.InputBufferLength;
OutBufLength = pStack->Parameters.DeviceIoControl.OutputBufferLength;
//유저 어플리케이션에서 전달한 컨트롤 코드 찾아옴
ControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
switch (pStack->Parameters.DeviceIoControl.IoControlCode) // IOCTL 명령어를 확인합니다
{
case IOCTL_MESSAGE:
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "==> IOCTL EVENT!\n");
//유저에서 넘어온 메시지
InBuf = (PWCHAR)pIrp->AssociatedIrp.SystemBuffer;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "data from user : %S\n", InBuf);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "meesage length : %d\n", InBufLength);
WCHAR ob[128] = { 0, };
// [Driver->App send message]
RtlStringCbPrintfW(ob, sizeof(ob), L"hello world (%d)\n", 77);
unsigned int ob_len = (unsigned int)wcslen(ob) * 2;
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "send : %S\n", ob);
DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "lenght : %d\n", ob_len);
//유저로 넘길 메시지
OutBuf = (PWCHAR)pIrp->AssociatedIrp.SystemBuffer;
//메시지 복사
RtlCopyBytes(OutBuf, ob, ob_len); // NULL 문자를 뺀 순수 문자열의 길이만 구한다.
pIrp->IoStatus.Information = ob_len;
break;
}
Status = STATUS_SUCCESS;
pIrp->IoStatus.Status = Status;
IoCompleteRequest(pIrp, 0); // 0 -> IO_NO_INCREMENT
return Status;
}
|
cs |
App 코드
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
|
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
// IOCTL 코드 정의
#define IOCTL_PROCLIST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x888, METHOD_BUFFERED, FILE_ANY_ACCESS)
#pragma warning(disable: 4996)
int main()
{
HANDLE hHandle;
BOOL DICret;
WCHAR path[] = L"\\\\.\\MY_GF_sys_driver";
WCHAR inputBuffer[100];
WCHAR outputBuffer[100];
ULONG bytesret;
int mLen;
//CreateFile 실행하여 Device handle 반환
hHandle = CreateFile(path,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hHandle == INVALID_HANDLE_VALUE)
printf("Open Handle ERROR\n");
wcscpy(inputBuffer, L"Sending debugging message");
wprintf(L"[app->driver] : %s\n", inputBuffer);
mLen = (DWORD)wcslen(inputBuffer) * 2 + 1;
DICret = DeviceIoControl(hHandle,
IOCTL_PROCLIST,
&inputBuffer,
mLen,
&outputBuffer,
sizeof(outputBuffer),
&bytesret,
NULL);
if (!DICret) {
printf("Device Io Control Error (%d)\n", GetLastError());
}
wprintf(L">>>>>> [Driver->App] %s", outputBuffer);
wprintf(L"buffer size : %d(%d)\n", wcslen(outputBuffer), wcslen(outputBuffer) * 2);
CloseHandle(hHandle);
_getch();
return 0;
}
|
cs |
결과

'Windows Driver > Kernel & Driver 개발' 카테고리의 다른 글
Window Kernel & driver 문자열 변환 (0) | 2023.01.20 |
---|---|
PEB 구조체 분석 - 프로세스에 로드된 dll 정보 분석 (0) | 2023.01.06 |
7. 드라이버와 App간 통신 (문자열 주고 받기_이론) (0) | 2022.11.04 |
6. 드라이버와 app간 통신 (0) | 2022.10.26 |
5. 특정 프로그램 실행 제어 (0) | 2022.10.03 |