1
1
using System ;
2
2
using System . IO ;
3
3
using System . Runtime . InteropServices ;
4
+ using System . Runtime . Versioning ;
4
5
using System . Security . Principal ;
5
6
using System . Text ;
6
7
using Microsoft . Win32 . SafeHandles ;
@@ -10,6 +11,10 @@ namespace LockCheck.Windows
10
11
internal static class NativeMethods
11
12
{
12
13
private const string NtDll = "ntdll.dll" ;
14
+ private const string RestartManagerDll = "rstrtmgr.dll" ;
15
+ private const string AdvApi32Dll = "advapi32.dll" ;
16
+ private const string KernelDll = "kernel32.dll" ;
17
+ private const string PsApiDll = "psapi.dll" ;
13
18
14
19
[ StructLayout ( LayoutKind . Sequential , Pack = 0 ) ]
15
20
internal struct IO_STATUS_BLOCK
@@ -34,17 +39,31 @@ internal static extern uint NtQueryInformationFile(SafeFileHandle fileHandle, re
34
39
[ DllImport ( NtDll ) ]
35
40
internal static extern int RtlNtStatusToDosError ( uint status ) ;
36
41
42
+ [ DllImport ( NtDll ) ]
43
+ internal static extern int NtQueryInformationProcess ( SafeProcessHandle ProcessHandle , int ProcessInformationClass , ref PROCESS_BASIC_INFORMATION ProcessInformation , int ProcessInformationLength , IntPtr ReturnLength ) ;
44
+
45
+ [ DllImport ( NtDll ) ]
46
+ internal static extern int NtQueryInformationProcess ( SafeProcessHandle ProcessHandle , int ProcessInformationClass , ref IntPtr ProcessInformation , int ProcessInformationLength , IntPtr ReturnLength ) ;
47
+
48
+ [ DllImport ( NtDll ) ]
49
+ internal static extern int NtWow64QueryInformationProcess64 ( SafeProcessHandle ProcessHandle , int ProcessInformationClass , ref PROCESS_BASIC_INFORMATION_WOW64 ProcessInformation , int ProcessInformationLength , IntPtr ReturnLength ) ;
50
+
51
+ [ DllImport ( NtDll ) ]
52
+ internal static extern int NtWow64ReadVirtualMemory64 ( SafeProcessHandle hProcess , long lpBaseAddress , ref long lpBuffer , long dwSize , IntPtr lpNumberOfBytesRead ) ;
53
+
54
+ [ DllImport ( NtDll ) ]
55
+ internal static extern int NtWow64ReadVirtualMemory64 ( SafeProcessHandle hProcess , long lpBaseAddress , ref UNICODE_STRING_WOW64 lpBuffer , long dwSize , IntPtr lpNumberOfBytesRead ) ;
56
+
57
+ [ DllImport ( NtDll ) ]
58
+ internal static extern int NtWow64ReadVirtualMemory64 ( SafeProcessHandle hProcess , long lpBaseAddress , [ MarshalAs ( UnmanagedType . LPWStr ) ] string lpBuffer , long dwSize , IntPtr lpNumberOfBytesRead ) ;
59
+
37
60
internal const int ERROR_MR_MID_NOT_FOUND = 317 ;
38
61
39
62
internal const uint STATUS_SUCCESS = 0 ;
40
63
internal const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 ;
41
64
42
65
// ----------------------------------------------------------------------------------------------
43
66
44
- private const string RestartManagerDll = "rstrtmgr.dll" ;
45
- private const string AdvApi32Dll = "advapi32.dll" ;
46
- private const string KernelDll = "kernel32.dll" ;
47
-
48
67
[ DllImport ( RestartManagerDll , CharSet = CharSet . Unicode ) ]
49
68
internal static extern int RmRegisterResources ( uint pSessionHandle ,
50
69
uint nFiles ,
@@ -174,7 +193,7 @@ internal static extern bool OpenProcessToken(SafeProcessHandle processHandle,
174
193
internal const int PROCESS_VM_WRITE = 0x20 ;
175
194
176
195
[ DllImport ( KernelDll , SetLastError = true ) ]
177
- private static extern SafeProcessHandle OpenProcess ( int dwDesiredAccess , bool bInheritHandle , int dwProcessId ) ;
196
+ internal static extern SafeProcessHandle OpenProcess ( int dwDesiredAccess , bool bInheritHandle , int dwProcessId ) ;
178
197
179
198
internal static SafeProcessHandle OpenProcessLimited ( int pid )
180
199
{
@@ -211,6 +230,22 @@ internal static DateTime GetProcessStartTime(SafeProcessHandle handle)
211
230
[ DllImport ( KernelDll , SetLastError = true ) ]
212
231
private static extern bool ProcessIdToSessionId ( int dwProcessId , out int sessionId ) ;
213
232
233
+ [ DllImport ( KernelDll , SetLastError = true ) ]
234
+ internal static extern bool ReadProcessMemory ( SafeProcessHandle hProcess , IntPtr lpBaseAddress , ref IntPtr lpBuffer , IntPtr dwSize , IntPtr lpNumberOfBytesRead ) ;
235
+
236
+ [ DllImport ( KernelDll , SetLastError = true ) ]
237
+ internal static extern bool ReadProcessMemory ( SafeProcessHandle hProcess , IntPtr lpBaseAddress , ref UNICODE_STRING lpBuffer , IntPtr dwSize , IntPtr lpNumberOfBytesRead ) ;
238
+
239
+ [ DllImport ( KernelDll , SetLastError = true ) ]
240
+ internal static extern bool ReadProcessMemory ( SafeProcessHandle hProcess , IntPtr lpBaseAddress , ref UNICODE_STRING_32 lpBuffer , IntPtr dwSize , IntPtr lpNumberOfBytesRead ) ;
241
+
242
+ [ DllImport ( KernelDll , SetLastError = true ) ]
243
+ internal static extern bool ReadProcessMemory ( SafeProcessHandle hProcess , IntPtr lpBaseAddress , [ MarshalAs ( UnmanagedType . LPWStr ) ] string lpBuffer , IntPtr dwSize , IntPtr lpNumberOfBytesRead ) ;
244
+
245
+ [ DllImport ( KernelDll , SetLastError = true , CallingConvention = CallingConvention . Winapi ) ]
246
+ [ return : MarshalAs ( UnmanagedType . Bool ) ]
247
+ internal static extern bool IsWow64Process ( [ In ] SafeProcessHandle processHandle , [ Out , MarshalAs ( UnmanagedType . Bool ) ] out bool wow64Process ) ;
248
+
214
249
internal static int GetProcessSessionId ( int dwProcessId )
215
250
{
216
251
if ( ProcessIdToSessionId ( dwProcessId , out int sessionId ) )
@@ -308,5 +343,111 @@ internal static SafeFileHandle GetFileHandle(string name)
308
343
( int ) FileAttributes . Normal ,
309
344
IntPtr . Zero ) ;
310
345
}
346
+
347
+ [ DllImport ( PsApiDll , CharSet = CharSet . Auto , SetLastError = true ) ]
348
+ [ ResourceExposure ( ResourceScope . Machine ) ]
349
+ public static extern bool EnumProcesses ( int [ ] processIds , int size , out int needed ) ;
350
+
351
+ internal static int [ ] GetProcessIds ( )
352
+ {
353
+ int [ ] processIds = new int [ 256 ] ;
354
+ int size ;
355
+
356
+ for ( ; ; )
357
+ {
358
+ if ( ! EnumProcesses ( processIds , processIds . Length * 4 , out size ) )
359
+ {
360
+ return Array . Empty < int > ( ) ;
361
+ }
362
+
363
+ if ( size == processIds . Length * 4 )
364
+ {
365
+ processIds = new int [ processIds . Length * 2 ] ;
366
+ continue ;
367
+ }
368
+
369
+ break ;
370
+ }
371
+
372
+ int [ ] ids = new int [ size / 4 ] ;
373
+ Array . Copy ( processIds , ids , ids . Length ) ;
374
+
375
+ return ids ;
376
+ }
377
+
378
+ [ StructLayout ( LayoutKind . Sequential ) ]
379
+ internal struct UNICODE_STRING_32
380
+ {
381
+ public short Length ;
382
+ public short MaximumLength ;
383
+ public int Buffer ;
384
+ }
385
+
386
+ [ StructLayout ( LayoutKind . Sequential ) ]
387
+ internal struct UNICODE_STRING
388
+ {
389
+ public short Length ;
390
+ public short MaximumLength ;
391
+ public IntPtr Buffer ;
392
+ }
393
+
394
+ // for 32-bit process
395
+ [ StructLayout ( LayoutKind . Sequential ) ]
396
+ internal struct UNICODE_STRING_WOW64
397
+ {
398
+ public short Length ;
399
+ public short MaximumLength ;
400
+ public long Buffer ;
401
+ }
402
+
403
+ internal enum PROCESSINFOCLASS : int
404
+ {
405
+ ProcessBasicInformation = 0 , // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
406
+ ProcessWow64Information = 26 , // q: ULONG_PTR
407
+ }
408
+
409
+ [ StructLayout ( LayoutKind . Sequential ) ]
410
+ internal struct PROCESS_BASIC_INFORMATION
411
+ {
412
+ public IntPtr Reserved1 ;
413
+ public IntPtr PebBaseAddress ;
414
+ public IntPtr Reserved2_0 ;
415
+ public IntPtr Reserved2_1 ;
416
+ public IntPtr UniqueProcessId ;
417
+ public IntPtr Reserved3 ;
418
+ }
419
+
420
+ // for 32-bit process in a 64-bit OS only
421
+ [ StructLayout ( LayoutKind . Sequential ) ]
422
+ internal struct PROCESS_BASIC_INFORMATION_WOW64
423
+ {
424
+ public long Reserved1 ;
425
+ public long PebBaseAddress ;
426
+ public long Reserved2_0 ;
427
+ public long Reserved2_1 ;
428
+ public long UniqueProcessId ;
429
+ public long Reserved3 ;
430
+ }
431
+
432
+ internal static bool GetProcessIsWow64 ( SafeProcessHandle hProcess )
433
+ {
434
+ if ( ( OSVersion . Major == 5 && OSVersion . Minor >= 1 ) || OSVersion . Major >= 6 )
435
+ {
436
+ if ( ! IsWow64Process ( hProcess , out bool retVal ) )
437
+ {
438
+ return false ;
439
+ }
440
+
441
+ return retVal ;
442
+ }
443
+ else
444
+ {
445
+ return false ;
446
+ }
447
+ }
448
+
449
+ internal static readonly Version OSVersion = Environment . OSVersion . Version ;
450
+ internal static readonly bool Is64BitOperatingSystem = Environment . Is64BitOperatingSystem ;
451
+ internal static readonly bool IsCurrentProcessWOW64 = Environment . Is64BitOperatingSystem && ! Environment . Is64BitProcess ;
311
452
}
312
453
}
0 commit comments