c++ - 使用 PPID 欺骗路由进程的标准输出
问题描述
我试图编写一个CreateProcess()
用于执行CMD
命令并将重定向stdout
到命名管道的代码。我想添加一个功能来欺骗父 PID,以便 cmd 将在 explorer.exe 下生成。每个功能都可以独立工作,但是当我尝试合并它们时,它就不起作用了。
标准输出路由:
int main()
{
HANDLE hStdout_Rd = NULL;
HANDLE hStdout_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
CreatePipe(&hStdout_Rd, &hStdout_Wr, &saAttr, NULL);
SetHandleInformation(hStdout_Rd, HANDLE_FLAG_INHERIT, 0);
//Set startup info
STARTUPINFO si;
ZeroMemory(&si, (sizeof(STARTUPINFO)));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdError = hStdout_Wr;
si.hStdOutput = hStdout_Wr;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
CString cmd;
if (CreateProcess(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
//Great success read pipe contents
}
CloseHandle(hStdout_Rd);
CloseHandle(hStdout_Wr);
}
PPID 欺骗:
int main() {
CString cmd;
STARTUPINFOEXA sInfoEX;
PROCESS_INFORMATION pInfo;
SIZE_T sizeT;
HANDLE expHandle = OpenProcess(PROCESS_ALL_ACCESS, false, getParentProcessID());
ZeroMemory(&sInfoEX, sizeof(STARTUPINFOEXA));
InitializeProcThreadAttributeList(NULL, 1, 0, &sizeT);
sInfoEX.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, sizeT);
InitializeProcThreadAttributeList(sInfoEX.lpAttributeList, 1, 0, &sizeT);
UpdateProcThreadAttribute(sInfoEX.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &expHandle, sizeof(HANDLE), NULL, NULL);
sInfoEX.StartupInfo.cb = sizeof(STARTUPINFOEXA);
CreateProcessA(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast<LPSTARTUPINFOA>(&sInfoEX), &pInfo);
return 0;
}
全部一起:
int main() {
HANDLE hStdout_Rd = NULL;
HANDLE hStdout_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
CString cmd;
STARTUPINFOEXA sInfoEX;
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo, sizeof(PROCESS_INFORMATION));
SIZE_T sizeT;
HANDLE expHandle = OpenProcess(PROCESS_ALL_ACCESS, false, getParentProcessID());
ZeroMemory(&sInfoEX, sizeof(STARTUPINFOEXA));
sInfoEX.StartupInfo = sizeof(STARTUPINFO);
sInfoEX.StartupInfo = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
sInfoEX.StartupInfo = hStdout_Wr;
sInfoEX.StartupInfo = hStdout_Wr;
sInfoEX.StartupInfo = SW_HIDE;
InitializeProcThreadAttributeList(NULL, 1, 0, &sizeT);
sInfoEX.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, sizeT);
InitializeProcThreadAttributeList(sInfoEX.lpAttributeList, 1, 0, &sizeT);
UpdateProcThreadAttribute(sInfoEX.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &expHandle, sizeof(HANDLE), NULL, NULL);
sInfoEX.StartupInfo.cb = sizeof(STARTUPINFOEXA);
if (CreateProcessA(NULL, cmd.GetBuffer(), NULL, NULL, TRUE, CREATE_SUSPENDED | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast<LPSTARTUPINFOA>(&sInfoEX), &pInfo))
{
//Read pipe contents
}
return 0;
}
有什么我想念的吗?
解决方案
每个功能都可以独立工作,但是当我尝试合并它们时,它就不起作用了。
匿名管道是一种未命名的单向管道,通常在父进程和子进程之间传输数据。要使用管道进行通信,管道服务器必须将管道句柄传递给另一个进程。通常,这是通过继承完成的;也就是说,该进程允许该句柄被子进程继承。
由于您将子进程的父进程更改为 explorer.exe。最初的父子关系不再存在。所以新进程无法访问旧父进程中创建的handle
( )。hStdout_Wr
这就是它停止工作的原因。
为达到您的目的:
- 一种方法是:“进程还可以使用 DuplicateHandle 函数复制管道句柄,并使用某种形式的进程间通信(例如 DDE 或共享内存)将其发送到不相关的进程。 ”
- 另一种方法是使用命名管道。任何进程都可以访问命名管道,但需要经过安全检查,这使得命名管道成为相关或不相关进程之间的一种简单通信形式。
推荐阅读
- python - BSC 代币浏览器
- sql - postgres 表的分区键失败错误
- java - 如何将列表重置为其初始状态
- java - 在android中按下按钮时进行HTTP Get调用
- spring - 在 JPA Spring Boot 中保持多对一关系
- amazon-web-services - 如何迭代 Terraform 中的“计数”资源?
- python - 在不复制的情况下检查变量的变化
- xml - 表 (xxxxx) 在嵌套关系中不能是其自身的子表
- python - 我想在我暂停的地方恢复这个循环。但它看起来不可能(Python 循环)
- git - 如何根据我们合并的分支增加版本次要/补丁