RunAsNewUserDllW

Method briefly mentioned by Hexacorn, demonstration comes from Adrian B.

#include <Windows.h>

PWCHAR StringCopyW(_Inout_ PWCHAR String1, _In_ LPCWSTR String2)
{
	PWCHAR p = String1;

	while ((*p++ = *String2++) != 0);

	return String1;
}

typedef struct _RUNASNEWUSERPARAM {
	WCHAR EventName[56];
	WCHAR ExecutableFile[MAX_PATH];
	WCHAR Arguments[MAX_PATH];
	BYTE Padding[1536];
	WCHAR Directory[MAX_PATH - 4];
} RUNASNEWUSERPARAM, *PRUNASNEWUSERPARAM;

typedef INT(WINAPI* RUNASNEWUSER_RUNDLLW)(HWND, HINSTANCE, LPCWSTR, INT);

BOOL CreateProcessRunAsNewUserDllW(_In_ PWCHAR BinaryPath, _In_ PWCHAR FileMapString, _In_ PWCHAR EventString)
{
	RUNASNEWUSER_RUNDLLW RunAsNewUser_RunDllW = NULL;
	PRUNASNEWUSERPARAM Parameters = NULL;
	HMODULE Module = NULL;

	HANDLE FileMap = NULL;
	HANDLE Event = NULL;

	BOOL bFlag = FALSE;

	Module = LoadLibraryA("shell32.dll");
	if (Module == NULL)
		goto EXIT_ROUTINE;

	RunAsNewUser_RunDllW = (RUNASNEWUSER_RUNDLLW)GetProcAddress(Module, "RunAsNewUser_RunDLLW");
	if (RunAsNewUser_RunDllW == NULL)
		goto EXIT_ROUTINE;

	FileMap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(RUNASNEWUSERPARAM), FileMapString);
	if (FileMap == NULL)
		goto EXIT_ROUTINE;

	Event = CreateEventW(NULL, FALSE, FALSE, EventString);
	if (Event == NULL)
		goto EXIT_ROUTINE;

	Parameters = (PRUNASNEWUSERPARAM)MapViewOfFile(FileMap, FILE_MAP_WRITE, 0, 0, 0);
	if (Parameters == NULL)
		goto EXIT_ROUTINE;

	if (StringCopyW(Parameters->EventName, EventString) == NULL)
		goto EXIT_ROUTINE;

	if (StringCopyW(Parameters->ExecutableFile, BinaryPath) == NULL)
		goto EXIT_ROUTINE;

	RunAsNewUser_RunDllW(NULL, NULL, FileMapString, SW_SHOW);

	bFlag = TRUE;

EXIT_ROUTINE:

	if (Parameters)
		UnmapViewOfFile(Parameters);

	if (FileMap)
		CloseHandle(FileMap);

	if (Event)
		CloseHandle(Event);

	return bFlag;
}

INT main(VOID)
{

	CreateProcessRunAsNewUserDllW((PWCHAR)L"C:\\Windows\\System32\\calc.exe", (PWCHAR)L"FileMapString", (PWCHAR)L"EventString");

	return 0;
}

Last updated