Creating remote thread is crashing the process
<p>I am trying to inject code in a different process, so far there is some success, I can inject data and method in the target process. I can execute remote thread and will get return value after the completion of thread only if the thread function is without body. eg if I omit MessageBox line from ThreadFunc then it will work, but no std::cout/printf/MessageBox can be there and no windows api calls. so either I return immediately from that function or do some simple math operations.</p>

<p><strong>compiling code</strong></p>

<pre><code>#include &lt;windows.h&gt;
#include &lt;tlhelp32.h&gt;
#include &lt;string.h&gt;
#include &lt;iostream&gt;
using namespace std;

#define cbNewProc       1600

typedef struct {
    HWND hwnd;
} INJDATA, *PINJDATA;

static const char *err_str(void) {
    static char buf[2048];
    if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buf,
            sizeof(buf), NULL))
        return buf;
    return "Unknown error";
}

// entry point in remote process
static LRESULT CALLBACK ThreadFunc(LPVOID param) {
    MessageBox(NULL, "I am inside remote process", "Hiiii", 0);
    return 1;
}

static int inject_code(DWORD pid) {
    cout &lt;&lt; "Process found: " &lt;&lt; pid &lt;&lt; endl;

    HANDLE hp = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
    PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
    if (!hp) {
        fprintf(stderr, "OpenProcess( %s )\n", err_str());
        return 0;
    }

    int size = sizeof(INJDATA) + cbNewProc;
    BYTE* pDataRemote = (BYTE*) VirtualAllocEx(hp, NULL, size,
    MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (!pDataRemote) {
        fprintf(stderr, "VirtualAllocEx( %s )\n", err_str());
        CloseHandle(hp);
        return 0;
    }

    SIZE_T dwNumBytesXferred;
    BYTE* pNewProcRemote = pDataRemote + sizeof(INJDATA);
    if (!WriteProcessMemory(hp, pNewProcRemote, (void*) &amp;ThreadFunc,
    cbNewProc, &amp;dwNumBytesXferred)) {
        fprintf(stderr, "WriteProcessMemory( %s )\n", err_str());
        VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
        CloseHandle(hp);
        return 0;
    }

    INJDATA DataLocal;
    ZeroMemory(&amp;DataLocal, sizeof(INJDATA));
    if (!WriteProcessMemory(hp, pDataRemote, &amp;DataLocal, sizeof(INJDATA),
            &amp;dwNumBytesXferred)) {
        fprintf(stderr, "WriteProcessMemory( %s )\n", err_str());
        VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
        CloseHandle(hp);
        return 0;
    }

    printf("pDataRemote=%ld\n", pDataRemote);
    printf("pNewProcRemote1=%ld\n", pNewProcRemote);
    printf("pNewProcRemote2=%ld\n", pNewProcRemote + cbNewProc);

    int nSuccess = 0;
    DWORD dwThreadId;
    HANDLE hThread = CreateRemoteThread(hp, NULL, 0,
            (LPTHREAD_START_ROUTINE) pNewProcRemote, pDataRemote, 0,
            &amp;dwThreadId);
    if (hThread == 0) {
        cout &lt;&lt; "CreateRemoteThread failed" &lt;&lt; endl;
        return 0;
    }

    WaitForSingleObject(hThread, INFINITE);
    GetExitCodeThread(hThread, (PDWORD) &amp;nSuccess);
    VirtualFreeEx(hp, pDataRemote, size, MEM_RELEASE);
    cout &lt;&lt; "nSuccess=" &lt;&lt; nSuccess &lt;&lt; ", size=" &lt;&lt; size &lt;&lt; endl;

    CloseHandle(hp);
    return 1;
}

int main() {
    cout &lt;&lt; "Remote Thread" &lt;&lt; endl;

    HANDLE h;
    PROCESSENTRY32 p;

    h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (h == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateToolHelp32Snapshot( %s )\n", err_str());
        return 0;
    }

    p.dwSize = sizeof(p);

    if (!Process32First(h, &amp;p)) {
        fprintf(stderr, "Process32First( %s )\n", err_str());
        goto out_close;
    }

    do {
        if (strcasecmp(p.szExeFile, "dllexp.exe"))
            continue;
        inject_code(p.th32ProcessID);
    } while (Process32Next(h, &amp;p));

    out_close: CloseHandle(h);
    return 0;
}
</code></pre>

<p>Usually target process will crash with a page fault or invalid read location error.</p>