2
0

ProcessHelper.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Net.NetworkInformation;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. namespace WechatPCMsgBakTool.Helpers
  11. {
  12. public class ProcessHelper
  13. {
  14. private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
  15. private const int DUPLICATE_CLOSE_SOURCE = 0x1;
  16. private const int DUPLICATE_SAME_ACCESS = 0x2;
  17. private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
  18. private const int OBJECT_TYPE_MUTANT = 17;
  19. public static Process GetProcess(string ProcessName)
  20. {
  21. Process[] processes = Process.GetProcessesByName(ProcessName);
  22. if (processes.Length == 0)
  23. return null;
  24. else if(processes.Length > 1) {
  25. SelectWechat selectWechat = new SelectWechat();
  26. MessageBox.Show("检测到有多个微信,请选择本工作区对应的微信");
  27. selectWechat.ShowDialog();
  28. if (selectWechat.SelectProcess == null)
  29. return null;
  30. Process? p = processes.ToList().Find(x => x.Id.ToString() == selectWechat.SelectProcess.ProcessId);
  31. if (p == null)
  32. return null;
  33. return p;
  34. }
  35. else
  36. return processes[0];
  37. }
  38. public static ProcessModule? FindProcessModule(int ProcessId, string ModuleName)
  39. {
  40. Process process = Process.GetProcessById(ProcessId);
  41. foreach (ProcessModule module in process.Modules)
  42. {
  43. if (module.ModuleName == ModuleName)
  44. return module;
  45. }
  46. return null;
  47. }
  48. public static List<SYSTEM_HANDLE_INFORMATION> GetHandles(Process process)
  49. {
  50. List<SYSTEM_HANDLE_INFORMATION> aHandles = new List<SYSTEM_HANDLE_INFORMATION>();
  51. int handle_info_size = Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()) * 20000;
  52. IntPtr ptrHandleData = IntPtr.Zero;
  53. try
  54. {
  55. ptrHandleData = Marshal.AllocHGlobal(handle_info_size);
  56. int nLength = 0;
  57. while (NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ptrHandleData, handle_info_size, ref nLength) == STATUS_INFO_LENGTH_MISMATCH)
  58. {
  59. handle_info_size = nLength;
  60. Marshal.FreeHGlobal(ptrHandleData);
  61. ptrHandleData = Marshal.AllocHGlobal(nLength);
  62. }
  63. long handle_count = Marshal.ReadIntPtr(ptrHandleData).ToInt64();
  64. IntPtr ptrHandleItem = ptrHandleData + Marshal.SizeOf(ptrHandleData);
  65. for (long lIndex = 0; lIndex < handle_count; lIndex++)
  66. {
  67. SYSTEM_HANDLE_INFORMATION? oSystemHandleInfo = new SYSTEM_HANDLE_INFORMATION();
  68. oSystemHandleInfo = Marshal.PtrToStructure(ptrHandleItem, oSystemHandleInfo.GetType()) as SYSTEM_HANDLE_INFORMATION?;
  69. if (oSystemHandleInfo == null)
  70. throw new Exception("获取SYSTEM_HANDLE_INFORMATION失败");
  71. ptrHandleItem += Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION());
  72. if (oSystemHandleInfo.Value.ProcessID != process.Id) { continue; }
  73. aHandles.Add(oSystemHandleInfo.Value);
  74. }
  75. }
  76. catch (Exception)
  77. {
  78. throw;
  79. }
  80. finally
  81. {
  82. Marshal.FreeHGlobal(ptrHandleData);
  83. }
  84. return aHandles;
  85. }
  86. public static string FindHandleName(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process)
  87. {
  88. IntPtr ipHandle = IntPtr.Zero;
  89. IntPtr openProcessHandle = IntPtr.Zero;
  90. IntPtr hObjectName = IntPtr.Zero;
  91. try
  92. {
  93. PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
  94. openProcessHandle = OpenProcess(flags, false, process.Id);
  95. // 通过 DuplicateHandle 访问句柄
  96. if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS))
  97. {
  98. return "";
  99. }
  100. int nLength = 0;
  101. hObjectName = Marshal.AllocHGlobal(256 * 1024);
  102. // 查询句柄名称
  103. while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
  104. {
  105. Marshal.FreeHGlobal(hObjectName);
  106. if (nLength == 0)
  107. {
  108. Console.WriteLine("Length returned at zero!");
  109. return "";
  110. }
  111. hObjectName = Marshal.AllocHGlobal(nLength);
  112. }
  113. OBJECT_NAME_INFORMATION? objObjectName = new OBJECT_NAME_INFORMATION();
  114. objObjectName = Marshal.PtrToStructure(hObjectName, objObjectName.GetType()) as OBJECT_NAME_INFORMATION?;
  115. if (objObjectName == null)
  116. return "";
  117. if (objObjectName.Value.Name.Buffer != IntPtr.Zero)
  118. {
  119. string? strObjectName = Marshal.PtrToStringUni(objObjectName.Value.Name.Buffer);
  120. if (strObjectName != null)
  121. return strObjectName;
  122. }
  123. }
  124. catch (Exception ex)
  125. {
  126. Console.WriteLine(ex.Message);
  127. }
  128. finally
  129. {
  130. Marshal.FreeHGlobal(hObjectName);
  131. CloseHandle(ipHandle);
  132. CloseHandle(openProcessHandle);
  133. }
  134. return "";
  135. }
  136. // 这里开始下面是对Windows API引用声明
  137. public static byte[]? ReadMemoryDate(IntPtr hProcess, IntPtr lpBaseAddress, int nSize = 100)
  138. {
  139. byte[] array = new byte[nSize];
  140. if (ReadProcessMemory(hProcess, lpBaseAddress, array, nSize, 0) == 0)
  141. return null;
  142. else
  143. return array;
  144. }
  145. [DllImport("kernel32.dll")]
  146. public static extern int ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, int lpNumberOfBytesRead);
  147. [DllImport("ntdll.dll")]
  148. private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
  149. [DllImport("kernel32.dll")]
  150. private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
  151. [DllImport("kernel32.dll", SetLastError = true)]
  152. [return: MarshalAs(UnmanagedType.Bool)]
  153. private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
  154. [DllImport("kernel32.dll")]
  155. private static extern IntPtr GetCurrentProcess();
  156. [DllImport("ntdll.dll")]
  157. private static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
  158. [DllImport("kernel32.dll")]
  159. private static extern bool CloseHandle(IntPtr hObject);
  160. [DllImport("kernel32.dll")]
  161. private static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags);
  162. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  163. public struct SYSTEM_HANDLE_INFORMATION
  164. { // Information Class 16
  165. public ushort ProcessID;
  166. public ushort CreatorBackTrackIndex;
  167. public byte ObjectType;
  168. public byte HandleAttribute;
  169. public ushort Handle;
  170. public IntPtr Object_Pointer;
  171. public IntPtr AccessMask;
  172. }
  173. private enum OBJECT_INFORMATION_CLASS : int
  174. {
  175. ObjectBasicInformation = 0,
  176. ObjectNameInformation = 1,
  177. ObjectTypeInformation = 2,
  178. ObjectAllTypesInformation = 3,
  179. ObjectHandleInformation = 4
  180. }
  181. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  182. private struct OBJECT_NAME_INFORMATION
  183. {
  184. public UNICODE_STRING Name;
  185. }
  186. [StructLayout(LayoutKind.Sequential)]
  187. private struct UNICODE_STRING
  188. {
  189. public ushort Length;
  190. public ushort MaximumLength;
  191. public IntPtr Buffer;
  192. }
  193. [Flags]
  194. private enum PROCESS_ACCESS_FLAGS : uint
  195. {
  196. All = 0x001F0FFF,
  197. Terminate = 0x00000001,
  198. CreateThread = 0x00000002,
  199. VMOperation = 0x00000008,
  200. VMRead = 0x00000010,
  201. VMWrite = 0x00000020,
  202. DupHandle = 0x00000040,
  203. SetInformation = 0x00000200,
  204. QueryInformation = 0x00000400,
  205. Synchronize = 0x00100000
  206. }
  207. }
  208. }