void LogToConsole()

in PPLGuardDll/dllexploit.cpp [112:163]


void LogToConsole(LPCWSTR pwszFormat, ...)
{
    //
    // The process in which we load this DLL does not have a console so we need to attach to the 
    // parent process' console. To do so, we can call AttachConsole with the special value 
    // ATTACH_PARENT_PROCESS. Then, we can get the STDOUT handle. This handle is stored will be 
    // stored as a global variable so we need to initialize it only once.
    //
    if (g_hConsoleOutput == NULL)
    {
        AttachConsole(ATTACH_PARENT_PROCESS);
        if (!(g_hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE)))
            return;
    }

    //
    // Prepare otuput string and use WriteConsole instead of wprintf. This way, we can directly use
    // the STDOUT handle we got previously.
    //
    DWORD dwOutputStringSize = 0;
    LPWSTR pwszOutputString = NULL;
    va_list va;
    size_t offset = 0;

    va_start(va, pwszFormat);

    if (g_bDebug)
        dwOutputStringSize += (DWORD)wcslen(L"[DEBUG] (DLL) ") * sizeof(WCHAR);
    else
        dwOutputStringSize += (DWORD)wcslen(L"(DLL) ") * sizeof(WCHAR);
    dwOutputStringSize += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2; // \0
    pwszOutputString = (LPWSTR)LocalAlloc(LPTR, dwOutputStringSize);

    if (pwszOutputString)
    {
        if (g_bDebug)
            StringCchPrintf(pwszOutputString, dwOutputStringSize, L"[DEBUG] (DLL) ");
        else
            StringCchPrintf(pwszOutputString, dwOutputStringSize, L"(DLL) ");

        if (SUCCEEDED(StringCbLength(pwszOutputString, dwOutputStringSize, &offset)))
        {
            StringCbVPrintf(&pwszOutputString[offset / sizeof(WCHAR)], dwOutputStringSize - offset, pwszFormat, va);

            WriteConsole(g_hConsoleOutput, pwszOutputString, (DWORD)wcslen(pwszOutputString), NULL, NULL);
        }

        LocalFree(pwszOutputString);
    }

    va_end(va);
}