api: redirect log to stderr in rundll32 invocations

The WoW64 client will provide stdio handles to read the log messages.
Furthermore, the rundll32 calls could return results using stdout.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2020-10-16 13:26:04 +02:00 committed by Jason A. Donenfeld
parent b79703bba8
commit 2d20564f0a

View File

@ -7,10 +7,6 @@
#if defined(_M_AMD64) || defined(_M_ARM64) #if defined(_M_AMD64) || defined(_M_ARM64)
// TODO: Log to Windows Event Log in production.
# ifdef _DEBUG
static VOID CALLBACK static VOID CALLBACK
ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ const WCHAR *LogLine) ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ const WCHAR *LogLine)
{ {
@ -29,11 +25,9 @@ ConsoleLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ const WCHAR *LogLine)
default: default:
return; return;
} }
fwprintf(stdout, Template, LogLine); fwprintf(stderr, Template, LogLine);
} }
# endif
static BOOL ElevateToSystem(VOID) static BOOL ElevateToSystem(VOID)
{ {
HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken; HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken;
@ -128,30 +122,20 @@ cleanup:
return FALSE; return FALSE;
} }
static void static int Argc;
Init(_In_ BOOL ShowConsole) static WCHAR **Argv;
static void Init(VOID)
{ {
# ifdef _DEBUG
if (ShowConsole)
{
AllocConsole();
FILE *Stream;
_wfreopen_s(&Stream, L"CONOUT$", L"w", stdout);
}
WintunSetLogger(ConsoleLogger); WintunSetLogger(ConsoleLogger);
# else Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
UNREFERENCED_PARAMETER(ShowConsole);
# endif
ElevateToSystem(); ElevateToSystem();
} }
static void Done(VOID) static void Done(VOID)
{ {
RevertToSelf(); RevertToSelf();
# ifdef _DEBUG LocalFree(Argv);
_putws(L"\nPress any key to close . . .");
(VOID) _getwch();
# endif
} }
__declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) __declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
@ -159,30 +143,28 @@ __declspec(dllexport) VOID __stdcall CreateAdapter(HWND hwnd, HINSTANCE hinst, L
UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(hinst); UNREFERENCED_PARAMETER(hinst);
UNREFERENCED_PARAMETER(lpszCmdLine); UNREFERENCED_PARAMETER(lpszCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
int Argc; Init();
LPWSTR *Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
if (Argc < 4) if (Argc < 4)
goto cleanupArgv; goto cleanup;
if (wcslen(Argv[2]) >= MAX_POOL) if (wcslen(Argv[2]) >= MAX_POOL)
goto cleanupArgv; goto cleanup;
if (wcslen(Argv[3]) >= MAX_ADAPTER_NAME) if (wcslen(Argv[3]) >= MAX_ADAPTER_NAME)
goto cleanupArgv; goto cleanup;
GUID RequestedGUID; GUID RequestedGUID;
if (Argc > 4 && FAILED(CLSIDFromString(Argv[4], &RequestedGUID))) if (Argc > 4 && FAILED(CLSIDFromString(Argv[4], &RequestedGUID)))
goto cleanupArgv; goto cleanup;
WINTUN_ADAPTER *Adapter; WINTUN_ADAPTER *Adapter;
BOOL RebootRequired = FALSE; BOOL RebootRequired = FALSE;
Init(!!nCmdShow);
DWORD Result = WintunCreateAdapter(Argv[2], Argv[3], Argc > 4 ? &RequestedGUID : NULL, &Adapter, &RebootRequired); DWORD Result = WintunCreateAdapter(Argv[2], Argv[3], Argc > 4 ? &RequestedGUID : NULL, &Adapter, &RebootRequired);
Done();
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
goto cleanupArgv; goto cleanup;
WintunFreeAdapter(Adapter); WintunFreeAdapter(Adapter);
cleanupArgv:
LocalFree(Argv); cleanup:
Done();
} }
__declspec(dllexport) VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) __declspec(dllexport) VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
@ -190,22 +172,20 @@ __declspec(dllexport) VOID __stdcall DeleteAdapter(HWND hwnd, HINSTANCE hinst, L
UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(hinst); UNREFERENCED_PARAMETER(hinst);
UNREFERENCED_PARAMETER(lpszCmdLine); UNREFERENCED_PARAMETER(lpszCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
int Argc; Init();
LPWSTR *Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
if (Argc < 3) if (Argc < 3)
goto cleanupArgv; goto cleanup;
WINTUN_ADAPTER Adapter = { 0 }; WINTUN_ADAPTER Adapter = { 0 };
if (FAILED(CLSIDFromString(Argv[2], &Adapter.CfgInstanceID))) if (FAILED(CLSIDFromString(Argv[2], &Adapter.CfgInstanceID)))
goto cleanupArgv; goto cleanup;
BOOL RebootRequired = FALSE; BOOL RebootRequired = FALSE;
Init(!!nCmdShow);
WintunDeleteAdapter(&Adapter, &RebootRequired); WintunDeleteAdapter(&Adapter, &RebootRequired);
Done();
cleanupArgv: cleanup:
LocalFree(Argv); Done();
} }
#endif #endif