您的位置:首页 > 其它

使用CreateProcess函数实现隐秘的程序调用之二:使用匿名管道

2016-09-14 13:56 671 查看
// 所有原创文章转载请注明作者及链接

// blackboycpp(AT)gmail.com
// QQ群: 135202158

前一篇文章已经实现了基本功能,但有一个问题,就是需要读写硬盘上的文件。

如果实在不想读写文件,可以将进程启动信息中的输出重定向到一个匿名管道,再从管道中读取进程的输出即可。

 

[cpp] view
plain copy

 print?

void CCPTFDlg::OnBnClickedBtnPing()  

{  

    UpdateData(TRUE);  

  

    BOOL bRet = FALSE;  

    // 拼接要执行的命令行,如"ping.exe www.google.com"  

    CString sAddr;  

    GetDlgItem(IDC_EDIT_ADDR)->GetWindowText(sAddr);  

    CString sCmdLine = _T("ping.exe ") + sAddr;  

      

    // 设置管道句柄安全属性  

    SECURITY_ATTRIBUTES sa;  

    ::ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));  

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);  

    sa.bInheritHandle = TRUE;       // 必须为TRUE  

    sa.lpSecurityDescriptor = NULL;  

  

    // 创建匿名管道  

    HANDLE hPipeRead, hPipeWrite;  

    bRet = ::CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0);  

    ASSERT(bRet == TRUE);  

  

    // 设置进程的启动信息,这是一个输入参数  

    STARTUPINFO si;  

    ::ZeroMemory(&si, sizeof(STARTUPINFO));  

    si.cb = sizeof(STARTUPINFO);  

    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;   // 这个必须设置,否则仍将显示窗口  

    si.hStdOutput = hPipeWrite; // 设置为写管道  

    si.wShowWindow = SW_HIDE;   // 不显示窗口  

  

    // 设置进程信息,这是一个输出参数。我们需要从这个结构中取得创建成功的进程及其主线程的句柄  

    PROCESS_INFORMATION pi;  

    ::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));  

      

    // 使用刚才设置的各个参数创建隐秘的进程  

    // 此进程将把ping程序运行的结果写到管道   

    bRet = ::CreateProcess(NULL, sCmdLine.GetBuffer(), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi);  

    ASSERT(bRet == TRUE);  

      

    // 等待进程对象的结束。即等待ping程序运行完成  

    ::WaitForSingleObject(pi.hProcess, INFINITE);  

    // 结束进程  

    ::CloseHandle(pi.hProcess);  

    ::CloseHandle(pi.hThread);  

  

    // 从管道读取上述进程的输出,并显示于界面  

    char buffer[1024] = {0};  

    DWORD dwBytesRead;  

    bRet = ::ReadFile(hPipeRead, buffer, 1023, &dwBytesRead, 0);  

    ASSERT(bRet == TRUE);  

    ASSERT(dwBytesRead > 0);  

    GetDlgItem(IDC_EDIT_OUT)->SetWindowText(CString(buffer));  

  

    // 关闭管道  

    ::CloseHandle(hPipeRead);  

    ::CloseHandle(hPipeWrite);  

}  

界面和其余部分与上一篇提到的小例子相同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: