c++ - 来自注入(inject)的 .dll 的管道卡住直到进程终止

标签 c++ pipe dll-injection

我正在尝试通过已设置管道的注入(inject) .dll 将一些数据从外部进程通过管道传输到我的程序。但是,ReadFile() 只有在外部程序退出后才会返回(之后它将给出正确的输出)。这是标准行为,还是我使用的管道(或其他东西)有误?

相关部分代码如下(为简洁省略部分):

ma​​in.cpp:

int main() {
    // Create a duplex pipe-based communication channel
    STARTUPINFO startupInfo = {};
    HANDLE parent_IN, parent_OUT;
    if (!IntraProcessComms(startupInfo, parent_IN, parent_OUT)) {
        std::cout << "Could not set up communication necessities" << std::endl;
        return 1;
    }

    // Launch program and obtain the handle
    PROCESS_INFORMATION processInfo = {};
    if (!CreateProcess(
            nullptr,                                                        // path
            LPSTR("[the program path]"),                                    // commands
            nullptr,                                                        // handler inheritable
            nullptr,                                                        // thread inheritable
            true,                                                           // handler inheritance from caller
            0,                                                              // creation flag
            nullptr,                                                        // environment
            nullptr,                                                        // directory
            &startupInfo,                                                   // startup info
            &processInfo)) {                                                // process info
        std::cout << "Could not launch program" << std::endl;
        return 2;
    }

    // Inject the DLL (omitted here; it is injected successfully)
    if (!InjectDLL(processInfo.hProcess, "scraper.dll")) {
        std::cout << "Could not inject DLL" << std::endl;
        return 3;
    }

    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
    std::cout << "Successfully set up" << std::endl;

    char buffer[BUFSIZ];
    ZeroMemory(buffer, BUFSIZ);
    ReadFile(parent_IN, buffer, sizeof(buffer), nullptr, nullptr);
    std::cout << "Read: \"" << buffer << "\"" << std::endl;
    return 0;
}

bool IntraProcessComms(STARTUPINFO &si, HANDLE &parent_IN, HANDLE &parent_OUT) {
    HANDLE child_IN, child_OUT;
    SECURITY_ATTRIBUTES securityAttr {
        sizeof(SECURITY_ATTRIBUTES),                                        // size
        nullptr,                                                            // security
        true                                                                // inheritable
    };

    // Create pipes from the child to the parent and vice-versa
    if (!CreatePipe(
            &parent_IN,
            &child_OUT,
            &securityAttr,
            0)
    || !CreatePipe(
            &child_IN,
            &parent_OUT,
            &securityAttr,
            0))
        return false;

    // Ensure only the correct handles are inherited
    if (!SetHandleInformation(
            parent_IN,
            HANDLE_FLAG_INHERIT,
            0)
    || !SetHandleInformation(
            parent_OUT,
            HANDLE_FLAG_INHERIT,
            0))
        return false;

    // Set up startupinfo
    si.cb = sizeof(STARTUPINFO);
    si.hStdError = child_OUT;
    si.hStdOutput = child_OUT;
    si.hStdInput = child_IN;
    si.dwFlags = STARTF_USESTDHANDLES;

    return true;
}

scraper.dll:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    if (fdwReason == DLL_PROCESS_ATTACH) {
        // stdout was redirected by IntraProcessComms()
        std::cout << "Send from .dll";
    }
    return true;
}

(可能会有一些明显的错误/奇怪的做法,我是C++的新手)

最佳答案

写入 std::cout 的内容将在内部缓存,直到缓冲区变满或被刷新。在此刷新发生之前,管道将看不到任何写入的数据。

您可以调用std::cout.flush()写入数据后,或附加 << std::endl在您的输出语句中添加换行符并刷新缓冲区。如果您只打算发送完整的消息(即一个 <<cout ,而不是几个来撰写消息),您可以使用 unitbuf流中的标志以在每次输出操作后刷新输出 ( std::cout << std::unitbuf << "Send from .dll"; ) 您可以使用 nounitbuf重新打开缓冲。

关于c++ - 来自注入(inject)的 .dll 的管道卡住直到进程终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50934202/

相关文章:

c++ - 在 Eigen (C++) 中求解欠定方程组

C++ Poco - 如何遍历 JSON 数组?

c++ - 为什么我们在内存中限制堆栈的大小而不是堆的大小

awk - 如何逐行grep awk的输出?

c - 通过管道读写数据

bash - Golang exec.Command 多个管道

c++ - Firefox pr_write 钩子(Hook)。 dll 注入(inject),Windows 钩子(Hook)

c++ - 使用什么技术注入(inject) DLL?

dll-injection - 在 LoadLibrary 上 CreateRemoteThread 并取回 HMODULE

c++ - C++ HTTPS 库在性能(例如内存占用、CPU 时间等)方面如何比较?