forked from CCob/MirrorDump
-
Notifications
You must be signed in to change notification settings - Fork 16
/
ProcessUtility.cs
116 lines (95 loc) · 4.7 KB
/
ProcessUtility.cs
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
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace MirrorDump {
/// <summary>
/// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry.htm?ts=0,242
/// https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process
/// </summary>
public class ProcessUtility {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_HANDLE_INFORMATION {
// Information Class 16
public int ProcessID;
public byte ObjectTypeNumber;
public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
public ushort Handle;
public int Object_Pointer;
public UInt32 GrantedAccess;
}
public class ProcessHandle {
public IntPtr Handle;
public Process Process;
}
[DllImport("kernel32.dll", SetLastError= true)]
public static extern uint GetProcessId(IntPtr handle);
[DllImport("ntdll.dll")]
public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
[DllImport("kernel32.dll", EntryPoint = "RtlCopyMemory")]
static extern void CopyMemory(byte[] Destination, IntPtr Source, uint Length);
private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
private const int OBJECT_TYPE_PROCESS = 0x7;
static bool Is64Bits() {
return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
}
static List<SYSTEM_HANDLE_INFORMATION> GetHandles(Process process, int? type) {
uint nStatus;
int nHandleInfoSize = 0x10000;
IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
int nLength = 0;
IntPtr ipHandle = IntPtr.Zero;
List<SYSTEM_HANDLE_INFORMATION> lstHandles = new List<SYSTEM_HANDLE_INFORMATION>();
while ((nStatus = NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH) {
nHandleInfoSize = nLength;
Marshal.FreeHGlobal(ipHandlePointer);
ipHandlePointer = Marshal.AllocHGlobal(nLength);
}
if(nStatus != 0) {
Console.WriteLine($"[!] Failed to query handle information with error 0x{nStatus:x}");
return lstHandles;
}
byte[] baTemp = new byte[nLength];
CopyMemory(baTemp, ipHandlePointer, (uint)nLength);
long lHandleCount = 0;
if (Is64Bits()) {
lHandleCount = Marshal.ReadInt32(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
} else {
lHandleCount = Marshal.ReadInt32(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
}
SYSTEM_HANDLE_INFORMATION shHandle;
for (long lIndex = 0; lIndex < lHandleCount; lIndex++) {
shHandle = new SYSTEM_HANDLE_INFORMATION();
if (Is64Bits()) {
shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
} else {
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
}
if (shHandle.ProcessID != process.Id) continue;
if(!type.HasValue)
lstHandles.Add(shHandle);
else if(type.Value == shHandle.ObjectTypeNumber)
lstHandles.Add(shHandle);
}
return lstHandles;
}
public static IEnumerable<ProcessHandle> GetProcessHandles(Process process) {
var processHandles = GetHandles(process, OBJECT_TYPE_PROCESS);
var result = new List<ProcessHandle>();
foreach(var item in processHandles) {
var procHandle = new ProcessHandle();
var procId = (int)GetProcessId((IntPtr)item.Handle);
procHandle.Handle = (IntPtr)item.Handle;
if (procId > 0)
procHandle.Process = Process.GetProcessById(procId);
result.Add(procHandle);
}
return result;
}
}
}