# Thread-less Payload Execution

Avoiding the use of threads will help us minimize our artifacts as EDRs may subscribe to callbacks which can make thread creation visible at a kernel level.

For extra stealthiness, we may want to not use threads and find other ways to execute our payload.

## Function Pointer Execution

This technique will use a function pointer to execute our payload, we will simply create a function pointer assigned to the address of our shellcode, and then proceed to call the function pointer thus calling our shellcode.

```
int (*func)();
func = (int (*)()) (void*)shellcode;
(int)(*func)();
```

This will make our payload run in the process's main thread instead of a new thread being spawned via createthread.

### Callbacks

callbacks are functions that are called through a function pointer. If we pass a function pointer to our shellcode to a function that a requires a callback function as it's parameter, it will then instead execute our shellcode. This can be used to pass our shellcode instead of our function pointer.

An example of this is EnumFonts

```
EnumFonts(GetDC(0), (LPCWSTR)0, (FONTENUMPROC)(char *)shellcode, 0);
```

an extensive list of such functions you can abuse for shellcode execution can be found here:

{% embed url="<https://github.com/ChaitanyaHaritash/Callback_Shellcode_Injection>" %}

## Fibers

Fibers allow an app to schedule its own thread of execution rather than priority based scheduling. These are basically light weightthreads, and are invisble to the kernel due to the fact that they are implemented in kernel32.

To use fibers, we must call ConvertThreadToFiber, which will convert the thread running into a running fiber. We can then make additional fibers with the CreateFiber function.

To abuse this for shellcode execution we will:

1. Convert the main thread into a fiber
2. allocate shellcode
3. create a new fiber that points to our shellcode
4. schedule the new fiber that point to our schedule
5. the fiber gets scheduled and our shellcode runs

```
void * fMain = ConvertThreadToFiber(NULL);
void * lShellcode = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
void * shellcodeFiber = CreateFiber(NULL, (LPFIBER_START_ROUTINE)lShellcode, NULL);
SwitchToFiber(shellcodeFiber);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kwcsec.gitbook.io/the-red-team-handbook/techniques/defense-evasion/minimization/thread-less-payload-execution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
