gpt4 book ai didi

c# - 在垃圾收集之前检测堆损坏

转载 作者:行者123 更新时间:2023-11-30 18:02:45 25 4
gpt4 key购买 nike

我正在使用 CDB(Microsoft 控制台调试器)和 WinDbg P/Invoke 发生堆损坏时尝试强制中断进入读文件。我从文本文件中读取的字节数比我分配给 chBuf 数组的字节数多得多。调试器直到 GC.Collect 之后才发现访问冲突,这对我来说太晚了。在运行我的程序之前,我运行

gflags -p /enable testheap.exe /unaligned

效果好像没用。我编写了这个小测试程序,以将我发现的内容应用于调试存在堆损坏问题的更大的商业程序。

我也尝试过使用 DebugDiag Application Verifier和 MDA callbackOnCollectedDelegate 没有成功。我对 gflags 的使用不是应该在 ReadFile 后立即检测堆损坏吗?

代码:

    namespace TestHeap

public partial class Form1 : Form
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(SafeFileHandle hFile, [Out] byte[] lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

string fileName = "testHeap.txt";
const uint GENERIC_READ = 0x80000000;
const uint OPEN_EXISTING = 3;
SafeFileHandle sh;
byte[] chBuf = new byte[8];

public Form1()
{
InitializeComponent();
}

private void testBtn_Click(object sender, EventArgs e)
{
bool nStat;
uint bytesToRead = 1025;
uint bytesRead = 0;

if (!(nStat = ReadFile( sh, chBuf, bytesToRead, out bytesRead, IntPtr.Zero)))
Debug.Print("testBtn_Click error in ReadFile, nStat = {0}", nStat);
MessageBox.Show(string.Format("After ReadFile, bytesToRead = {0},\n bytes read = {1}", bytesToRead, bytesRead));
GC.Collect();
MessageBox.Show("testBtn_Click end, after GC.Collect");
}

private void Form1_Load(object sender, EventArgs e)
{
sh = CreateFile(fileName, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
}
}
}

最佳答案

只是一个猜测,但我相信意外的 gflags 行为是由这一行引起的:

byte[] chBuf = new byte[8];

由于 chBuf 由 CLR 管理,gflags 无法在其后放置填充模式来检测缓冲区溢出。尝试将其更改为:

IntPtr chBuf = Marshal.AllocHGlobal(8);

因此您将在非托管堆中进行分配。 Gflags 应该可以使用它。此外,您可能需要更改 ReadFile 的签名才能使其正常工作:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(SafeFileHandle hFile, [Out] IntPtr lpBuffer,
uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

关于c# - 在垃圾收集之前检测堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7948932/

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