CreateRemoteThread causes process to crash without error code

0

I'm attempting to execute a simple function inside another process (the "host"). To do this, I call WriteProcessMemory to copy the function to the host, then use CreateRemoteThread to execute that function. The host process just crashes, with no error codes.

I use Notepad++ (32 bit) as an example host. I also compile my program to x86 (on Windows, obviously). What am I doing wrong here?

#include <iostream>
#include <Windows.h>
#include <psapi.h>

// the function to be executed inside the host
DWORD __stdcall func(LPVOID pParam)
{
    // this is the end goal, but
    // just return 1 for now to help
    // solve one problem at a time
    /*
    AllocConsole(); FILE* consoleFile;
    freopen_s(&consoleFile, "CONOUT$", "w", stdout);

    int parameter = *(int*)pParam;
    std::cout << "param: " << parameter << std::endl;
    */
    return 1;
}

// exists only to help calculate the size of func()
DWORD __stdcall after()
{
    return 0;
}

int main() {
    HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 30512); // PID found via task manager
    char procName[MAX_PATH + 1];
    GetModuleFileNameEx(process, NULL, procName, MAX_PATH);
    std::cout << "got process: " << procName << std::endl;

    size_t functionSize = (DWORD)after - (DWORD)func;
    void* functionMemory = VirtualAllocEx(process, NULL, functionSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    std::cout << "function address: " << (DWORD)functionMemory << std::endl;
    bool functionWPM = WriteProcessMemory(process, functionMemory, func, functionSize, NULL);
    std::cout << "function wpm: " << (functionWPM ? "true" : "false") << std::endl;

    int parameter = 1234;
    size_t parameterSize = sizeof(int);
    void* parameterMemory = VirtualAllocEx(process, NULL, parameterSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    std::cout << "parameter address: " << (DWORD)parameterMemory << std::endl;
    bool parameterWPM = WriteProcessMemory(process, parameterMemory, &parameter, parameterSize, NULL);
    std::cout << "parameter wpm: " << (parameterWPM ? "true" : "false") << std::endl;

    
    HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)functionMemory, parameterMemory, 0, NULL);
    WaitForSingleObject(hThread, INFINITE);
    std::cout << "thread 0x" << std::hex << hThread << std::dec << " completed" << std::endl;

    std::cout << "errno: " << GetLastError() << std::endl;

    CloseHandle(hThread);
    CloseHandle(process);
    return 0;
}

This is the output, which does not indicate that anything has gone wrong:

got process: C:\Program Files (x86)\Notepad++\notepad++.exe
function address: 55115776
function wpm: true
parameter address: 55181312
parameter wpm: true
(there is a noticable ~0.5 second delay here)
thread 0x000000E0 completed
errno: 0
c++
windows
code-injection
asked on Stack Overflow Dec 6, 2020 by Gaberocksall • edited Dec 6, 2020 by Gaberocksall

1 Answer

1

The solution to the immediate problem was to compile in release mode. I'm not exactly sure why, so if anyone has an idea I'd love to hear it in a comment.

As @RaymodChen has mentioned, this process is more complicated than I once thought, and I was unable to run any significant amount of code in the host process.

If anyone comes along this question trying to do the same thing, my advice is to keep in mind that the address space of the func() is completely different to your injector program. This means that if you want to call AllocConsole() then you'll have to determine it's address in the host program, then call it at that address instead of just using AllocConsole() as I did in the question.

answered on Stack Overflow Dec 6, 2020 by Gaberocksall

User contributions licensed under CC BY-SA 3.0