-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDriverLoader.cs
More file actions
279 lines (232 loc) · 8.53 KB
/
DriverLoader.cs
File metadata and controls
279 lines (232 loc) · 8.53 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
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Threading;
public static class DriverLoader
{
private const string DRIVER_ID = "WinRing0_1_2_0";
private static readonly string DriverPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WinRing0x64.sys");
private const int MaxRetry = 2;
public static void InitializeDriver()
{
StringBuilder report = new StringBuilder();
for (int i = 0; i < MaxRetry; i++)
{
if (TryOpenDriver())
{
report.AppendLine("驱动已加载并可打开。");
break;
}
if (!File.Exists(DriverPath))
{
report.AppendLine("驱动文件不存在:" + DriverPath);
break;
}
report.AppendLine($"第 {i + 1} 次尝试安装驱动...");
string error;
if (!InstallDriver(DriverPath, out error))
{
report.AppendLine("安装失败:" + error);
DeleteDriverService();
Thread.Sleep(2000);
continue;
}
Thread.Sleep(1000); // 等待驱动加载
if (TryOpenDriver())
{
report.AppendLine("驱动安装并打开成功。");
break;
}
else
{
report.AppendLine("安装成功但无法打开,准备删除后重试...");
DeleteDriverService();
Thread.Sleep(2000);
}
}
Console.WriteLine(report.ToString());
}
private static bool TryOpenDriver()
{
SafeFileHandle handle = new SafeFileHandle(NativeMethods.CreateFile(@"\\.\" + DRIVER_ID,
FileAccessFlags.GENERIC_READ | FileAccessFlags.GENERIC_WRITE, 0, IntPtr.Zero,
CreationDisposition.OPEN_EXISTING, FileAttributesFlags.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero), true);
if (handle.IsInvalid)
{
handle.Dispose();
return false;
}
try
{
FileSecurity security = File.GetAccessControl(@"\\.\" + DRIVER_ID);
return true;
}
catch
{
return false;
}
}
private static bool InstallDriver(string path, out string errorMessage)
{
IntPtr manager = NativeMethods.OpenSCManager(null, null,
ServiceControlManagerAccessRights.SC_MANAGER_ALL_ACCESS);
if (manager == IntPtr.Zero)
{
errorMessage = "OpenSCManager 返回 NULL。";
return false;
}
IntPtr service = NativeMethods.CreateService(manager, DRIVER_ID, DRIVER_ID,
ServiceAccessRights.SERVICE_ALL_ACCESS,
ServiceType.SERVICE_KERNEL_DRIVER, StartType.SERVICE_SYSTEM_START,
ErrorControl.SERVICE_ERROR_NORMAL, path, null, null, null, null, null);
if (service == IntPtr.Zero)
{
int hr = Marshal.GetHRForLastWin32Error();
if (hr == ERROR_SERVICE_EXISTS)
{
errorMessage = "服务已存在。";
NativeMethods.CloseServiceHandle(manager);
return false;
}
else
{
errorMessage = "CreateService 错误: " +
Marshal.GetExceptionForHR(hr).Message;
NativeMethods.CloseServiceHandle(manager);
return false;
}
}
if (!NativeMethods.StartService(service, 0, null))
{
int hr = Marshal.GetHRForLastWin32Error();
if (hr != ERROR_SERVICE_ALREADY_RUNNING)
{
errorMessage = "StartService 错误: " +
Marshal.GetExceptionForHR(hr).Message;
NativeMethods.CloseServiceHandle(service);
NativeMethods.CloseServiceHandle(manager);
return false;
}
}
NativeMethods.CloseServiceHandle(service);
NativeMethods.CloseServiceHandle(manager);
try
{
FileSecurity fileSecurity = File.GetAccessControl(@"\\.\" + DRIVER_ID);
fileSecurity.SetSecurityDescriptorSddlForm("O:BAG:SYD:(A;;FA;;;SY)(A;;FA;;;BA)");
File.SetAccessControl(@"\\.\" + DRIVER_ID, fileSecurity);
}
catch { }
errorMessage = null;
return true;
}
private static void DeleteDriverService()
{
IntPtr manager = NativeMethods.OpenSCManager(null, null,
ServiceControlManagerAccessRights.SC_MANAGER_ALL_ACCESS);
if (manager == IntPtr.Zero)
return;
IntPtr service = NativeMethods.OpenService(manager, DRIVER_ID,
ServiceAccessRights.SERVICE_ALL_ACCESS);
if (service == IntPtr.Zero)
{
NativeMethods.CloseServiceHandle(manager);
return;
}
ServiceStatus status = new ServiceStatus();
NativeMethods.ControlService(service, ServiceControl.SERVICE_CONTROL_STOP, ref status);
NativeMethods.DeleteService(service);
NativeMethods.CloseServiceHandle(service);
NativeMethods.CloseServiceHandle(manager);
}
#region Native and Structs
private enum ServiceAccessRights : uint
{
SERVICE_ALL_ACCESS = 0xF01FF
}
private enum ServiceControlManagerAccessRights : uint
{
SC_MANAGER_ALL_ACCESS = 0xF003F
}
private enum ServiceType : uint
{
SERVICE_KERNEL_DRIVER = 1
}
private enum StartType : uint
{
SERVICE_SYSTEM_START = 1
}
private enum ErrorControl : uint
{
SERVICE_ERROR_NORMAL = 1
}
private enum ServiceControl : uint
{
SERVICE_CONTROL_STOP = 1
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct ServiceStatus
{
public uint dwServiceType;
public uint dwCurrentState;
public uint dwControlsAccepted;
public uint dwWin32ExitCode;
public uint dwServiceSpecificExitCode;
public uint dwCheckPoint;
public uint dwWaitHint;
}
private enum FileAccessFlags : uint
{
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000
}
private enum CreationDisposition : uint
{
OPEN_EXISTING = 3
}
private enum FileAttributesFlags : uint
{
FILE_ATTRIBUTE_NORMAL = 0x80
}
private const int
ERROR_SERVICE_EXISTS = unchecked((int)0x80070431),
ERROR_SERVICE_ALREADY_RUNNING = unchecked((int)0x80070420);
private static class NativeMethods
{
private const string ADVAPI = "advapi32.dll";
private const string KERNEL = "kernel32.dll";
[DllImport(ADVAPI, SetLastError = true)]
public static extern IntPtr OpenSCManager(string machineName,
string databaseName, ServiceControlManagerAccessRights dwAccess);
[DllImport(ADVAPI)]
public static extern bool CloseServiceHandle(IntPtr hSCObject);
[DllImport(ADVAPI, SetLastError = true)]
public static extern IntPtr CreateService(IntPtr hSCManager,
string lpServiceName, string lpDisplayName,
ServiceAccessRights dwDesiredAccess, ServiceType dwServiceType,
StartType dwStartType, ErrorControl dwErrorControl,
string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId,
string lpDependencies, string lpServiceStartName, string lpPassword);
[DllImport(ADVAPI, SetLastError = true)]
public static extern IntPtr OpenService(IntPtr hSCManager,
string lpServiceName, ServiceAccessRights dwDesiredAccess);
[DllImport(ADVAPI, SetLastError = true)]
public static extern bool DeleteService(IntPtr hService);
[DllImport(ADVAPI, SetLastError = true)]
public static extern bool StartService(IntPtr hService,
uint dwNumServiceArgs, string[] lpServiceArgVectors);
[DllImport(ADVAPI, SetLastError = true)]
public static extern bool ControlService(IntPtr hService,
ServiceControl dwControl, ref ServiceStatus lpServiceStatus);
[DllImport(KERNEL, SetLastError = true)]
public static extern IntPtr CreateFile(string lpFileName,
FileAccessFlags dwDesiredAccess, uint dwShareMode,
IntPtr lpSecurityAttributes, CreationDisposition dwCreationDisposition,
FileAttributesFlags dwFlagsAndAttributes, IntPtr hTemplateFile);
}
#endregion
}