gpt4 book ai didi

C# 获取句柄列表,AcessViolationException

转载 作者:太空宇宙 更新时间:2023-11-03 15:14:23 24 4
gpt4 key购买 nike

信息:

  • .Net 4.5

测试于:

  • Win7 64 位

  • Win10 64 位(虚拟盒子)

我正在尝试获取一个外部进程的句柄列表,并将它们的名称作为字符串返回,这样我就可以在之后关闭一个特定的进程。因此我使用 Win32API 编写了这个函数,它将检查句柄是否是我想要关闭的句柄:`

        const int CNST_SYSTEM_HANDLE_INFORMATION = 16;
const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;

public static string getObjectTypeName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process)
{
IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);
IntPtr ipHandle = IntPtr.Zero;
var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
IntPtr ipBasic = IntPtr.Zero;
var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();
IntPtr ipObjectType = IntPtr.Zero;
IntPtr ipObjectName = IntPtr.Zero;
string strObjectTypeName = "";
int nLength = 0;
int nReturn = 0;
IntPtr ipTemp = IntPtr.Zero;


if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle,
Win32API.GetCurrentProcess(), out ipHandle,
0, false, Win32API.DUPLICATE_SAME_ACCESS))
return null;



ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation,
ipBasic, Marshal.SizeOf(objBasic), ref nLength);
objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
Marshal.FreeHGlobal(ipBasic);

ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);
nLength = objBasic.TypeInformationLength;
while ((uint)(nReturn = Win32API.NtQueryObject(
ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType,
nLength, ref nLength)) ==
Win32API.STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(ipObjectType);
ipObjectType = Marshal.AllocHGlobal(nLength);
}

objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());
if (Is64Bits())
{
ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32);
}
else
{
ipTemp = objObjectType.Name.Buffer;
}

strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);


Marshal.FreeHGlobal(ipObjectType);
Win32API.CloseHandle(ipHandle);
return strObjectTypeName;
}`

但问题是这段代码在 Win7 64 位中有效,在 Win10 中无效! --> 在 Win 10 中 strObjectTypeName = Marshal.PtrToStringUni(); 抛出一个 AcessViolationException(代码中的最后几行)

System.AccessViolationException Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

我是否遗漏了有关在 win10 中必须如何访问非托管内存的内容?

最佳答案

我刚遇到同样的问题。我没有尝试过 Win7,但是当您在 Win10(x64) 上以 32 位运行代码时(例如,设置应用程序的“首选 32 位标志”)它应该可以工作。当异常发生时,将变量“ipTemp”拖放到Visual Studio的“内存窗口”中,如果它只显示问号或错误消息则您没有有效的指针。据我所知,此 API 使用的结构的 64 位版本中有(更多)填充字节:OBJECT_TYPE_INFORMATION 包含一个 UNICODE_STRING 并且 UNICODE_STRING 在 64 位模式的缓冲区字段之前有 4 个填充字节。我的解决方法是:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct UNICODE_STRING
{
private IntPtr _dummy; // the two ushorts seem to be padded with 4 bytes in 64bit mode only

/// <summary>
/// The length, in bytes, of the string stored in Buffer. If the string is null-terminated, Length does not include the trailing null character.
/// </summary>
public ushort Length
{
get { return (ushort)Marshal.ReadInt16(this, 0); }
}

/// <summary>
/// The length, in bytes, of Buffer.
/// </summary>
public ushort MaximumLength
{
get { return (ushort)Marshal.ReadInt16(this, 2); }
}

public IntPtr Buffer;
}

在我的研究过程中,我发现了很多关于这个主题的问题,基本上有两种示例代码我正在考虑创建一个名为 WinKernelObjectsDotNet 的开源库。

更新:库现已可用here .它支持使用一行代码查找锁定文件或串行端口 (COM) 的进程。

关于C# 获取句柄列表,AcessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39593458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com