Search code examples
c++bufferexternalstack-basedoverrun

Stackbased buffer overrun


When running my code I get the following error:

Unhandled exception at 0x00BA16A0 in GameLauncher.exe: Stack cookie instrumentation code detected a stack-based buffer overrun.

I have no idea what could be causing this. It is caused with the following code:

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>

int main()
{

    std::cout << "Which process would you like to close? (Include .exe)" << std::endl;
    wchar_t userProcessToFind;
    std::wcin.getline(&userProcessToFind, 20);

    HANDLE processSnapshot;
    DWORD processID = 0;
    PROCESSENTRY32 processEntery;
    processEntery.dwSize = sizeof(PROCESSENTRY32);

    processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, processID);
    if(Process32First(processSnapshot, &processEntery) == TRUE)
    { 

        while (Process32Next(processSnapshot, &processEntery) == TRUE)
        {
            if (_wcsicmp(processEntery.szExeFile, &userProcessToFind) == 0)
            {
                HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processEntery.th32ProcessID);

                TerminateProcess(hProcess, 0);

                CloseHandle(hProcess);
            }
        }

        CloseHandle(processSnapshot);
    }

    return 0;
}

Solution

  • In

    wchar_t userProcessToFind;
    std::wcin.getline(&userProcessToFind, 20);
    

    You have allocated space for a single wchar_t but you are trying to read in up to 20 characters and place it in the memory at the address of userProcessToFind. This will cause stack corruption as you are going to try to write into memory that does not belong to &userProcessToFind. What you need to do is create an array like

    wchar_t userProcessToFind[20];
    std::wcin.getline(userProcessToFind, 20);
    

    Or you could use a std::wstring and your code would become

    std::wstring userProcessToFind;
    std::getline(std::wcin, userProcessToFind);
    

    This gives the benefit of not having to use an arbitrary size for the process name as std::wstring will scale to fit the input. If you need to pass the underlying wchar_t* to a function you can use std::wstring::c_str() to get it.