C++ 无法写入AllocConsole()

C++ 无法写入AllocConsole(),c++,console,dll-injection,C++,Console,Dll Injection,我有一个cpp dll,我想在注入后将文本打印到控制台。我使用alloconsole()创建控制台,因为这是最简单的方法,但我不能在控制台中编写 当我尝试printf()时,什么都没有发生。此外,我还尝试了std::cout在通过分配新控制台后,您需要重新打开标准流(stdout,stderr,stdin),然后才能使用它们 您可以使用freopen(在较新版本的Visual Studio中,您需要使用freopen\s) 例如: 文件*fDummy; freopen_s(&fDummy,“CO

我有一个cpp dll,我想在注入后将文本打印到控制台。我使用alloconsole()创建控制台,因为这是最简单的方法,但我不能在控制台中编写


当我尝试printf()时,什么都没有发生。此外,我还尝试了std::cout在通过分配新控制台后,您需要重新打开标准流(
stdout
stderr
stdin
),然后才能使用它们

您可以使用
freopen
(在较新版本的Visual Studio中,您需要使用
freopen\s
) 例如:

文件*fDummy;
freopen_s(&fDummy,“CONIN$”、“r”、stdin);
freopen_s(&fdumm,“CONOUT$”、“w”、stderr);
freopen_s(&fdumm,“CONOUT$”、“w”、stdout);
如果您想使用弃用的
freopen
,您可以通过
定义
ing
\u CRT\u SECURE\u NO\u警告

如果还希望使用宽字符流(
std::wcout
std::wcerr
,等等),则需要调用为进程设置新的输出句柄。通过使用
CONOUT$
/
CONIN$
作为文件名调用,可以获取此操作所需的文件句柄:

HANDLE hConOut=CreateFile(_T(“CONOUT$”),通用读取,通用写入,文件共享读取,文件共享写入,NULL,打开,文件属性正常,NULL);
设置TDHandle(标准输出句柄,hConOut);
此外,如果在重新打开流之前尝试使用其中一个流,则它们将具有和 在其
iostate
中设置,因此后续写入/读取将被忽略。
您可以使用重置流状态,然后可以再次读取/写入流:

std::cout.clear();
std::cin.clear();
下面是在
alloconsole()
之后重新打开所有流的完整示例:

void CreateConsole()
{
如果(!alloconsole()){
//在这里添加一些错误处理。
//您可以调用GetLastError()以获取有关错误的更多信息。
返回;
}
//标准::cout,标准::clog,标准::cerr,标准::cin
文件*fDummy;
freopen_s(&fdumm,“CONOUT$”、“w”、stdout);
freopen_s(&fdumm,“CONOUT$”、“w”、stderr);
freopen_s(&fDummy,“CONIN$”、“r”、stdin);
std::cout.clear();
std::clog.clear();
标准::cerr.clear();
std::cin.clear();
//std::wcout、std::wclog、std::wcerr、std::wcin
HANDLE hConOut=CreateFile(_T(“CONOUT$”),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE hConIn=CreateFile(_T(“CONIN$”),GENERIC_READ|GENERIC|WRITE,FILE_SHARE|READ|FILE|SHARE|WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
设置TDHandle(标准输出句柄,hConOut);
设置TDHandle(标准错误句柄,hConOut);
设置TDHandle(标准输入句柄,hConIn);
std::wcout.clear();
std::wclog.clear();
std::wcerr.clear();
std::wcin.clear();
}

要写入Windows控制台,您需要使用Win32 console API。可能存在重复的
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        AllocConsole();
        printf("Injected");
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)main, NULL, NULL, NULL);
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}