Search code examples
cwinapistdoutdll-injection

Stdout of process not redirected properly via dll injection


I'm injecting a C dll (as a thread) into a running console process, and trying to redirect its stdout to a file. My dll also writes to the console via wprintf.

As a simple redirection test I made the dll call TestRedirect at the start:

FILE *file = NULL;
BOOL WINAPI Test1(void *param);

void TestRedirect()
{
    file = freopen("C:\\temp\\test1.txt", "w", stdout);
    _beginthreadex(NULL, 0, Test1, (void*)file, NULL, 0, NULL);
}

BOOL WINAPI Test1(void *param)
{
    FILE *file = (FILE*)param;
    while (1)
    {
        wprintf(L"Test1\n");
        fflush(file);
        Sleep(200);
    }
}

Every time my dll writes to stdout via wprintf, regardless of the thread, the text appears in the file. However, my test console program (also a C program) doesn't write to the file. All the console program does is call wprintf every second to print something. When my dll is injected in the process, the exe's text stops appearing in the console window but doesn't get written to the file. Same if I try it on other programs, e.g. ping.exe.

However if I put the same code directly into my test console program and make that program call TestRedirect, then the program's output is written to the file (without injecting the dll).

What am I doing wrong?


Solution

  • I was able to do this by making the injected dll call FreeConsole and then AttachConsole, passing in the PID of the process with the console where I wanted the output to be redirected to.

    (I know the question mentioned redirecting it to a file, but that was really just for testing purposes as an ostensibly easier thing to do; ultimately, I wanted it to be redirected to a console. At the end of the day, I can make my own console redirect its stdout (which it receives from the "remote" process) to a file if I want, which should still satisfy the actual question.)