CLI tool for running Playbooks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

985 lines
40 KiB

1 year ago
6 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
1 year ago
6 months ago
1 year ago
1 year ago
6 months ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
1 year ago
1 year ago
1 year ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
6 months ago
1 year ago
9 months ago
1 year ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Management;
  8. using System.Net.Http;
  9. using System.Reflection;
  10. using System.Runtime.InteropServices;
  11. using System.Security.Principal;
  12. using System.ServiceProcess;
  13. using System.Text.RegularExpressions;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using System.Windows;
  17. using System.Windows.Interop;
  18. using Microsoft.Win32;
  19. using TrustedUninstaller.Shared.Actions;
  20. using TrustedUninstaller.Shared.Tasks;
  21. namespace TrustedUninstaller.Shared
  22. {
  23. using SLID = Guid; //SLID id declared as typedef GUID SLID; in slpublic.h
  24. public static class WinUtil
  25. {
  26. public enum SHSTOCKICONID : uint
  27. {
  28. SIID_DOCNOASSOC = 0,
  29. SIID_DOCASSOC = 1,
  30. SIID_APPLICATION = 2,
  31. SIID_FOLDER = 3,
  32. SIID_FOLDEROPEN = 4,
  33. SIID_DRIVE525 = 5,
  34. SIID_DRIVE35 = 6,
  35. SIID_DRIVEREMOVE = 7,
  36. SIID_DRIVEFIXED = 8,
  37. SIID_DRIVENET = 9,
  38. SIID_DRIVENETDISABLED = 10,
  39. SIID_DRIVECD = 11,
  40. SIID_DRIVERAM = 12,
  41. SIID_WORLD = 13,
  42. SIID_SERVER = 15,
  43. SIID_PRINTER = 16,
  44. SIID_MYNETWORK = 17,
  45. SIID_FIND = 22,
  46. SIID_HELP = 23,
  47. SIID_SHARE = 28,
  48. SIID_LINK = 29,
  49. SIID_SLOWFILE = 30,
  50. SIID_RECYCLER = 31,
  51. SIID_RECYCLERFULL = 32,
  52. SIID_MEDIACDAUDIO = 40,
  53. SIID_LOCK = 47,
  54. SIID_AUTOLIST = 49,
  55. SIID_PRINTERNET = 50,
  56. SIID_SERVERSHARE = 51,
  57. SIID_PRINTERFAX = 52,
  58. SIID_PRINTERFAXNET = 53,
  59. SIID_PRINTERFILE = 54,
  60. SIID_STACK = 55,
  61. SIID_MEDIASVCD = 56,
  62. SIID_STUFFEDFOLDER = 57,
  63. SIID_DRIVEUNKNOWN = 58,
  64. SIID_DRIVEDVD = 59,
  65. SIID_MEDIADVD = 60,
  66. SIID_MEDIADVDRAM = 61,
  67. SIID_MEDIADVDRW = 62,
  68. SIID_MEDIADVDR = 63,
  69. SIID_MEDIADVDROM = 64,
  70. SIID_MEDIACDAUDIOPLUS = 65,
  71. SIID_MEDIACDRW = 66,
  72. SIID_MEDIACDR = 67,
  73. SIID_MEDIACDBURN = 68,
  74. SIID_MEDIABLANKCD = 69,
  75. SIID_MEDIACDROM = 70,
  76. SIID_AUDIOFILES = 71,
  77. SIID_IMAGEFILES = 72,
  78. SIID_VIDEOFILES = 73,
  79. SIID_MIXEDFILES = 74,
  80. SIID_FOLDERBACK = 75,
  81. SIID_FOLDERFRONT = 76,
  82. SIID_SHIELD = 77,
  83. SIID_WARNING = 78,
  84. SIID_INFO = 79,
  85. SIID_ERROR = 80,
  86. SIID_KEY = 81,
  87. SIID_SOFTWARE = 82,
  88. SIID_RENAME = 83,
  89. SIID_DELETE = 84,
  90. SIID_MEDIAAUDIODVD = 85,
  91. SIID_MEDIAMOVIEDVD = 86,
  92. SIID_MEDIAENHANCEDCD = 87,
  93. SIID_MEDIAENHANCEDDVD = 88,
  94. SIID_MEDIAHDDVD = 89,
  95. SIID_MEDIABLURAY = 90,
  96. SIID_MEDIAVCD = 91,
  97. SIID_MEDIADVDPLUSR = 92,
  98. SIID_MEDIADVDPLUSRW = 93,
  99. SIID_DESKTOPPC = 94,
  100. SIID_MOBILEPC = 95,
  101. SIID_USERS = 96,
  102. SIID_MEDIASMARTMEDIA = 97,
  103. SIID_MEDIACOMPACTFLASH = 98,
  104. SIID_DEVICECELLPHONE = 99,
  105. SIID_DEVICECAMERA = 100,
  106. SIID_DEVICEVIDEOCAMERA = 101,
  107. SIID_DEVICEAUDIOPLAYER = 102,
  108. SIID_NETWORKCONNECT = 103,
  109. SIID_INTERNET = 104,
  110. SIID_ZIPFILE = 105,
  111. SIID_SETTINGS = 106,
  112. SIID_DRIVEHDDVD = 132,
  113. SIID_DRIVEBD = 133,
  114. SIID_MEDIAHDDVDROM = 134,
  115. SIID_MEDIAHDDVDR = 135,
  116. SIID_MEDIAHDDVDRAM = 136,
  117. SIID_MEDIABDROM = 137,
  118. SIID_MEDIABDR = 138,
  119. SIID_MEDIABDRE = 139,
  120. SIID_CLUSTEREDDRIVE = 140,
  121. SIID_MAX_ICONS = 175
  122. }
  123. [Flags]
  124. public enum SHGSI : uint
  125. {
  126. SHGSI_ICONLOCATION = 0,
  127. SHGSI_ICON = 0x000000100,
  128. SHGSI_SYSICONINDEX = 0x000004000,
  129. SHGSI_LINKOVERLAY = 0x000008000,
  130. SHGSI_SELECTED = 0x000010000,
  131. SHGSI_LARGEICON = 0x000000000,
  132. SHGSI_SMALLICON = 0x000000001,
  133. SHGSI_SHELLICONSIZE = 0x000000004
  134. }
  135. [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  136. public struct SHSTOCKICONINFO
  137. {
  138. public UInt32 cbSize;
  139. public IntPtr hIcon;
  140. public Int32 iSysIconIndex;
  141. public Int32 iIcon;
  142. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260 /*MAX_PATH*/)]
  143. public string szPath;
  144. }
  145. [DllImport("Shell32.dll", SetLastError = false)]
  146. public static extern Int32 SHGetStockIconInfo(SHSTOCKICONID siid, SHGSI uFlags, ref SHSTOCKICONINFO psii);
  147. [DllImport("user32.dll", SetLastError = true)]
  148. public static extern bool DestroyIcon(IntPtr hIcon);
  149. public static bool IsAdministrator()
  150. {
  151. using var identity = WindowsIdentity.GetCurrent();
  152. var principal = new WindowsPrincipal(identity);
  153. return principal.IsInRole(WindowsBuiltInRole.Administrator);
  154. }
  155. public static string GetUserName()
  156. {
  157. var wi = WindowsIdentity.GetCurrent();
  158. var groups = from g in wi.Groups
  159. select new SecurityIdentifier(g.Value)
  160. .Translate(typeof(NTAccount)).Value;
  161. var msAccount = (from g in groups
  162. where g.StartsWith(@"MicrosoftAccount\")
  163. select g).FirstOrDefault();
  164. return msAccount == null ? Environment.UserName : msAccount.Substring(@"MicrosoftAccount\".Length);
  165. }
  166. public static bool IsLocalAccount()
  167. {
  168. var wi = WindowsIdentity.GetCurrent();
  169. var groups = from g in wi.Groups
  170. select new SecurityIdentifier(g.Value)
  171. .Translate(typeof(NTAccount)).Value;
  172. var msAccount = (from g in groups
  173. where g.StartsWith(@"MicrosoftAccount\")
  174. select g).FirstOrDefault();
  175. return msAccount == null;
  176. }
  177. public enum SL_GENUINE_STATE
  178. {
  179. SL_GEN_STATE_IS_GENUINE = 0,
  180. // SL_GEN_STATE_INVALID_LICENSE = 1,
  181. // SL_GEN_STATE_TAMPERED = 2,
  182. SL_GEN_STATE_LAST = 3
  183. }
  184. [DllImport("Slwga.dll", EntryPoint = "SLIsGenuineLocal", CharSet = CharSet.None, ExactSpelling =
  185. false, SetLastError = false, PreserveSig = true, CallingConvention = CallingConvention.Winapi, BestFitMapping =
  186. false, ThrowOnUnmappableChar = false)]
  187. [PreserveSigAttribute()]
  188. internal static extern uint SLIsGenuineLocal(ref SLID slid, [In, Out] ref SL_GENUINE_STATE genuineState, IntPtr val3);
  189. public static bool IsGenuineWindows()
  190. {
  191. // Microsoft-Windows-Security-SPP GUID
  192. // http://technet.microsoft.com/en-us/library/dd772270.aspx
  193. var windowsSlid = new SLID("55c92734-d682-4d71-983e-d6ec3f16059f");
  194. var genuineState = SL_GENUINE_STATE.SL_GEN_STATE_LAST;
  195. var resultInt = SLIsGenuineLocal(ref windowsSlid, ref genuineState, IntPtr.Zero);
  196. #if DEBUG
  197. return true;
  198. #else
  199. return resultInt == 0 && genuineState == SL_GENUINE_STATE.SL_GEN_STATE_IS_GENUINE;
  200. #endif
  201. }
  202. private static IEnumerable<string> GetWindowsGroups(WindowsIdentity id)
  203. {
  204. var irc = id.Groups ?? new IdentityReferenceCollection();
  205. return irc.Select(ir => (NTAccount) ir.Translate(typeof(NTAccount))).Select(acc => acc.Value).ToList();
  206. }
  207. public static bool HasWindowsGroup(string groupName)
  208. {
  209. var appDomain = Thread.GetDomain();
  210. appDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
  211. var currentPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal;
  212. var groups = GetWindowsGroups((WindowsIdentity) currentPrincipal.Identity);
  213. return groups.Any(group => group == groupName);
  214. }
  215. public static bool IsTrustedInstaller()
  216. {
  217. return HasWindowsGroup(@"NT SERVICE\TrustedInstaller");
  218. }
  219. public static bool RelaunchAsTrustedInstaller()
  220. {
  221. var controller = new ServiceController("TrustedInstaller");
  222. if (controller.Status != ServiceControllerStatus.Running)
  223. {
  224. controller.Start();
  225. controller.WaitForStatus(ServiceControllerStatus.Running);
  226. }
  227. var targetProcess = Process.GetProcessesByName("TrustedInstaller").FirstOrDefault();
  228. if (targetProcess == null)
  229. {
  230. return false;
  231. }
  232. var currentProcess = Process.GetCurrentProcess();
  233. var currentModule = currentProcess.MainModule;
  234. if (currentModule == null)
  235. {
  236. return false;
  237. }
  238. var currentExecutable = currentModule.FileName;
  239. return NativeProcess.StartProcess(currentExecutable, targetProcess.Id, AmeliorationUtil.Playbook.Path);
  240. }
  241. [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  242. public static extern Boolean ChangeServiceConfig(
  243. IntPtr hService,
  244. UInt32 nServiceType,
  245. UInt32 nStartType,
  246. UInt32 nErrorControl,
  247. String lpBinaryPathName,
  248. String lpLoadOrderGroup,
  249. IntPtr lpdwTagId,
  250. [In] char[] lpDependencies,
  251. String lpServiceStartName,
  252. String lpPassword,
  253. String lpDisplayName);
  254. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  255. static extern IntPtr OpenService(
  256. IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
  257. [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode,
  258. SetLastError = true)]
  259. public static extern IntPtr OpenSCManager(
  260. string machineName, string databaseName, uint dwAccess);
  261. [DllImport("advapi32.dll", EntryPoint = "CloseServiceHandle")]
  262. public static extern int CloseServiceHandle(IntPtr hSCObject);
  263. private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
  264. private const uint SERVICE_QUERY_CONFIG = 0x00000001;
  265. private const uint SERVICE_CHANGE_CONFIG = 0x00000002;
  266. private const uint SC_MANAGER_ALL_ACCESS = 0x000F003F;
  267. public static void ChangeStartMode(ServiceController svc, ServiceStartMode mode)
  268. {
  269. var scManagerHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
  270. if (scManagerHandle == IntPtr.Zero)
  271. {
  272. throw new ExternalException("Open Service Manager Error");
  273. }
  274. var serviceHandle = OpenService(
  275. scManagerHandle,
  276. svc.ServiceName,
  277. SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
  278. if (serviceHandle == IntPtr.Zero)
  279. {
  280. throw new ExternalException("Open Service Error");
  281. }
  282. var result = ChangeServiceConfig(
  283. serviceHandle,
  284. SERVICE_NO_CHANGE,
  285. (uint)mode,
  286. SERVICE_NO_CHANGE,
  287. null,
  288. null,
  289. IntPtr.Zero,
  290. null,
  291. null,
  292. null,
  293. null);
  294. if (result == false)
  295. {
  296. var nError = Marshal.GetLastWin32Error();
  297. var win32Exception = new Win32Exception(nError);
  298. throw new ExternalException("Could not change service start type: "
  299. + win32Exception.Message);
  300. }
  301. CloseServiceHandle(serviceHandle);
  302. CloseServiceHandle(scManagerHandle);
  303. }
  304. [StructLayout(LayoutKind.Sequential)]
  305. struct RM_UNIQUE_PROCESS
  306. {
  307. public int dwProcessId;
  308. public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
  309. }
  310. const int RmRebootReasonNone = 0;
  311. const int CCH_RM_MAX_APP_NAME = 255;
  312. const int CCH_RM_MAX_SVC_NAME = 63;
  313. enum RM_APP_TYPE
  314. {
  315. RmUnknownApp = 0,
  316. RmMainWindow = 1,
  317. RmOtherWindow = 2,
  318. RmService = 3,
  319. RmExplorer = 4,
  320. RmConsole = 5,
  321. RmCritical = 1000
  322. }
  323. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  324. struct RM_PROCESS_INFO
  325. {
  326. public RM_UNIQUE_PROCESS Process;
  327. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
  328. public string strAppName;
  329. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
  330. public string strServiceShortName;
  331. public RM_APP_TYPE ApplicationType;
  332. public uint AppStatus;
  333. public uint TSSessionId;
  334. [MarshalAs(UnmanagedType.Bool)] public bool bRestartable;
  335. }
  336. [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
  337. static extern int RmRegisterResources(uint pSessionHandle,
  338. UInt32 nFiles,
  339. string[] rgsFilenames,
  340. UInt32 nApplications,
  341. [In] RM_UNIQUE_PROCESS[] rgApplications,
  342. UInt32 nServices,
  343. string[] rgsServiceNames);
  344. [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
  345. static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
  346. [DllImport("rstrtmgr.dll")]
  347. static extern int RmEndSession(uint pSessionHandle);
  348. [DllImport("rstrtmgr.dll")]
  349. static extern int RmGetList(uint dwSessionHandle,
  350. out uint pnProcInfoNeeded,
  351. ref uint pnProcInfo,
  352. [In, Out] RM_PROCESS_INFO[] rgAffectedApps,
  353. ref uint lpdwRebootReasons);
  354. /// <summary>
  355. /// Find out what process(es) have a lock on the specified file.
  356. /// </summary>
  357. /// <param name="path">Path of the file.</param>
  358. /// <returns>Processes locking the file</returns>
  359. /// <remarks>See also:
  360. /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx
  361. /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing)
  362. ///
  363. /// </remarks>
  364. public static List<Process> WhoIsLocking(string path)
  365. {
  366. string key = Guid.NewGuid().ToString();
  367. List<Process> processes = new List<Process>();
  368. int res = RmStartSession(out uint handle, 0, key);
  369. if (res != 0)
  370. {
  371. ErrorLogger.WriteToErrorLog("Could not begin restart session. Unable to determine file locker.",
  372. Environment.StackTrace, $"Error while attempting to get locking processes of file {path}");
  373. throw new Exception("Could not begin restart session. Unable to determine file locker.");
  374. }
  375. try
  376. {
  377. const int ERROR_MORE_DATA = 234;
  378. uint pnProcInfoNeeded = 0,
  379. pnProcInfo = 0,
  380. lpdwRebootReasons = RmRebootReasonNone;
  381. string[] resources = new string[] { path }; // Just checking on one resource.
  382. res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
  383. if (res != 0) throw new Exception("Could not register resource.");
  384. //Note: there's a race condition here -- the first call to RmGetList() returns
  385. // the total number of process. However, when we call RmGetList() again to get
  386. // the actual processes this number may have increased.
  387. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
  388. if (res == ERROR_MORE_DATA)
  389. {
  390. // Create an array to store the process results
  391. RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded + 3];
  392. pnProcInfo = pnProcInfoNeeded;
  393. // Get the list
  394. res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
  395. if (res == 0)
  396. {
  397. processes = new List<Process>((int)pnProcInfo);
  398. // Enumerate all of the results and add them to the
  399. // list to be returned
  400. for (int i = 0; i < pnProcInfo; i++)
  401. {
  402. try
  403. {
  404. processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
  405. }
  406. // catch the error -- in case the process is no longer running
  407. catch (ArgumentException) { }
  408. }
  409. }
  410. else throw new Exception("Could not list processes locking resource: " + res);
  411. }
  412. else if (res != 0)
  413. throw new Exception("Could not list processes locking resource. Could not get size of result." + $" Result value: {res}");
  414. }
  415. finally
  416. {
  417. RmEndSession(handle);
  418. }
  419. return processes;
  420. }
  421. /// <summary>
  422. /// Finds active anti-viruses in the system.
  423. /// </summary>
  424. /// <returns>a list of ProviderStatus.</returns>
  425. /// <remarks>See also:
  426. /// https://jdhitsolutions.com/blog/powershell/5187/get-antivirus-product-status-with-powershell/
  427. /// https://docs.microsoft.com/en-us/windows/win32/api/iwscapi/ne-iwscapi-wsc_security_product_state?redirectedfrom=MSDN
  428. /// https://mspscripts.com/get-installed-antivirus-information-2/
  429. /// https://social.msdn.microsoft.com/Forums/pt-BR/6501b87e-dda4-4838-93c3-244daa355d7c/wmisecuritycenter2-productstate?forum=vblanguage
  430. /// https://stackoverflow.com/questions/4700897/wmi-security-center-productstate-clarification/4711211
  431. /// https://blogs.msdn.microsoft.com/alejacma/2008/05/12/how-to-get-antivirus-information-with-wmi-vbscript/#comment-442
  432. /// https://www.magnumdb.com/search?q=parent:WSC_SECURITY_PRODUCT_STATE
  433. /// https://web.archive.org/web/20190121133247/http://neophob.com/2010/03/wmi-query-windows-securitycenter2/
  434. /// </remarks>
  435. public static List<ProviderStatus> GetEnabledAvList(bool ensureWMI = true)
  436. {
  437. if (ensureWMI)
  438. {
  439. var svc = new ServiceController("Winmgmt");
  440. ChangeStartMode(svc, ServiceStartMode.Automatic);
  441. }
  442. List<ProviderStatus> avList = new List<ProviderStatus>();
  443. string computer = Environment.MachineName;
  444. string wmipath = @"\\" + computer + @"\root\SecurityCenter2";
  445. string query = @"SELECT * FROM AntivirusProduct WHERE displayName != ""Windows Defender""";
  446. try
  447. {
  448. using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipath, query))
  449. {
  450. ManagementObjectCollection results = searcher.Get();
  451. foreach (var o in results)
  452. {
  453. // You can find if an AV is active or not by accessing the hex code of the productState
  454. // (from the right) 19th bit == Anti Virus is on
  455. // (from the right) 13th bit == On Access Scanning
  456. // 00000000 00000[1]10 000[1]0000 000[0]0000
  457. // 19th bit (yes) = Av on
  458. // 13th bit (yes) = On Access Scanning
  459. // The third byte defines if the .dat file is up-to-date
  460. var result = (ManagementObject)o;
  461. var productState = result["productState"];
  462. string hex = Hex(Convert.ToInt32(productState));
  463. string bin = Binary(Convert.ToInt32(productState));
  464. string reversed = Reverse(bin);
  465. var enabled = GetBit(reversed, 18);
  466. var scanning = GetBit(reversed, 12);
  467. var outdated = GetBit(reversed, 4);
  468. static string Binary(int value)
  469. {
  470. return Convert.ToString(value, 2).PadLeft(24, '0');
  471. }
  472. static string Hex(int value)
  473. {
  474. return Convert.ToString(value, 16).PadLeft(6, '0');
  475. }
  476. static bool GetBit(string value, int index)
  477. {
  478. return value.Substring(index, 1).Equals("1");
  479. }
  480. static string Reverse(string value)
  481. {
  482. return new string(value.Reverse().ToArray());
  483. }
  484. if (!enabled) continue;
  485. var av = new ProviderStatus()
  486. {
  487. DisplayName = result["displayName"].ToString(),
  488. AVStatus = enabled ? AVStatusFlags.Enabled : AVStatusFlags.Unknown,
  489. SecurityProvider = ProviderFlags.ANTIVIRUS,
  490. SignatureStatus = outdated ? SignatureStatusFlags.OutOfDate : SignatureStatusFlags.UpToDate,
  491. FileExists = File.Exists(result["pathToSignedProductExe"].ToString())
  492. };
  493. avList.Add(av);
  494. }
  495. }
  496. }
  497. catch (Exception e)
  498. {
  499. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "Error while retrieving the AV list.");
  500. }
  501. return avList;
  502. }
  503. //Checks if Visual C++ redistributable is installed.
  504. public static bool IsVCInstalled()
  505. {
  506. string dependenciesPath = @"SOFTWARE\Classes\Installer\Dependencies";
  507. using (RegistryKey dependencies = Registry.LocalMachine.OpenSubKey(dependenciesPath))
  508. {
  509. if (dependencies == null) return false;
  510. foreach (string subKeyName in dependencies.GetSubKeyNames().Where(n => !n.ToLower().Contains("dotnet") && !n.ToLower().Contains("microsoft")))
  511. {
  512. using (RegistryKey subDir = Registry.LocalMachine.OpenSubKey(dependenciesPath + "\\" + subKeyName))
  513. {
  514. var value = subDir.GetValue("DisplayName")?.ToString() ?? null;
  515. if (string.IsNullOrEmpty(value))
  516. {
  517. continue;
  518. }
  519. if (Environment.Is64BitOperatingSystem)
  520. {
  521. if (Regex.IsMatch(value, @"C\+\+ 2015.*\((x64|x86)\)"))
  522. {
  523. return true;
  524. }
  525. }
  526. else
  527. {
  528. if (Regex.IsMatch(value, @"C\+\+ 2015.*\(x86\)"))
  529. {
  530. return true;
  531. }
  532. }
  533. }
  534. }
  535. }
  536. return false;
  537. }
  538. public static async Task RemoveProtectionAsync()
  539. {
  540. var cmdAction = new CmdAction();
  541. if (AmeliorationUtil.UseKernelDriver)
  542. {
  543. /*
  544. if (!IsVCInstalled())
  545. {
  546. Console.WriteLine(Environment.NewLine + "Installing VC 15...");
  547. try
  548. {
  549. //Install Visual C++ 2015 redistributable package silently
  550. cmdAction.Command = "vc_redist.x64.exe /q /norestart";
  551. cmdAction.RunTaskOnMainThread();
  552. }
  553. catch (Exception e)
  554. {
  555. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "Error while installing VC 15.");
  556. throw;
  557. }
  558. }
  559. */
  560. try
  561. {
  562. Console.WriteLine(Environment.NewLine + "Installing driver...");
  563. cmdAction.Command = Environment.Is64BitOperatingSystem
  564. ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -installkph"
  565. : $"ProcessHacker\\x86\\ProcessHacker.exe -s -installkph";
  566. cmdAction.RunTaskOnMainThread();
  567. await AmeliorationUtil.SafeRunAction(new RegistryValueAction()
  568. { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Value = "DeleteFlag", Type = RegistryValueType.REG_DWORD, Data = 1 });
  569. }
  570. catch (Exception e)
  571. {
  572. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "ProcessHacker ran into an error while installing its driver.");
  573. throw;
  574. }
  575. }
  576. }
  577. public static void CheckKph()
  578. {
  579. try
  580. {
  581. if (!AmeliorationUtil.UseKernelDriver || new RegistryKeyAction() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Operation = RegistryKeyOperation.Add }.GetStatus() == UninstallTaskStatus.Completed)
  582. return;
  583. Console.WriteLine(Environment.NewLine + "Installing driver...");
  584. var cmdAction = new CmdAction();
  585. cmdAction.Command = Environment.Is64BitOperatingSystem
  586. ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -installkph"
  587. : $"ProcessHacker\\x86\\ProcessHacker.exe -s -installkph";
  588. cmdAction.RunTaskOnMainThread();
  589. AmeliorationUtil.SafeRunAction(new RegistryValueAction()
  590. { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\KProcessHacker2", Value = "DeleteFlag", Type = RegistryValueType.REG_DWORD, Data = 1 }).Wait();
  591. }
  592. catch (Exception e)
  593. {
  594. ErrorLogger.WriteToErrorLog("Error checking kernel driver: " + e.Message, e.StackTrace, "Warning");
  595. }
  596. }
  597. private const int GWL_STYLE = -16;
  598. private const int WS_SYSMENU = 0x80000;
  599. [DllImport("user32.dll", SetLastError = true)]
  600. private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
  601. [DllImport("user32.dll")]
  602. private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
  603. //public static void RemoveCloseButton(Window window)
  604. //{
  605. //var hwnd = new WindowInteropHelper(window).Handle;
  606. //SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
  607. //}
  608. public static bool IsVM()
  609. {
  610. try
  611. {
  612. using (var searcher = new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
  613. {
  614. using (var items = searcher.Get())
  615. {
  616. foreach (var item in items)
  617. {
  618. string manufacturer = item["Manufacturer"].ToString().ToLower();
  619. if ((manufacturer == "microsoft corporation" && item["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL"))
  620. || manufacturer.Contains("vmware")
  621. || item["Model"].ToString() == "VirtualBox")
  622. {
  623. return true;
  624. }
  625. }
  626. }
  627. }
  628. return false;
  629. }
  630. catch (Exception e)
  631. {
  632. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "Error while checking if running system is a VM.");
  633. return false;
  634. }
  635. }
  636. public static async Task UninstallDriver()
  637. {
  638. if (AmeliorationUtil.UseKernelDriver == false)
  639. return;
  640. AmeliorationUtil.UseKernelDriver = false;
  641. CmdAction cmdAction = new CmdAction();
  642. try
  643. {
  644. Console.WriteLine("Removing driver...");
  645. cmdAction.Command = Environment.Is64BitOperatingSystem
  646. ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -uninstallkph"
  647. : $"ProcessHacker\\x86\\ProcessHacker.exe -s -uninstallkph";
  648. cmdAction.RunTaskOnMainThread();
  649. }
  650. catch (Exception e)
  651. {
  652. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "ProcessHacker ran into an Error while uninstalling the driver.");
  653. throw;
  654. }
  655. }
  656. public class RegistryManager
  657. {
  658. [DllImport("advapi32.dll", SetLastError = true)]
  659. static extern int RegLoadKey(IntPtr hKey, string lpSubKey, string lpFile);
  660. [DllImport("advapi32.dll", SetLastError = true)]
  661. static extern int RegSaveKey(IntPtr hKey, string lpFile, uint securityAttrPtr = 0);
  662. [DllImport("advapi32.dll", SetLastError = true)]
  663. static extern int RegUnLoadKey(IntPtr hKey, string lpSubKey);
  664. [DllImport("ntdll.dll", SetLastError = true)]
  665. static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue);
  666. [DllImport("advapi32.dll")]
  667. static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref UInt64 lpLuid);
  668. [DllImport("advapi32.dll")]
  669. static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpName, ref UInt64 lpLuid);
  670. public static void LoadFromFile(string path, bool classHive = false)
  671. {
  672. var parentKey = RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default);
  673. string name;
  674. if (path.Contains("Users\\Default\\")) name = classHive ? "AME_UserHive_Default_Classes" : "AME_UserHive_Default";
  675. else name = classHive ? "AME_UserHive_" + (HivesLoaded) + "_Classes" : "AME_UserHive_" + (HivesLoaded + 1);
  676. IntPtr parentHandle = parentKey.Handle.DangerousGetHandle();
  677. RegLoadKey(parentHandle, name, path);
  678. if (!path.Contains("Users\\Default\\"))
  679. HivesLoaded++;
  680. }
  681. private static void AcquirePrivileges()
  682. {
  683. ulong luid = 0;
  684. bool throwaway;
  685. LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid);
  686. RtlAdjustPrivilege((int)luid, true, false, out throwaway);
  687. LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid);
  688. RtlAdjustPrivilege((int)luid, true, false, out throwaway);
  689. }
  690. private static void ReturnPrivileges()
  691. {
  692. ulong luid = 0;
  693. bool throwaway;
  694. LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid);
  695. RtlAdjustPrivilege((int)luid, false, false, out throwaway);
  696. LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid);
  697. RtlAdjustPrivilege((int)luid, false, false, out throwaway);
  698. }
  699. private static bool HivesHooked;
  700. private static int HivesLoaded;
  701. public static void HookUserHives()
  702. {
  703. try
  704. {
  705. if (HivesHooked || WinUtil.IsTrustedInstaller() || RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default).GetSubKeyNames().Any(x => x.StartsWith("AME_UserHive_"))) return;
  706. HivesHooked = true;
  707. var usersDir = Environment.GetEnvironmentVariable("SYSTEMDRIVE") + "\\Users";
  708. var ignoreList = new List<string>() { "Default User", "Public", "All Users" };
  709. var userDirs = Directory.GetDirectories(usersDir).Where(x => !ignoreList.Contains(x.Split('\\').Last())).ToList();
  710. var userKeys = Registry.Users.GetSubKeyNames().Where(x => x.StartsWith("S-"));
  711. foreach (var userKey in userKeys)
  712. {
  713. try
  714. {
  715. var userEnv = Registry.Users.OpenSubKey(userKey).OpenSubKey("Volatile Environment");
  716. userDirs.Remove((string)userEnv.GetValue("USERPROFILE"));
  717. }
  718. catch (Exception) { }
  719. }
  720. if (userDirs.Any()) AcquirePrivileges();
  721. foreach (var userDir in userDirs)
  722. {
  723. if (!File.Exists($"{userDir}\\NTUSER.DAT"))
  724. {
  725. ErrorLogger.WriteToErrorLog($"NTUSER.DAT file not found in user folder '{userDir}'.",
  726. Environment.StackTrace, $"Error attempting to load user registry hive.");
  727. continue;
  728. }
  729. LoadFromFile($"{userDir}\\NTUSER.DAT");
  730. if (userDir.EndsWith("\\Default"))
  731. {
  732. try
  733. {
  734. if (!Directory.Exists($@"{userDir}\AppData\Local\Microsoft\Windows")) Directory.CreateDirectory($@"{userDir}\AppData\Local\Microsoft\Windows");
  735. var fs = File.Create($@"{userDir}\AppData\Local\Microsoft\Windows" + @"\UsrClass.dat");
  736. var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("TrustedUninstaller.Shared.Properties.UsrClass.dat");
  737. resource.CopyTo(fs);
  738. fs.Close();
  739. }
  740. catch (Exception e)
  741. {
  742. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace,
  743. $"Failed to create default user class hive.", userDir);
  744. }
  745. }
  746. if (!File.Exists($@"{userDir}\AppData\Local\Microsoft\Windows\UsrClass.dat"))
  747. {
  748. ErrorLogger.WriteToErrorLog($@"UsrClass.dat file not found in user appdata folder '{userDir}\AppData\Local\Microsoft\Windows'.",
  749. Environment.StackTrace, $"Error attempting to load user classes registry hive.");
  750. continue;
  751. }
  752. LoadFromFile($@"{userDir}\AppData\Local\Microsoft\Windows\UsrClass.dat", true);
  753. }
  754. if (userDirs.Any()) ReturnPrivileges();
  755. }
  756. catch (Exception e)
  757. {
  758. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace,
  759. $"Critical error while attempting to mount user hives.");
  760. Console.WriteLine(":AME-ERROR: Failure while mounting user registry hives.");
  761. }
  762. }
  763. public static void UnhookUserHives()
  764. {
  765. try
  766. {
  767. var usersKey = RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default);
  768. var userHives = usersKey.GetSubKeyNames().Where(x => x.StartsWith("AME_UserHive_")).ToList();
  769. if (userHives.Any()) AcquirePrivileges();
  770. foreach (var userHive in userHives)
  771. {
  772. RegUnLoadKey(usersKey.Handle.DangerousGetHandle(), userHive);
  773. }
  774. if (userHives.Any()) ReturnPrivileges();
  775. usersKey.Close();
  776. }
  777. catch (Exception e)
  778. {
  779. ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace,
  780. $"Critical error while attempting to unmount user hives.");
  781. Console.WriteLine(":AME-ERROR: Failure while unmounting user registry hives.");
  782. }
  783. }
  784. }
  785. public class HttpProgressClient : IDisposable
  786. {
  787. private string _downloadUrl;
  788. private string _destinationFilePath;
  789. public HttpClient Client;
  790. public delegate void ProgressChangedHandler(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage);
  791. public event ProgressChangedHandler ProgressChanged;
  792. public HttpProgressClient()
  793. {
  794. Client = new HttpClient { Timeout = TimeSpan.FromDays(1) };
  795. }
  796. public async Task StartDownload(string downloadUrl, string destinationFilePath, long? size = null)
  797. {
  798. _downloadUrl = downloadUrl;
  799. _destinationFilePath = destinationFilePath;
  800. using (var response = await Client.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))
  801. await DownloadFileFromHttpResponseMessage(response, size);
  802. }
  803. public Task<HttpResponseMessage> GetAsync(string link)
  804. {
  805. return Client.GetAsync(link);
  806. }
  807. private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response, long? size)
  808. {
  809. response.EnsureSuccessStatusCode();
  810. if (!size.HasValue)
  811. size = response.Content.Headers.ContentLength;
  812. using (var contentStream = await response.Content.ReadAsStreamAsync())
  813. await ProcessContentStream(size, contentStream);
  814. }
  815. private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
  816. {
  817. var totalBytesRead = 0L;
  818. var readCount = 0L;
  819. var buffer = new byte[8192];
  820. var isMoreToRead = true;
  821. using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
  822. {
  823. do
  824. {
  825. var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
  826. if (bytesRead == 0)
  827. {
  828. isMoreToRead = false;
  829. TriggerProgressChanged(totalDownloadSize, totalBytesRead);
  830. continue;
  831. }
  832. await fileStream.WriteAsync(buffer, 0, bytesRead);
  833. totalBytesRead += bytesRead;
  834. readCount += 1;
  835. if (readCount % 50 == 0)
  836. TriggerProgressChanged(totalDownloadSize, totalBytesRead);
  837. }
  838. while (isMoreToRead);
  839. }
  840. }
  841. private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
  842. {
  843. if (ProgressChanged == null)
  844. return;
  845. double? progressPercentage = null;
  846. if (totalDownloadSize.HasValue)
  847. {
  848. progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);
  849. }
  850. ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
  851. }
  852. public void Dispose()
  853. {
  854. Client?.Dispose();
  855. }
  856. }
  857. }
  858. }