挂在NtQuerySystemInformation在WinXPx32,但在Win7x64工作良好

本文关键字:Win7x64 工作 但在 NtQuerySystemInformation WinXPx32 挂在 | 更新日期: 2023-09-27 18:10:07

我有一个类,可以让我关闭给定进程中的进程句柄。我已经掌握了基本原理,它在Win7 x64中运行完美,但当我在WinXP x86中运行它时,它挂起了,我不明白为什么。我觉得我在这里错过了一些相当明显的东西。

    public static List<handleFinder.SYSTEM_HANDLE_INFORMATION>
    GetHandles(Process process = null, string IN_strObjectTypeName = null, string IN_strObjectName = null)
    {
        int nLength = 0;
        int nHandleInfoSize = 0x10000;
        IntPtr ipHandle = IntPtr.Zero;
        IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
        uint nStatus;
        while ((nStatus = handleFinder.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer,nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
        {
            nHandleInfoSize = nLength;
            Marshal.FreeHGlobal(ipHandlePointer);
            ipHandlePointer = Marshal.AllocHGlobal(nLength);
        }
        byte[] baTemp = new byte[nLength];
        Marshal.Copy(ipHandlePointer, baTemp, 0, nLength);
        long lHandleCount = 0;
        if (Is64Bits())
        {
            lHandleCount = Marshal.ReadInt64(ipHandlePointer);
            ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
        }
        else
        {
            lHandleCount = Marshal.ReadInt32(ipHandlePointer);
            ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
        }
        handleFinder.SYSTEM_HANDLE_INFORMATION shHandle;
        List<handleFinder.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<handleFinder.SYSTEM_HANDLE_INFORMATION>();
        for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
        {
            shHandle = new handleFinder.SYSTEM_HANDLE_INFORMATION();
            if (Is64Bits())
            {
                shHandle = (handleFinder.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 = (handleFinder.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
            }
            if (process != null)
            {
                if (shHandle.ProcessID != process.Id) continue;
            }
            string strObjectTypeName = "";
            if (IN_strObjectTypeName != null)
            {
                strObjectTypeName = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
                if (strObjectTypeName != IN_strObjectTypeName) continue;
            }
            string strObjectName = "";
            if (IN_strObjectName != null)
            {
                strObjectName = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
                if (strObjectName != IN_strObjectName) continue;
            }
            lstHandles.Add(shHandle);
            string strObjectTypeName2 = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
            string strObjectName2 = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
            Console.WriteLine("{0}   {1}   {2}", shHandle.ProcessID, strObjectTypeName2, strObjectName2);
        }
        return lstHandles;
    }
    public static bool Is64Bits()
    {
        return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
    }
}
public class HandleKiller
{
    public static void doMurderHandle()
    {
        String ProcessName = "xboxstat";
        try
        {
            Process process = Process.GetProcessesByName(ProcessName)[0];
            var handles = Win32Processes.GetHandles(process, "File");
            if (handles.Count == 0) throw new System.ArgumentException("No handles found");
            foreach (var handle in handles)
            {
                IntPtr ipHandle = IntPtr.Zero;
                if (!handleFinder.DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, handleFinder.GetCurrentProcess(), out ipHandle, 0, false, handleFinder.DUPLICATE_CLOSE_SOURCE))
                    Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error());
                Console.WriteLine("Handle Killed!");
            }
        }
        catch (IndexOutOfRangeException)
        {
            Console.WriteLine("The process name '{0}' is not currently running", ProcessName);
        }
        catch (ArgumentException)
        {
            Console.WriteLine("The Handle '{0}' was not found in the process '{1}'", "", ProcessName);
        }
        Console.ReadLine();
    }
}
}

挂在NtQuerySystemInformation在WinXPx32,但在Win7x64工作良好

为了避免在遇到带有挂起等待操作的同步命名管道时发生死锁,请在重复句柄上调用CreateFileMapping()。

如果GetLastError()返回193 (ERROR_BAD_EXE_FORMAT),则句柄不是文件句柄,您应该跳过对文件名的查询。

与其他类型的测试命名管道的调用不同,CreateFileMapping()在内核中不会死锁。

ERROR_BAD_EXE_FORMAT——ZwCreateSection可能返回STATUS_INVALID_FILE_FOR_SECTION,它映射到用户错误代码。

见http://msdn.microsoft.com/en-us/library/windows/hardware/ff566428 (v = vs.85) . aspx同时http://support.microsoft.com/kb/113996