2
0

NativeAPIHelper.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using static WechatBakTool.Helpers.NativeAPI;
  9. namespace WechatBakTool.Helpers
  10. {
  11. public class NativeAPIHelper
  12. {
  13. // Managed native buffer
  14. internal static IntPtr AllocManagedMemory(uint iSize)
  15. {
  16. IntPtr pAlloc = Marshal.AllocHGlobal((int)iSize);
  17. RtlZeroMemory(pAlloc, iSize);
  18. return pAlloc;
  19. }
  20. // Free managed buffer
  21. internal static bool FreeManagedMemory(IntPtr pAlloc)
  22. {
  23. Marshal.FreeHGlobal(pAlloc);
  24. return true;
  25. }
  26. // Get an array of OBJECT_ALL_TYPES_INFORMATION, describing all object types
  27. // Win8+ only
  28. internal static string FindHandleName(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX systemHandleInformation, Process process)
  29. {
  30. IntPtr ipHandle = IntPtr.Zero;
  31. IntPtr openProcessHandle = IntPtr.Zero;
  32. IntPtr hObjectName = IntPtr.Zero;
  33. try
  34. {
  35. PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
  36. openProcessHandle = OpenProcess(flags, false, process.Id);
  37. // 通过 DuplicateHandle 访问句柄
  38. if (!DuplicateHandle(openProcessHandle, systemHandleInformation.HandleValue, GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS))
  39. {
  40. return "";
  41. }
  42. uint nLength = 0;
  43. hObjectName = AllocManagedMemory(256 * 1024);
  44. // 查询句柄名称
  45. while (NtQueryObject(ipHandle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength) == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
  46. {
  47. FreeManagedMemory(hObjectName);
  48. if (nLength == 0)
  49. {
  50. Console.WriteLine("Length returned at zero!");
  51. return "";
  52. }
  53. hObjectName = AllocManagedMemory(nLength);
  54. }
  55. OBJECT_NAME_INFORMATION? objObjectName = new OBJECT_NAME_INFORMATION();
  56. objObjectName = Marshal.PtrToStructure(hObjectName, objObjectName.GetType()) as OBJECT_NAME_INFORMATION?;
  57. if (objObjectName == null)
  58. return "";
  59. if (objObjectName.Value.Name.Buffer != IntPtr.Zero)
  60. {
  61. string? strObjectName = Marshal.PtrToStringUni(objObjectName.Value.Name.Buffer);
  62. if (strObjectName != null)
  63. return strObjectName;
  64. }
  65. }
  66. catch (Exception ex)
  67. {
  68. Console.WriteLine(ex.Message);
  69. }
  70. finally
  71. {
  72. FreeManagedMemory(hObjectName);
  73. CloseHandle(ipHandle);
  74. CloseHandle(openProcessHandle);
  75. }
  76. return "";
  77. }
  78. internal static List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> GetHandleInfoForPID(uint ProcId)
  79. {
  80. // Create return object
  81. List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> ltei = new List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX>();
  82. // Create Buffer variable
  83. IntPtr BuffPtr = IntPtr.Zero;
  84. // Loop till success
  85. uint LoopSize = 0;
  86. while (true)
  87. {
  88. BuffPtr = AllocManagedMemory(LoopSize);
  89. uint SystemInformationLength = 0;
  90. uint CallRes = NtQuerySystemInformation(SystemExtendedHandleInformation, BuffPtr, LoopSize, ref SystemInformationLength);
  91. if (CallRes == NTSTATUS_STATUS_INFO_LENGTH_MISMATCH)
  92. {
  93. FreeManagedMemory(BuffPtr);
  94. LoopSize = Math.Max(LoopSize, SystemInformationLength);
  95. }
  96. else if (CallRes == NTSTATUS_STATUS_SUCCESS)
  97. {
  98. break;
  99. }
  100. else if (CallRes == NTSTATUS_STATUS_ACCESS_DENIED)
  101. {
  102. FreeManagedMemory(BuffPtr);
  103. throw new AccessViolationException("[!] Failed to query SystemExtendedHandleInformation: Access Denied");
  104. }
  105. else
  106. {
  107. FreeManagedMemory(BuffPtr);
  108. throw new InvalidOperationException("[!] Failed to query SystemExtendedHandleInformation.");
  109. }
  110. }
  111. // Read handle count
  112. Int32 HandleCount = Marshal.ReadInt32(BuffPtr);
  113. // Move Buff ptr
  114. BuffPtr = (IntPtr)(BuffPtr.ToInt64() + (IntPtr.Size * 2));
  115. // Loop handles
  116. for (int i = 0; i < HandleCount; i++)
  117. {
  118. ulong iCurrProcId = (ulong)Marshal.ReadIntPtr((IntPtr)(BuffPtr.ToInt64() + IntPtr.Size));
  119. if (ProcId == iCurrProcId)
  120. {
  121. // Ptr -> SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
  122. SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX? tei = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX?)Marshal.PtrToStructure(BuffPtr, typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX));
  123. if (tei == null)
  124. continue;
  125. else
  126. ltei.Add(tei.Value);
  127. }
  128. // Move Buffptr
  129. BuffPtr = (IntPtr)(BuffPtr.ToInt64() + Marshal.SizeOf(typeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)));
  130. }
  131. // Return list
  132. return ltei;
  133. }
  134. }
  135. }