-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
343 lines (301 loc) · 13.7 KB
/
Copy pathmain.cpp
File metadata and controls
343 lines (301 loc) · 13.7 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
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#include <windows.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <chrono>
#include <thread>
#include <conio.h> // _kbhit(), _getch()
// Upper.c 驅動的 IOCTL 定義 - 只需要一個
constexpr DWORD IOCTL_UPPER_SET_RECEIVE = CTL_CODE(FILE_DEVICE_MOUSE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS);
// 修正:使用與 Upper.h 完全相同的結構定義
typedef struct _UPPER_CONTROL_DATA {
BOOLEAN Receive; // 輸入:是否啟用接收模式
} UPPER_CONTROL_DATA, *PUPPER_CONTROL_DATA;
// 滑鼠輸入數據結構 (與內核一致)
typedef struct _MOUSE_INPUT_DATA {
USHORT UnitId;
USHORT Flags;
union {
ULONG Buttons;
struct {
USHORT ButtonFlags;
USHORT ButtonData;
};
};
ULONG RawButtons;
LONG LastX;
LONG LastY;
ULONG ExtraInformation;
} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA;
typedef struct _UPPER_MOUSE_DATA {
BOOLEAN HasData; // 是否有數據
MOUSE_INPUT_DATA Data; // 滑鼠數據
} UPPER_MOUSE_DATA, *PUPPER_MOUSE_DATA;
void CheckSymbolicLink() {
std::cout << "\n=== Symbolic Link Diagnostic ===" << std::endl;
// 檢查符號連結是否存在
HANDLE hTest = CreateFileW(
L"\\\\.\\Upper",
0, // 不要求任何存取權限,只檢查存在性
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (hTest != INVALID_HANDLE_VALUE) {
std::cout << "✅ Symbolic link exists and accessible" << std::endl;
CloseHandle(hTest);
} else {
DWORD error = GetLastError();
std::cout << "❌ Symbolic link test failed. Error: " << error << std::endl;
// 嘗試其他路徑
std::cout << "Trying alternative paths..." << std::endl;
// 嘗試直接設備路徑
hTest = CreateFileW(
L"\\\\?\\GLOBALROOT\\Device\\UpperControl",
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (hTest != INVALID_HANDLE_VALUE) {
std::cout << "✅ Direct device path works!" << std::endl;
CloseHandle(hTest);
} else {
std::cout << "❌ Direct device path failed. Error: " << GetLastError() << std::endl;
}
}
}
void MonitorMouseData(HANDLE hDevice) {
std::cout << "\n=== Mouse Data Monitor Started ===" << std::endl;
std::cout << "📋 Press any key to stop monitoring..." << std::endl;
std::cout << "📋 The monitor will call IOCTL_UPPER_SET_RECEIVE repeatedly to get mouse data..." << std::endl;
while (!_kbhit()) {
UPPER_CONTROL_DATA controlData = { TRUE }; // 保持接收模式開啟
UPPER_MOUSE_DATA mouseOutput = { 0 };
DWORD bytesReturned = 0;
BOOL ok = DeviceIoControl(
hDevice,
IOCTL_UPPER_SET_RECEIVE,
&controlData,
sizeof(UPPER_CONTROL_DATA),
&mouseOutput,
sizeof(UPPER_MOUSE_DATA),
&bytesReturned,
nullptr
);
if (ok && bytesReturned == sizeof(UPPER_MOUSE_DATA)) {
if (mouseOutput.HasData) {
std::cout << "🖱️ Mouse Data: X=" << mouseOutput.Data.LastX
<< ", Y=" << mouseOutput.Data.LastY
<< ", Buttons=0x" << std::hex << mouseOutput.Data.ButtonFlags << std::dec
<< ", Flags=0x" << std::hex << mouseOutput.Data.Flags << std::dec << std::endl;
}
} else {
// IOCTL 失敗或沒有數據,短暫等待
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
_getch(); // 清除按鍵緩衝區
std::cout << "\n📋 Mouse data monitoring stopped." << std::endl;
}
int main() {
std::cout << "=== Upper Driver Test Tool (Simplified Design) ===" << std::endl;
// 檢查是否以管理員身份運行
BOOL isAdmin = FALSE;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) {
CheckTokenMembership(nullptr, AdministratorsGroup, &isAdmin);
FreeSid(AdministratorsGroup);
}
if (!isAdmin) {
std::cout << "⚠️ WARNING: Not running as administrator!" << std::endl;
std::cout << " This may cause permission issues." << std::endl;
} else {
std::cout << "✅ Running as administrator" << std::endl;
}
// 檢查驅動程式服務狀態
SC_HANDLE scManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
if (scManager) {
SC_HANDLE service = OpenServiceW(scManager, L"Upper", SERVICE_QUERY_STATUS);
if (service) {
SERVICE_STATUS status;
if (QueryServiceStatus(service, &status)) {
std::cout << "Driver service found. Status: ";
switch (status.dwCurrentState) {
case SERVICE_RUNNING: std::cout << "RUNNING ✅" << std::endl; break;
case SERVICE_STOPPED: std::cout << "STOPPED ❌" << std::endl; break;
case SERVICE_PAUSED: std::cout << "PAUSED ⚠️" << std::endl; break;
default: std::cout << "UNKNOWN (" << status.dwCurrentState << ") ❓" << std::endl; break;
}
}
CloseServiceHandle(service);
} else {
std::cout << "Driver service not found. Error: " << GetLastError() << std::endl;
}
CloseServiceHandle(scManager);
}
// 檢查符號連結
CheckSymbolicLink();
// 嘗試多種方式打開設備
std::cout << "\n=== Device Connection Attempts ===" << std::endl;
HANDLE hDevice = INVALID_HANDLE_VALUE;
// 方法 1: 標準方式
std::cout << "Attempt 1: Standard path..." << std::endl;
hDevice = CreateFileW(
L"\\\\.\\Upper",
GENERIC_READ | GENERIC_WRITE,
0,
nullptr,
OPEN_EXISTING,
0,
nullptr
);
if (hDevice == INVALID_HANDLE_VALUE) {
DWORD error1 = GetLastError();
std::cout << "❌ Failed with error: " << error1 << std::endl;
// 方法 2: 等待一下再試
std::cout << "Attempt 2: Waiting 2 seconds and retry..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
hDevice = CreateFileW(
L"\\\\.\\Upper",
GENERIC_READ | GENERIC_WRITE,
0,
nullptr,
OPEN_EXISTING,
0,
nullptr
);
if (hDevice == INVALID_HANDLE_VALUE) {
DWORD error2 = GetLastError();
std::cout << "❌ Still failed with error: " << error2 << std::endl;
// 方法 3: 降低權限要求
std::cout << "Attempt 3: Lower privilege requirements..." << std::endl;
hDevice = CreateFileW(
L"\\\\.\\Upper",
GENERIC_READ, // 只要求讀取權限
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
0,
nullptr
);
if (hDevice == INVALID_HANDLE_VALUE) {
DWORD error3 = GetLastError();
std::cout << "❌ Final attempt failed with error: " << error3 << std::endl;
std::cout << "\n=== Error Analysis ===" << std::endl;
switch (error3) {
case ERROR_FILE_NOT_FOUND:
std::cout << "🔍 Device not found. Check if symbolic link exists." << std::endl;
break;
case ERROR_ACCESS_DENIED:
std::cout << "🔒 Access denied. Try running as administrator." << std::endl;
break;
case ERROR_INVALID_FUNCTION:
std::cout << "⚙️ Invalid function. Driver may not support CREATE operation." << std::endl;
std::cout << " Check if UpperCreateClose handler is working properly." << std::endl;
break;
case ERROR_SHARING_VIOLATION:
std::cout << "🔄 Sharing violation. Device may be in use." << std::endl;
break;
default:
std::cout << "❓ Unknown error: " << error3 << std::endl;
break;
}
std::cout << "\n=== Troubleshooting Suggestions ===" << std::endl;
std::cout << "1. Check DebugView for '[Upper] Control device opened' message" << std::endl;
std::cout << "2. Restart driver: sc stop Upper && sc start Upper" << std::endl;
std::cout << "3. Ensure CREATE/CLOSE handlers are properly implemented" << std::endl;
std::cout << "4. Check Windows Event Viewer for driver errors" << std::endl;
system("pause");
return 1;
}
}
}
std::cout << "✅ Device connected successfully!" << std::endl;
std::cout << "📢 Check DebugView for '[Upper] Control device opened' message" << std::endl;
std::string cmd;
std::cout << "\n=== Available Commands ===" << std::endl;
std::cout << " on - Enable mouse interception (redirect to usermode)" << std::endl;
std::cout << " off - Disable interception (normal mode)" << std::endl;
std::cout << " monitor - Monitor intercepted mouse data (simplified)" << std::endl;
std::cout << " status - Show current status" << std::endl;
std::cout << " exit - Exit program" << std::endl;
std::cout << "\n💡 New simplified design: Only one IOCTL needed!" << std::endl;
std::cout << "💡 IOCTL_UPPER_SET_RECEIVE both controls interception AND returns mouse data!" << std::endl;
while (true) {
std::cout << "\n> ";
std::cin >> cmd;
std::transform(cmd.begin(), cmd.end(), cmd.begin(), ::tolower);
if (cmd == "on" || cmd == "off") {
BOOLEAN receiveValue = (cmd == "on") ? TRUE : FALSE;
UPPER_CONTROL_DATA controlData = { receiveValue };
UPPER_MOUSE_DATA mouseOutput = { 0 };
DWORD bytesReturned = 0;
std::cout << "📤 Sending IOCTL with Receive=" << (receiveValue ? "TRUE" : "FALSE") << std::endl;
BOOL ok = DeviceIoControl(
hDevice,
IOCTL_UPPER_SET_RECEIVE,
&controlData,
sizeof(UPPER_CONTROL_DATA),
&mouseOutput,
sizeof(UPPER_MOUSE_DATA),
&bytesReturned,
nullptr
);
if (ok) {
std::cout << "✅ Set to " << cmd << " OK" << std::endl;
if (cmd == "on") {
std::cout << "🔄 Mouse data will now be redirected to usermode instead of system" << std::endl;
std::cout << "📌 Use 'monitor' command to see intercepted mouse data" << std::endl;
} else {
std::cout << "🔄 Mouse data will flow normally to system" << std::endl;
}
// 檢查是否同時返回了滑鼠數據
if (bytesReturned == sizeof(UPPER_MOUSE_DATA) && mouseOutput.HasData) {
std::cout << "📦 Bonus: Got mouse data with control response!" << std::endl;
std::cout << " X=" << mouseOutput.Data.LastX
<< ", Y=" << mouseOutput.Data.LastY
<< ", Buttons=0x" << std::hex << mouseOutput.Data.ButtonFlags << std::dec << std::endl;
}
std::cout << "📢 Check DebugView for '[Upper] IOCTL_UPPER_SET_RECEIVE' messages" << std::endl;
} else {
DWORD ioctl_error = GetLastError();
std::cout << "❌ IOCTL failed: " << ioctl_error << std::endl;
switch (ioctl_error) {
case ERROR_INVALID_FUNCTION:
std::cout << " Driver doesn't support this IOCTL" << std::endl;
break;
case ERROR_INVALID_PARAMETER:
std::cout << " Invalid parameter - check data structure" << std::endl;
break;
case ERROR_INSUFFICIENT_BUFFER:
std::cout << " Buffer too small" << std::endl;
break;
default:
std::cout << " Unknown IOCTL error" << std::endl;
break;
}
}
} else if (cmd == "monitor") {
MonitorMouseData(hDevice);
} else if (cmd == "exit") {
break;
} else if (cmd == "status") {
std::cout << "📊 Device handle: " << hDevice << std::endl;
std::cout << "📊 IOCTL code: 0x" << std::hex << IOCTL_UPPER_SET_RECEIVE << std::dec << std::endl;
std::cout << "📊 Buffer size: " << 8 << " mouse events (reduced from 64)" << std::endl;
std::cout << "📊 Design: Simplified single IOCTL approach" << std::endl;
} else {
std::cout << "❓ Unknown command. Use 'on', 'off', 'monitor', 'status', or 'exit'." << std::endl;
}
}
std::cout << "📢 Check DebugView for '[Upper] Control device closed' message" << std::endl;
CloseHandle(hDevice);
return 0;
}