简体   繁体   English

为什么我的互操作代码会抛出“堆栈 cookie 检测代码检测到基于堆栈的缓冲区溢出”异常?

[英]Why does my Interop code throw a "Stack cookie instrumentation code detected a stack-based buffer overrun" exception?

Since I was messing a bit around with memory reading etc etc. And I made byte[] arrays with 1000000 elements so that they would store 1MB of data each.因为我在内存读取等方面有点混乱。我制作了具有 1000000 个元素的 byte[] 数组,以便它们每个可以存储 1MB 的数据。 I wound up using around 750-isch of these 1000000 element array, which I added one by one when I retrieved data, eg: get MB of memory, add to list, get next MB.我最终使用了这些 1000000 个元素数组中的 750 个左右,这些数组是我在检索数据时一个一个添加的,例如:获取 MB 内存、添加到列表、获取下一个 MB。 But it just failed with an overflow exception.但它只是因溢出异常而失败。 So is there an actual limit of how much elements a List can contain, or is there a "data" limit to the List?那么列表可以包含多少元素是否有实际限制,或者列表是否有“数据”限制? If I didn't cross this limit what could have caused this problem to occur?如果我没有超过这个限制,是什么导致了这个问题的发生?

EDIT: Screenshot of exception编辑:异常截图在此处输入图片说明

EDIT2: I am calling a function from a c++ dll that reads the next 1MB and returns a pointer to that array EDIT2:我正在从 C++ dll 中调用一个函数,该函数读取下一个 1MB 并返回指向该数组的指针

EDIT3: C# part EDIT3:C# 部分

private static void FetchNextBuffer()
{
    IntPtr pRaw = Wrapper.GetNextMB();
    byte[] buff = new byte[1000000];
    Marshal.Copy(buff, 0, pRaw, 1000000);
    RawDataFetch.Add(buff);
}

wrapper包装纸

[DllImport("Dumper.dll")]
public static extern IntPtr GetNextMB();

c++ part .cpp file c++部分.cpp文件
extern "C"
{
    __declspec(dllexport) DWORD __cdecl GetPID();
    __declspec(dllexport)  byte * __cdecl GetNextMB();
}

.h file .h 文件

extern "C" { __declspec(dllexport) DWORD __cdecl GetPID(); __declspec(dllexport) byte * __cdecl GetNextMB(); }

EDIT4: Thank you for all the insights and quick response guys (and girls if they are out there :S) EDIT4:感谢所有的见解和快速反应的家伙(和女孩,如果他们在那里:S)

EDIT5: all fixed now and program is rolling EDIT5:现在全部修复,程序正在滚动

Okay, the code makes it obvious.好的,代码很明显。

You allocate a local array on the C++ side, and return a pointer to that.您在 C++ 端分配一个本地数组,并返回一个指向该数组的指针。 That should already ring alarm bells if you're used to working with native code - you don't return pointers to locals!如果您习惯于使用本机代码,那应该已经敲响了警钟——您不会将指针返回给本地人!

And then you kill it with using Marshal.Copy improperly - instead of copying from the data you get from the C++ code (which is possibly malformed, because you're returning a pointer to a local...), you copy the C# byte array over to the pointer you got from the C++ function - overwriting the C++ stack.然后你通过不正确地使用Marshal.Copy来杀死它 - 而不是从你从 C++ 代码中获得的数据中复制(这可能是格式错误的,因为你正在返回一个指向本地的指针......),而是复制 C# 字节数组转移到您从 C++ 函数获得的指针 - 覆盖 C++ 堆栈。 Boom.繁荣。

However, I don't see why you'd use a C++ library just to call ReadProcessMemory - why not just invoke that directly?但是,我不明白您为什么要使用 C++ 库来调用ReadProcessMemory - 为什么不直接调用它? I'm doing just that in my little tool at https://github.com/Luaancz/AutoPoke .我正在https://github.com/Luaancz/AutoPoke 上的小工具中这样做。

Yes, but its defined by how much memory you have.是的,但它由您拥有多少内存来定义。

If you have enough memory to have add over Int32.MaxValue values that that would break the List<T> class.如果您有足够的内存来添加会破坏List<T>类的Int32.MaxValue值。

This may the cause of an OverflowException .这可能是导致OverflowException的原因。

If you are running out of memory I'd expect an OutOfMemoryException .如果您的内存不足,我预计会出现OutOfMemoryException


The error you getting is not a C# exception but rather a C++ Exception, investigated in this question .您得到的错误不是 C# 异常,而是 C++ 异常, 在此问题中进行了调查

Either you've done something wrong in your C++ code or you've called it incorrectly from C#.要么您在 C++ 代码中做错了什么,要么在 C# 中错误地调用了它。 Note, this is very different from the original question that I think I've answered.请注意,这与我认为我已经回答的原始问题非常不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM