gpt4 book ai didi

c# - .NET Framework 4.5 或更高版本中的 AccessViolationException

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

我正在尝试运行在互联网上找到的 .NET C# 控制台应用程序(articlecode)。

它使用一些 pInvoke 调用,并在某些时候触发 Marshal.PtrToStringUni(IntPtr ptr, int len)

非常奇怪,而且我无法修复的是:

  • 如果我将项目编译为 .NET Framework 4.0,它就可以工作。
  • 在 .NET Framework 4.5 或更高版本下,它会抛出 AccessViolationException(臭名昭著的“试图读取或写入 protected 内存。这通常表明其他内存已损坏。”)

堆栈跟踪告诉我:

at System.Buffer.Memmove(Byte* dest, Byte* src, UInt64 len) at System.String.CtorCharPtrStartLength(Char* ptr, Int32 startIndex, Int32 length) at System.Runtime.InteropServices.Marshal.PtrToStringUni(IntPtr ptr, Int32 len)

我在网上搜索了几个小时,看到了类似的问题,但没有任何帮助。我绝对需要在我的项目中实现这个功能,并且觉得在.Net Framework 4.0 中编译这部分而其余部分在更高版本中可能会在未来带来一些麻烦。无论如何,必须有一种方法让它发挥作用。

有没有办法让这段代码工作?

编辑:我刚刚更新了链接“代码”。作者刚刚提交了一个新版本。

编辑 2:我知道这里没有直接的代码不会让人想要提供帮助。我认为链接到列出重要部分的文章会更有效率。

所以这里有一些上下文和一些代码:

该代码旨在列出进程锁定的所有文件。它首先获取 SYSTEM_HANDLE_INFORMATION 列表。这是结构:

 [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public int ProcessID;
public byte ObjectTypeNumber;
public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
public ushort Handle;
public int Object_Pointer;
public UInt32 GrantedAccess;
}

它遍历集合,并在 GetFileDetails 方法中发送每个项目。

这里是方法,我只复制到.NET 4.5失败,.NET 4.0成功的try/catch语句:

private static FileDetails GetFileDetails(Win32API.SYSTEM_HANDLE_INFORMATION sYSTEM_HANDLE_INFORMATION)
{
FileDetails fd = new FileDetails();
fd.Name = "";
IntPtr ipHandle = IntPtr.Zero;
Win32API.OBJECT_BASIC_INFORMATION objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
IntPtr ipBasic = IntPtr.Zero;
Win32API.OBJECT_TYPE_INFORMATION objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();
IntPtr ipObjectType = IntPtr.Zero;
Win32API.OBJECT_NAME_INFORMATION objObjectName = new Win32API.OBJECT_NAME_INFORMATION();
IntPtr ipObjectName = IntPtr.Zero;
string strObjectTypeName = "";
string strObjectName = "";
int nLength = 0;
int nReturn = 0;
IntPtr ipTemp = IntPtr.Zero;


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

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;
}

try
{
strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);
}
catch (AccessViolationException)
{
return null;
}

有兴趣的 friend 可以在上面的链接中找到完整的代码谢谢你的帮助

最佳答案

由于一些错误的指针,访问冲突异常来自操作系统。由于 .NET 旨在避免裸指针,因此只有几个可能的来源:

  • 通过 P/Invoke 或 COM 互操作调用非托管代码。
  • 二进制错配。如果您调用的非托管代码是 x32 而您从 x64 调用它(反之亦然),它将不起作用。解决方法是对二进制进行硬编码或使用适当二进制的辅助进程。据说链接代码专为 x64 运行。如果您不定义二元性,框架可以选择今天感觉的“任何”二元性。您是否相应地选择了项目的目标?
  • 第三者干扰。那是几年前的事了,但我们曾遇到过某个病毒扫描程序会杀死所有其他 Windows 窗体应用程序的情况。尝试排除程序/关闭后台保护一段时间。

关于c# - .NET Framework 4.5 或更高版本中的 AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48733914/

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