|
|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Management;
- using System.Net;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Xml.Serialization;
- using Microsoft.Win32;
- using TrustedUninstaller.Shared;
- using TrustedUninstaller.Shared.Actions;
- using TrustedUninstaller.Shared.Tasks;
-
- namespace TrustedUninstaller.Shared
- {
- public static class Requirements
- {
- [Serializable]
- public enum Requirement
- {
- [XmlEnum("Internet")]
- Internet = 0,
- [XmlEnum("NoInternet")]
- NoInternet = 1,
- [XmlEnum("DefenderDisabled")]
- DefenderDisabled = 2,
- [XmlEnum("DefenderToggled")]
- DefenderToggled = 3,
- [XmlEnum("NoPendingUpdates")]
- NoPendingUpdates = 4,
- [XmlEnum("Activation")]
- Activation = 5,
- [XmlEnum("NoAntivirus")]
- NoAntivirus = 6,
- [XmlEnum("LocalAccounts")]
- LocalAccounts = 11,
- [XmlEnum("PasswordSet")]
- PasswordSet = 11,
- [XmlEnum("AdministratorPasswordSet")]
- AdministratorPasswordSet = 8,
- [XmlEnum("PluggedIn")]
- PluggedIn = 9,
- [XmlEnum("NoTweakware")]
- NoTweakware = 10,
- }
-
- public static async Task<Requirement[]> MetRequirements(this Requirement[] requirements)
- {
- var requirementEnum = (Requirement[])Enum.GetValues(typeof(Requirement));
- if (requirements == null)
- {
- return requirementEnum;
- }
- // Add all requirements that are not included
- var metRequirements = requirementEnum.Except(requirements).ToList();
-
- if (requirements.Contains(Requirement.Internet))
- if (await new Internet().IsMet()) metRequirements.Add(Requirement.Internet);
- else metRequirements.Add(Requirement.NoInternet);
-
- if (requirements.Contains(Requirement.NoAntivirus))
- if (true) metRequirements.Add(Requirement.NoAntivirus);
-
- if (requirements.Contains(Requirement.NoPendingUpdates))
- if (await new NoPendingUpdates().IsMet()) metRequirements.Add(Requirement.NoPendingUpdates);
-
- if (requirements.Contains(Requirement.Activation))
- if (await new Activation().IsMet()) metRequirements.Add(Requirement.Activation);
-
- if (requirements.Contains(Requirement.DefenderDisabled))
- if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderDisabled);
-
- if (requirements.Contains(Requirement.DefenderToggled))
- if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderToggled);
-
- if (requirements.Contains(Requirement.LocalAccounts))
- metRequirements.Add(Requirement.LocalAccounts);
-
- if (requirements.Contains(Requirement.AdministratorPasswordSet))
- metRequirements.Add(Requirement.AdministratorPasswordSet);
-
- if (requirements.Contains(Requirement.PluggedIn))
- if (await new Battery().IsMet()) metRequirements.Add(Requirement.PluggedIn);
-
- return metRequirements.ToArray();
- }
-
- public interface IRequirements
- {
- Task<bool> IsMet();
- Task<bool> Meet();
- }
- public class RequirementBase
- {
- public class ProgressEventArgs : EventArgs
- {
- public int PercentAdded;
- public ProgressEventArgs(int percent)
- {
- PercentAdded = percent;
- }
- }
-
- public event EventHandler<ProgressEventArgs> ProgressChanged;
-
- protected void OnProgressAdded(int percent)
- {
- ProgressChanged?.Invoke(this, new ProgressEventArgs(percent));
- }
- }
-
- public class Battery : RequirementBase, IRequirements
- {
- [StructLayout(LayoutKind.Sequential)]
- public class PowerState
- {
- public ACLineStatus ACLineStatus;
- public BatteryFlag BatteryFlag;
- public Byte BatteryLifePercent;
- public Byte Reserved1;
- public Int32 BatteryLifeTime;
- public Int32 BatteryFullLifeTime;
-
- // direct instantation not intended, use GetPowerState.
- private PowerState() {}
-
- public static PowerState GetPowerState()
- {
- PowerState state = new PowerState();
- if (GetSystemPowerStatusRef(state))
- return state;
-
- throw new ApplicationException("Unable to get power state");
- }
-
- [DllImport("Kernel32", EntryPoint = "GetSystemPowerStatus")]
- private static extern bool GetSystemPowerStatusRef(PowerState sps);
- }
-
- // Note: Underlying type of byte to match Win32 header
- public enum ACLineStatus : byte
- {
- Offline = 0, Online = 1, Unknown = 255
- }
-
- public enum BatteryFlag : byte
- {
- High = 1, Low = 2, Critical = 4, Charging = 8,
- NoSystemBattery = 128, Unknown = 255
- }
-
- public async Task<bool> IsMet()
- {
- try
- {
- PowerState state = PowerState.GetPowerState();
- if ((state.BatteryFlag == BatteryFlag.NoSystemBattery || state.BatteryFlag == BatteryFlag.Charging)
- || state.ACLineStatus == ACLineStatus.Online || (state.ACLineStatus == ACLineStatus.Unknown && state.BatteryFlag == BatteryFlag.Unknown))
- return true;
- else
- return false;
- }
- catch { }
- return true;
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- public class Internet : RequirementBase, IRequirements
- {
- [DllImport("wininet.dll", SetLastError = true)]
- private static extern bool InternetCheckConnection(string lpszUrl, int dwFlags, int dwReserved);
-
- [DllImport("wininet.dll", SetLastError=true)]
- extern static bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);
-
- public async Task<bool> IsMet()
- {
- try
- {
- try
- {
- if (!InternetCheckConnection("http://archlinux.org", 1, 0))
- {
- if (!InternetCheckConnection("http://google.com", 1, 0))
- return false;
- }
- return true;
- }
- catch
- {
- var request = (HttpWebRequest)WebRequest.Create("http://google.com");
- request.KeepAlive = false;
- request.Timeout = 5000;
- using (var response = (HttpWebResponse)request.GetResponse())
- return true;
- }
- }
- catch
- {
- return false;
- }
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- public class DefenderDisabled : RequirementBase, IRequirements
- {
- public async Task<bool> IsMet()
- {
- try
- {
- if (Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\WinDefend") != null && new RegistryValueAction() { KeyName = @"HKLM\SYSTEM\CurrentControlSet\Services\WinDefend", Value = "Start", Data = 4, Type = RegistryValueType.REG_DWORD }.GetStatus() != UninstallTaskStatus.Completed)
- return false;
-
- if (Registry.ClassesRoot.OpenSubKey(@"CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32") != null) return false;
- if (Registry.ClassesRoot.OpenSubKey(@"CLSID\{a463fcb9-6b1c-4e0d-a80b-a2ca7999e25d}\InprocServer32") != null) return false;
- var key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity");
- if (key != null && (int)key.GetValue("Enabled") != 0)
- {
- return false;
- }
- }
- catch (Exception e)
- {
- }
- return RemnantsOnly();
- }
- public static bool RemnantsOnly()
- {
- if (Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\WinDefend") != null)
- return false;
- return Process.GetProcessesByName("MsMpEng").Length == 0;
- }
-
- public async Task<bool> Meet()
- {
- throw new NotImplementedException();
-
- OnProgressAdded(30);
- try
- {
- //Scheduled task to run the program on logon, and remove defender notifications
- var runOnLogOn = new CmdAction()
- {
- Command = $"schtasks /create /tn \"AME Wizard\" /tr \"{Assembly.GetExecutingAssembly().Location}\" /sc onlogon /RL HIGHEST /f",
- Wait = false
- };
- await runOnLogOn.RunTask();
-
- OnProgressAdded(10);
- var disableNotifs = new CmdAction()
- {
- Command = $"reg add \"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows Defender Security Center\\Notifications\" /v DisableNotifications /t REG_DWORD /d 1 /f"
- };
- await disableNotifs.RunTask();
- OnProgressAdded(10);
- var defenderService = new RunAction()
- {
- Exe = $"NSudoLC.exe",
- Arguments = "-U:T -P:E -M:S -Priority:RealTime -UseCurrentConsole -Wait reg delete \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend\" /f",
- BaseDir = true,
- CreateWindow = false
- };
- await defenderService.RunTask();
- OnProgressAdded(20);
- // MpOAV.dll normally is in use by a lot of processes. This prevents that.
- var MpOAVCLSID = new RunAction()
- {
- Exe = $"NSudoLC.exe",
- Arguments = @"-U:T -P:E -M:S -Priority:RealTime -Wait reg delete ""HKCR\CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32"" /f",
- BaseDir = true,
- CreateWindow = false
- };
- await MpOAVCLSID.RunTask();
- OnProgressAdded(20);
-
- if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
- {
- throw new Exception("Could not remove WinDefend service.");
- }
- OnProgressAdded(10);
-
- return true;
- }
- catch (Exception exception)
- {
- ErrorLogger.WriteToErrorLog(exception.Message, exception.StackTrace,
- $"Could not remove Windows Defender.");
-
- return false;
- // TODO: Move this to requirements page view if any Meet calls return false
- try
- {
- var saveLogDir = System.Windows.Forms.Application.StartupPath + "\\AME Logs";
- if (Directory.Exists(saveLogDir)) Directory.Delete(saveLogDir, true);
- Directory.Move(Directory.GetCurrentDirectory() + "\\Logs", saveLogDir);
- }
- catch (Exception) { }
-
- //MessageBox.Show("Could not remove Windows Defender. Check the error logs and contact the team " +
- // "for more information and assistance.", "Could not remove Windows Defender.", MessageBoxButton.OK, MessageBoxImage.Error);
- }
- }
- }
-
- public class DefenderToggled : RequirementBase, IRequirements
- {
- public async Task<bool> IsMet()
- {
- var defenderKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows Defender");
-
- RegistryKey realtimeKey = null;
- try
- {
- realtimeKey = defenderKey.OpenSubKey("Real-Time Protection");
- }
- catch
- {
-
- }
- if (realtimeKey != null)
- {
- try
- {
- if (!((int)realtimeKey.GetValue("DisableRealtimeMonitoring") != 1))
- return false;
- }
- catch (Exception exception)
- {
- return false;
- }
- }
-
- try
- {
- if (!((int)defenderKey.OpenSubKey("SpyNet").GetValue("SpyNetReporting") != 0))
- return false;
- }
- catch
- {
-
- }
- try
- {
- if (!((int)defenderKey.OpenSubKey("SpyNet").GetValue("SubmitSamplesConsent") != 0))
- return false;
- }
- catch
- {
-
- }
- try
- {
- if (!((int)defenderKey.OpenSubKey("Features").GetValue("TamperProtection") != 4))
- return false;
- }
- catch
- {
-
- }
- return true;
- }
-
- public async Task<bool> Meet()
- {
- throw new NotImplementedException();
- }
- }
-
- public class NoPendingUpdates : RequirementBase, IRequirements
- {
- public async Task<bool> IsMet()
- {
- //TODO: This
- return true;
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- public class NoAntivirus : RequirementBase, IRequirements
- {
- public async Task<bool> IsMet()
- {
- return !WinUtil.GetEnabledAvList(false).Any();
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- public class Activation : RequirementBase, IRequirements
- {
- public async Task<bool> IsMet()
- {
- return WinUtil.IsGenuineWindows();
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- public class WindowsBuild
- {
- public bool IsMet(string[] builds)
- {
- return builds.Any(x => x.Equals(Globals.WinVer.ToString()));
- }
-
- public Task<bool> Meet() => throw new NotImplementedException();
- }
-
- }
- }
|