Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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. 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 enter image description here

EDIT2: I am calling a function from a c++ dll that reads the next 1MB and returns a pointer to that array

EDIT3: C# part

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
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 file

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)

EDIT5: all fixed now and program is rolling


2 Answers

Okay, the code makes it obvious.

You allocate a local array on the C++ side, and return a pointer to that. 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. Boom.

However, I don't see why you'd use a C++ library just to call ReadProcessMemory - why not just invoke that directly? I'm doing just that in my little tool at https://github.com/Luaancz/AutoPoke.

like image 112
Luaan Avatar answered Aug 02 '26 04:08

Luaan


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.

This may the cause of an OverflowException.

If you are running out of memory I'd expect an OutOfMemoryException.


The error you getting is not a C# exception but rather a C++ Exception, investigated in this question.

Either you've done something wrong in your C++ code or you've called it incorrectly from C#. Note, this is very different from the original question that I think I've answered.

like image 39
Jodrell Avatar answered Aug 02 '26 04:08

Jodrell