[英]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();
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.