-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmouse_operation.c
More file actions
157 lines (132 loc) · 5.07 KB
/
mouse_operation.c
File metadata and controls
157 lines (132 loc) · 5.07 KB
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
// Copyright (c) 2026 渟雲. All rights reserved.
#include "./common.h"
MOUSE_OBJECT gMouseObject = {0};
inline BOOL MouseOpen(void) {
// https://github.com/nbqofficial/norsefire
// https://github.com/ekknod/MouseClassServiceCallbackMeme
if (gMouseObject.use_mouse == 0) {
UNICODE_STRING class_string = RTL_CONSTANT_STRING(L"\\Driver\\MouClass");
UNICODE_STRING mouse_driver_names[] = {
RTL_CONSTANT_STRING(L"\\Driver\\MouHID"),
RTL_CONSTANT_STRING(L"\\Driver\\i8042prt")};
PDRIVER_OBJECT class_driver_object = NULL;
PDRIVER_OBJECT hid_driver_object = NULL;
PDEVICE_OBJECT hid_device_object = NULL;
PDEVICE_OBJECT class_device_object = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
size_t driver_idx = 0;
status = ObReferenceObjectByName(&class_string, OBJ_CASE_INSENSITIVE, NULL,
0, *IoDriverObjectType, KernelMode, NULL,
(PVOID*)&class_driver_object);
if (!NT_SUCCESS(status)) {
gMouseObject.use_mouse = 0;
return FALSE;
}
for (driver_idx = 0; driver_idx < ARRAYSIZE(mouse_driver_names);
driver_idx++) {
status = ObReferenceObjectByName(
&mouse_driver_names[driver_idx], OBJ_CASE_INSENSITIVE, NULL, 0,
*IoDriverObjectType, KernelMode, NULL, (PVOID*)&hid_driver_object);
if (NT_SUCCESS(status)) {
break;
}
}
if (!NT_SUCCESS(status) || hid_driver_object == NULL) {
ObfDereferenceObject(class_driver_object);
gMouseObject.use_mouse = 0;
return FALSE;
}
hid_device_object = hid_driver_object->DeviceObject;
gMouseObject.service_callback = NULL;
gMouseObject.mouse_device = NULL;
while (hid_device_object && !gMouseObject.service_callback) {
class_device_object = class_driver_object->DeviceObject;
while (class_device_object && !gMouseObject.service_callback) {
if (!gMouseObject.mouse_device && !class_device_object->NextDevice) {
gMouseObject.mouse_device = class_device_object;
}
PULONG_PTR device_extension =
(PULONG_PTR)hid_device_object->DeviceExtension;
ULONG_PTR device_ext_size =
((ULONG_PTR)hid_device_object->DeviceObjectExtension -
(ULONG_PTR)hid_device_object->DeviceExtension) /
4;
for (ULONG_PTR i = 0; i < device_ext_size; i++) {
if (device_extension[i] == (ULONG_PTR)class_device_object &&
device_extension[i + 1] > (ULONG_PTR)class_driver_object) {
gMouseObject.service_callback =
(MouseClassServiceCallbackFn)(device_extension[i + 1]);
break;
}
}
class_device_object = class_device_object->NextDevice;
}
hid_device_object = hid_device_object->AttachedDevice;
}
if (!gMouseObject.mouse_device) {
PDEVICE_OBJECT target_device_object = class_driver_object->DeviceObject;
while (target_device_object) {
if (!target_device_object->NextDevice) {
gMouseObject.mouse_device = target_device_object;
break;
}
target_device_object = target_device_object->NextDevice;
}
}
ObfDereferenceObject(class_driver_object);
ObfDereferenceObject(hid_driver_object);
gMouseObject.use_mouse =
(gMouseObject.mouse_device && gMouseObject.service_callback) ? 1 : 0;
}
return (gMouseObject.mouse_device != NULL) &&
(gMouseObject.service_callback != NULL);
}
inline void MouseCall(long x, long y, unsigned short button_flags,
unsigned short flags) {
KIRQL irql;
ULONG input_data;
MOUSE_INPUT_DATA mid = {0};
mid.LastX = x;
mid.LastY = y;
mid.ButtonFlags = button_flags;
mid.Flags = flags;
if (!MouseOpen()) {
return;
}
mid.UnitId = 1;
RAISE_IRQL(DISPATCH_LEVEL, &irql);
MouseClassServiceCallbackMeme(gMouseObject.mouse_device, &mid,
(PMOUSE_INPUT_DATA)&mid + 1, &input_data);
KeLowerIrql(irql);
}
VOID HandleMouseEvent(Requests* request) {
if (!request) return;
DWORD dwFlags = request->dwFlags;
LONG dx = request->dx;
LONG dy = request->dy;
long x = 0, y = 0;
unsigned short button_flags = 0;
unsigned short flags = MOUSE_MOVE_RELATIVE;
if (dwFlags & MOUSEEVENTF_MOVE) {
x = dx;
y = dy;
if (dwFlags & MOUSEEVENTF_ABSOLUTE) {
flags = MOUSE_MOVE_ABSOLUTE;
if (dwFlags & MOUSEEVENTF_VIRTUALDESK) {
flags |= MOUSE_VIRTUAL_DESKTOP;
}
x = max(0, min(65535, dx));
y = max(0, min(65535, dy));
}
}
if (dwFlags & MOUSEEVENTF_LEFTDOWN) button_flags |= 0x0001;
if (dwFlags & MOUSEEVENTF_LEFTUP) button_flags |= 0x0002;
if (dwFlags & MOUSEEVENTF_RIGHTDOWN) button_flags |= 0x0004;
if (dwFlags & MOUSEEVENTF_RIGHTUP) button_flags |= 0x0008;
if (dwFlags & MOUSEEVENTF_MIDDLEDOWN) button_flags |= 0x0010;
if (dwFlags & MOUSEEVENTF_MIDDLEUP) button_flags |= 0x0020;
if (dwFlags & MOUSEEVENTF_XDOWN) button_flags |= 0x0040;
if (dwFlags & MOUSEEVENTF_XUP) button_flags |= 0x0080;
MouseCall(x, y, button_flags, flags);
request->return_value = TRUE;
}