-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNativeHelper.cs
More file actions
412 lines (336 loc) · 14.6 KB
/
Copy pathNativeHelper.cs
File metadata and controls
412 lines (336 loc) · 14.6 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
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace WinTombstone
{
public static class NativeHelper
{
// ================== 进程路径获取 ==================
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, int dwFlags, StringBuilder lpExeName, ref int lpdwSize);
public const uint PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
public static string GetRealProcessPath(int processId)
{
try
{
IntPtr hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, processId);
if (hProcess != IntPtr.Zero)
{
try
{
StringBuilder buffer = new StringBuilder(1024);
int size = buffer.Capacity;
if (QueryFullProcessImageName(hProcess, 0, buffer, ref size))
{
return buffer.ToString();
}
}
finally
{
CloseHandle(hProcess);
}
}
return System.Diagnostics.Process.GetProcessById(processId).MainModule?.FileName;
}
catch
{
return null;
}
}
// ================== Windows 原生挂起/恢复 ==================
[DllImport("ntdll.dll", PreserveSig = false)]
public static extern void NtSuspendProcess(IntPtr processHandle);
[DllImport("ntdll.dll", PreserveSig = false)]
public static extern void NtResumeProcess(IntPtr processHandle);
// ================== 窗口操作 ==================
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
public const int SW_HIDE = 0;
public const int SW_SHOW = 5;
public const int SW_RESTORE = 9;
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public Point ptMinPosition;
public Point ptMaxPosition;
public RECT rcNormalPosition;
}
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public int X;
public int Y;
}
// ================== 进程树查找 ==================
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
private const uint TH32CS_SNAPPROCESS = 0x00000002;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
}
public static Dictionary<int, List<int>> GetProcessParentChildrenMap()
{
var map = new Dictionary<int, List<int>>();
IntPtr handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (handle == IntPtr.Zero) return map;
try
{
PROCESSENTRY32 pe = new PROCESSENTRY32();
pe.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
if (Process32First(handle, ref pe))
{
do
{
int parentId = (int)pe.th32ParentProcessID;
int childId = (int)pe.th32ProcessID;
if (!map.ContainsKey(parentId))
map[parentId] = new List<int>();
map[parentId].Add(childId);
} while (Process32Next(handle, ref pe));
}
}
finally
{
CloseHandle(handle);
}
return map;
}
public const uint PROCESS_ALL_ACCESS = 0x1FFFFF;
// ================== Job Object 冻结机制 ==================
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateJobObjectW(IntPtr lpJobAttributes, string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetInformationJobObject(IntPtr hJob, int JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
public const int JobObjectFreezeInformation = 18;
[StructLayout(LayoutKind.Sequential, Size = 16)]
public struct JOBOBJECT_FREEZE_INFORMATION
{
public uint Flags;
public byte Freeze;
public byte Swap;
public ushort Spare;
public uint WakeFilterHigh;
public uint WakeFilterLow;
}
public static bool JobFreeze(IntPtr hJob, bool freeze)
{
var info = new JOBOBJECT_FREEZE_INFORMATION();
info.Flags = 1;
info.Freeze = (byte)(freeze ? 1 : 0);
info.Swap = 0;
int size = 16;
IntPtr pInfo = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(info, pInfo, false);
return SetInformationJobObject(hJob, JobObjectFreezeInformation, pInfo, (uint)size);
}
finally
{
Marshal.FreeHGlobal(pInfo);
}
}
// ================== 鼠标捕获释放 ==================
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ClipCursor(IntPtr lpRect);
[DllImport("user32.dll")]
public static extern int ShowCursor(bool bShow);
[DllImport("user32.dll")]
public static extern IntPtr SetCursor(IntPtr hCursor);
[DllImport("user32.dll")]
public static extern IntPtr LoadCursor(IntPtr hInstance, uint lpCursorName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern IntPtr GetCapture();
public const uint IDC_ARROW = 32512;
public const int CURSOR_SHOWING = 0x00000001;
[DllImport("user32.dll")]
public static extern bool GetCursorInfo(ref CURSORINFO pci);
[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
public int cbSize;
public int flags;
public IntPtr hCursor;
public Point ptScreenPos;
}
public static void ForceReleaseMouse()
{
try
{
IntPtr captured = GetCapture();
if (captured != IntPtr.Zero)
ReleaseCapture();
ClipCursor(IntPtr.Zero);
CURSORINFO ci = new CURSORINFO();
ci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(ref ci))
{
if ((ci.flags & CURSOR_SHOWING) == 0)
{
while (ShowCursor(true) < 0) { }
}
}
SetCursor(LoadCursor(IntPtr.Zero, IDC_ARROW));
}
catch { }
}
// ================== 原有辅助方法 ==================
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint nFlags);
public const uint PW_RENDERFULLCONTENT = 0x00000002;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public int Width => Right - Left;
public int Height => Bottom - Top;
}
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public const uint SWP_NOSIZE = 0x0001;
public const uint SWP_NOMOVE = 0x0002;
public const uint SWP_NOZORDER = 0x0004;
public const uint SWP_NOACTIVATE = 0x0010;
public const uint SWP_SHOWWINDOW = 0x0040;
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
public const uint GW_HWNDPREV = 3;
public const uint GW_OWNER = 4;
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_APPWINDOW = 0x00040000;
public const int WS_EX_TOOLWINDOW = 0x00000080;
public static bool IsTaskbarWindow(IntPtr hWnd)
{
if (!IsWindowVisible(hWnd)) return false;
int exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
if ((exStyle & WS_EX_APPWINDOW) != 0) return true;
if ((exStyle & WS_EX_TOOLWINDOW) != 0) return false;
if (GetWindow(hWnd, GW_OWNER) != IntPtr.Zero) return false;
return true;
}
public static List<IntPtr> GetVisibleWindowsForProcess(int processId)
{
List<IntPtr> handles = new List<IntPtr>();
EnumWindows(delegate (IntPtr hWnd, IntPtr lParam)
{
GetWindowThreadProcessId(hWnd, out uint pid);
if (pid == processId && IsWindowVisible(hWnd))
{
GetWindowRect(hWnd, out RECT r);
if (r.Right - r.Left != 0 || r.Bottom - r.Top != 0)
{
handles.Add(hWnd);
}
}
return true;
}, IntPtr.Zero);
return handles;
}
// ================== SeDebugPrivilege 提权 ==================
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out long lpLuid);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint BufferLength, IntPtr PreviousState, IntPtr ReturnLength);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
public long Luid;
public int Attributes;
}
private const int SE_PRIVILEGE_ENABLED = 0x00000002;
private const uint TOKEN_ADJUST_PRIVILEGES = 0x0020;
private const uint TOKEN_QUERY = 0x0008;
public static bool EnableDebugPrivilege()
{
IntPtr hToken = IntPtr.Zero;
try
{
if (!OpenProcessToken(System.Diagnostics.Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken))
return false;
TOKEN_PRIVILEGES tp = new TOKEN_PRIVILEGES();
tp.PrivilegeCount = 1;
tp.Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValue(null, "SeDebugPrivilege", out tp.Luid))
return false;
if (!AdjustTokenPrivileges(hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero))
return false;
return Marshal.GetLastWin32Error() == 0;
}
catch
{
return false;
}
finally
{
if (hToken != IntPtr.Zero) CloseHandle(hToken);
}
}
}
}