使用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);
}
界面和其余部分与上一篇提到的小例子相同。
// 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);
}
界面和其余部分与上一篇提到的小例子相同。
相关文章推荐
- 使用CreateProcess函数实现隐秘的程序调用之二:使用匿名管道
- 使用CreateProcess函数实现隐秘的程序调用
- Linux:使用rpcgen实现64位程序调用32位库函数
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- 使用CreateProcess函数运行其他程序
- 使用CreateProcess函数运行其他程序
- 【原译】使用匿名函数增强程序的可读性
- 怎样使用gprof和oprofile来分析 linux程序的性能(每个函数的调用次数与耗时)
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- C程序使用不同函数调用约定调用汇编子过程
- 使用“事件监听/链式事件处理方式”实现window.onload同时调用多个函数
- 程序性能调优之 怎样使用gprof和oprofile来分析 linux程序的性能(每个函数的调用次数与耗时)
- 使用pipe()与fork()函数通过管道实现父子进程之间的通信
- linux 系统下使用C程序实现时钟的函数
- 使用JNI技术实现JAVA程序调用dll
- 匿名管道实现获取控制台程序输出
- 使用JNI技术实现JAVA程序调用dll
- 使用sql Server 的函数功能返回 表,方便在程序中调用
- 使用JNI技术实现JAVA程序调用dll
- 使用JNI技术实现JAVA程序调用dll