伪造父PID调用CreateProcess时出现0xc0000142错误求助
伪造父PID启动自定义程序时出现0xc0000142错误的解决办法
问题描述
我尝试通过伪造父PID的方式启动程序,自定义了一个仅输出Hello World的test.exe,但用代码伪造cmd.exe的PID作为父进程启动test.exe时,出现“应用程序无法正常启动(0xc0000142)”错误;启动notepad、calc等系统程序则正常运行,求解决办法。
原代码
主程序代码
int main(int argc, char* argv[]) { STARTUPINFOEX si = { sizeof(si) }; PROCESS_INFORMATION pi; SIZE_T attributeSize; InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize); si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize); InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize); DWORD dwParentPID = 14256; //cmd.exe pid HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwParentPID); if (!hProcess) { return -1; } UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(HANDLE), NULL, NULL); LPCWSTR spawnProcess1 = L"C:\Users\user\source\repos\random_testing\x64\Debug\test.exe"; CreateProcess(spawnProcess1, NULL, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFO*)&si, &pi); return 0; }
test.exe代码
int main(int argc, char* argv[]) { printf("Hello World!\n"); getchar(); return 1; }
问题原因及解决办法
1. 权限冗余与句柄问题
原代码中OpenProcess使用PROCESS_ALL_ACCESS权限过高,伪造父进程仅需PROCESS_CREATE_PROCESS权限。过高权限可能导致获取进程句柄失败,或后续启动时权限冲突。
- 修正:将
OpenProcess调用改为:HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, dwParentPID);
2. 属性列表初始化错误
原代码两次调用InitializeProcThreadAttributeList的参数逻辑有误,第二次初始化未正确使用已分配的内存和获取到的大小,且未处理初始化失败的情况。此外,未在程序结束时释放属性列表,存在内存泄漏。
- 修正:完善属性列表的初始化与释放逻辑(参考下方修正后的完整代码)。
3. 路径转义错误
原代码中的路径字符串L"C:\Users\user\source\repos\random_testing\x64\Debug\test.exe"未对反斜杠进行转义,会导致系统无法正确解析路径,进而触发启动错误。
- 修正:将路径中的单个反斜杠改为双反斜杠:
LPCWSTR spawnProcess1 = L"C:\\Users\\user\\source\\repos\\random_testing\\x64\\Debug\\test.exe";
4. 调试版本依赖问题
Debug版本的test.exe依赖VC++调试运行库(如vcruntime140d.dll),而cmd.exe的运行环境可能未加载这些调试库,导致test.exe启动时找不到依赖文件。
- 解决:
- 将test.exe编译为Release版本(Release版本依赖的是发布版运行库,兼容性更强);
- 若需使用Debug版本,将对应的调试运行库文件复制到test.exe所在目录。
5. 缺失错误检查
原代码未对CreateProcess等关键API的返回值进行检查,无法获取具体错误码来定位问题。
- 修正:添加错误检查逻辑,例如:
if (!CreateProcess(spawnProcess1, NULL, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFO*)&si, &pi)) { printf("CreateProcess failed: %lu\n", GetLastError()); }
修正后的完整主程序代码
#include <windows.h> #include <stdio.h> int main(int argc, char* argv[]) { STARTUPINFOEX si = { sizeof(si) }; PROCESS_INFORMATION pi; SIZE_T attributeSize = 0; // 获取属性列表所需内存大小 if (!InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("InitializeProcThreadAttributeList failed: %lu\n", GetLastError()); return -1; } } // 分配内存并初始化属性列表 si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, attributeSize); if (!si.lpAttributeList) { printf("HeapAlloc failed: %lu\n", GetLastError()); return -1; } if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize)) { printf("InitializeProcThreadAttributeList failed: %lu\n", GetLastError()); HeapFree(GetProcessHeap(), 0, si.lpAttributeList); return -1; } DWORD dwParentPID = 14256; // cmd.exe的PID HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, dwParentPID); if (!hProcess) { printf("OpenProcess failed: %lu\n", GetLastError()); HeapFree(GetProcessHeap(), 0, si.lpAttributeList); return -1; } // 更新父进程属性 if (!UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(HANDLE), NULL, NULL)) { printf("UpdateProcThreadAttribute failed: %lu\n", GetLastError()); CloseHandle(hProcess); HeapFree(GetProcessHeap(), 0, si.lpAttributeList); return -1; } // 使用转义后的路径,建议使用Release版本的test.exe LPCWSTR spawnProcess1 = L"C:\\Users\\user\\source\\repos\\random_testing\\x64\\Release\\test.exe"; if (!CreateProcess(spawnProcess1, NULL, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFO*)&si, &pi)) { printf("CreateProcess failed: %lu\n", GetLastError()); CloseHandle(hProcess); HeapFree(GetProcessHeap(), 0, si.lpAttributeList); return -1; } // 清理资源 CloseHandle(hProcess); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); DeleteProcThreadAttributeList(si.lpAttributeList); HeapFree(GetProcessHeap(), 0, si.lpAttributeList); return 0; }
内容的提问来源于stack exchange,提问作者nahjoh44
相关产品推荐
相关产品推荐

