为什么我的 Interop 代码会抛出 "Stack cookie instrumentation code detected a stack-based buffer overrun" 异常?
Why does my Interop code throw a "Stack cookie instrumentation code detected a stack-based buffer overrun" exception?
因为我在内存读取等方面有点乱。我制作了包含 1000000 个元素的 byte[] 数组,这样它们每个可以存储 1MB 的数据。我最终使用了这 1000000 个元素数组中的大约 750 个,我在检索数据时一个一个地添加,例如:获取 MB 内存,添加到列表,获取下一个 MB。但它只是因溢出异常而失败。那么 List 可以包含多少元素是否存在实际限制,或者 List 是否存在“数据”限制?如果我没有超过这个限制,是什么导致了这个问题的发生?
编辑:异常截图
EDIT2:我正在从读取下一个 1MB 和 returns 指向该数组的指针的 c++ dll 中调用一个函数
编辑3:
C#部分
private static void FetchNextBuffer()
{
IntPtr pRaw = Wrapper.GetNextMB();
byte[] buff = new byte[1000000];
Marshal.Copy(buff, 0, pRaw, 1000000);
RawDataFetch.Add(buff);
}
包装器
[DllImport("Dumper.dll")]
public static extern IntPtr GetNextMB();
C++部分
.cpp 文件
extern byte * __cdecl GetNextMB()
{
if (!VarsSet) SetVars();
byte buffer[1000000];
ReadProcessMemory(pHandle, (void*)Address, &buffer, sizeof(buffer), 0);
Address = Address + sizeof(buffer);
return buffer;
}
.h 文件
extern "C"
{
__declspec(dllexport) DWORD __cdecl GetPID();
__declspec(dllexport) byte * __cdecl GetNextMB();
}
EDIT4:感谢你们所有的见解和快速的反应,伙计们(还有姑娘们,如果他们在那里的话:S)
EDIT5:现在全部修复,程序正在滚动
是的,但它取决于您有多少内存。
如果你有足够的内存来添加 Int32.MaxValue
values that that would break the List<T>
class.
这可能是 OverflowException
的原因。
如果您 运行 内存不足,我希望 OutOfMemoryException
。
您收到的错误不是 C# 异常而是 C++ 异常,investigated in this question。
要么您在 C++ 代码中做错了什么,要么您从 C# 中错误地调用了它。请注意,这与我认为我已经回答的原始问题有很大不同。
好的,代码很明显。
您在 C++ 端分配一个本地数组,return 一个指向它的指针。如果您习惯于使用本机代码,那应该已经敲响了警钟 - 您不会 return 指向本地人的指针!
然后你通过不正确地使用 Marshal.Copy
来杀死它——而不是从你从 C++ 代码获得的数据中复制(这可能是格式错误的,因为你 return 指向一个指针本地...),您将 C# 字节数组复制到从 C++ 函数获得的指针 - 覆盖 C++ 堆栈。轰.
但是,我不明白您为什么要使用 C++ 库来调用 ReadProcessMemory
- 为什么不直接调用它呢?我正在 https://github.com/Luaancz/AutoPoke.
我的小工具中这样做
因为我在内存读取等方面有点乱。我制作了包含 1000000 个元素的 byte[] 数组,这样它们每个可以存储 1MB 的数据。我最终使用了这 1000000 个元素数组中的大约 750 个,我在检索数据时一个一个地添加,例如:获取 MB 内存,添加到列表,获取下一个 MB。但它只是因溢出异常而失败。那么 List 可以包含多少元素是否存在实际限制,或者 List 是否存在“数据”限制?如果我没有超过这个限制,是什么导致了这个问题的发生?
编辑:异常截图
EDIT2:我正在从读取下一个 1MB 和 returns 指向该数组的指针的 c++ dll 中调用一个函数
编辑3: C#部分
private static void FetchNextBuffer()
{
IntPtr pRaw = Wrapper.GetNextMB();
byte[] buff = new byte[1000000];
Marshal.Copy(buff, 0, pRaw, 1000000);
RawDataFetch.Add(buff);
}
包装器
[DllImport("Dumper.dll")]
public static extern IntPtr GetNextMB();
C++部分 .cpp 文件
extern byte * __cdecl GetNextMB()
{
if (!VarsSet) SetVars();
byte buffer[1000000];
ReadProcessMemory(pHandle, (void*)Address, &buffer, sizeof(buffer), 0);
Address = Address + sizeof(buffer);
return buffer;
}
.h 文件
extern "C"
{
__declspec(dllexport) DWORD __cdecl GetPID();
__declspec(dllexport) byte * __cdecl GetNextMB();
}
EDIT4:感谢你们所有的见解和快速的反应,伙计们(还有姑娘们,如果他们在那里的话:S)
EDIT5:现在全部修复,程序正在滚动
是的,但它取决于您有多少内存。
如果你有足够的内存来添加 Int32.MaxValue
values that that would break the List<T>
class.
这可能是 OverflowException
的原因。
如果您 运行 内存不足,我希望 OutOfMemoryException
。
您收到的错误不是 C# 异常而是 C++ 异常,investigated in this question。
要么您在 C++ 代码中做错了什么,要么您从 C# 中错误地调用了它。请注意,这与我认为我已经回答的原始问题有很大不同。
好的,代码很明显。
您在 C++ 端分配一个本地数组,return 一个指向它的指针。如果您习惯于使用本机代码,那应该已经敲响了警钟 - 您不会 return 指向本地人的指针!
然后你通过不正确地使用 Marshal.Copy
来杀死它——而不是从你从 C++ 代码获得的数据中复制(这可能是格式错误的,因为你 return 指向一个指针本地...),您将 C# 字节数组复制到从 C++ 函数获得的指针 - 覆盖 C++ 堆栈。轰.
但是,我不明白您为什么要使用 C++ 库来调用 ReadProcessMemory
- 为什么不直接调用它呢?我正在 https://github.com/Luaancz/AutoPoke.