diff --git a/README.md b/README.md
index 50e2286..554b378 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,6 @@ Coming soon.
4. Build TrustedUninstaller.CLI
-If you run into reference issues with the Windows namespace, add `Windows.winmd` as a reference.
-
## License
This tool has an [MIT license](https://en.wikipedia.org/wiki/MIT_License), which waives any requirements or rules governing the source code’s use, removing politics from the equation.
diff --git a/TrustedUninstaller.CLI/App.config b/TrustedUninstaller.CLI/App.config
deleted file mode 100644
index d64b1fa..0000000
--- a/TrustedUninstaller.CLI/App.config
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/TrustedUninstaller.CLI/CLI.cs b/TrustedUninstaller.CLI/CLI.cs
index 3e00569..e6297f0 100644
--- a/TrustedUninstaller.CLI/CLI.cs
+++ b/TrustedUninstaller.CLI/CLI.cs
@@ -10,6 +10,7 @@ using System.Windows;
using Microsoft.Win32;
using TrustedUninstaller.Shared;
using TrustedUninstaller.Shared.Actions;
+using TrustedUninstaller.Shared.Tasks;
namespace TrustedUninstaller.CLI
{
@@ -40,13 +41,12 @@ namespace TrustedUninstaller.CLI
if (args.Length < 1 || !Directory.Exists(args[0]))
{
- Console.WriteLine("No Playbook selected: Use the GUI to select a playbook to run.");
+ Console.WriteLine("No Playbook selected.");
return -1;
}
AmeliorationUtil.Playbook = await AmeliorationUtil.DeserializePlaybook(args[0]);
- AmeliorationUtil.Playbook.Path = args[0];
-
+
if (!Directory.Exists($"{AmeliorationUtil.Playbook.Path}\\Configuration") || Directory.GetFiles($"{AmeliorationUtil.Playbook.Path}\\Configuration").Length == 0)
{
Console.WriteLine("Configuration folder is empty, put YAML files in it and restart the application.");
@@ -54,6 +54,9 @@ namespace TrustedUninstaller.CLI
return -1;
}
ExtractResourceFolder("resources", Directory.GetCurrentDirectory());
+
+
+
if (!WinUtil.IsTrustedInstaller())
{
Console.WriteLine("Checking requirements...\r\n");
@@ -71,20 +74,30 @@ namespace TrustedUninstaller.CLI
Console.WriteLine("All 4 windows security toggles must be set to off.\r\nNavigate to Windows Security > Virus & threat detection > manage settings.\r\nPress any key to continue...");
Console.ReadKey();
}
- Console.WriteLine("The system must be prepared before continuing Your system will restart after preparation\r\nPress any key to continue...");
+
+ bool remnantsOnly = Requirements.DefenderDisabled.RemnantsOnly();
+
+ Console.WriteLine(remnantsOnly ? "The system must be prepared before continuing.\r\nPress any key to continue..." : "The system must be prepared before continuing. Your system will restart after preparation\r\nPress any key to continue...");
Console.ReadKey();
try
{
- WinUtil.PrepareSystemCLI();
- CmdAction reboot = new CmdAction()
+ Console.WriteLine("\r\nPreparing system...");
+ PrepareSystemCLI();
+ Console.WriteLine("Preparation Complete");
+
+ if (!remnantsOnly)
{
- Command = "timeout /t 1 & shutdown /r /t 0",
- Wait = false
- };
+ Console.WriteLine("\r\nRestarting system...");
+ CmdAction reboot = new CmdAction()
+ {
+ Command = "timeout /t 1 & shutdown /r /t 0",
+ Wait = false
+ };
- AmeliorationUtil.SafeRunAction(reboot).Wait();
+ AmeliorationUtil.SafeRunAction(reboot).Wait();
- Environment.Exit(0);
+ Environment.Exit(0);
+ }
} catch (Exception e)
{
Console.WriteLine("Error preparing system: " + e.Message);
@@ -96,9 +109,33 @@ namespace TrustedUninstaller.CLI
{
Console.WriteLine("Internet must be connected to run this Playbook.");
}
+ }
+
+ if (!File.Exists($"{AmeliorationUtil.Playbook.Path}\\options.txt"))
+ {
+ List defaultOptions = new List();
+ foreach (var page in AmeliorationUtil.Playbook.FeaturePages)
+ {
+ if (page.DependsOn != null && !defaultOptions.Contains(page.DependsOn))
+ continue;
+
+ if (page.GetType() == typeof(Playbook.CheckboxPage))
+ {
+ foreach (var option in ((Playbook.CheckboxPage)page).Options.Where(x => ((Playbook.CheckboxPage.CheckboxOption)x).IsChecked))
+ {
+ defaultOptions.Add(option.Name);
+ }
+ }
+
+ if (page.GetType() == typeof(Playbook.RadioPage))
+ defaultOptions.Add(((Playbook.RadioPage)page).DefaultOption);
+ if (page.GetType() == typeof(Playbook.RadioImagePage))
+ defaultOptions.Add(((Playbook.RadioImagePage)page).DefaultOption);
+ }
+ AmeliorationUtil.Playbook.Options = defaultOptions;
}
-
+
try
{
if (!Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ame-assassin")))
@@ -227,8 +264,7 @@ namespace TrustedUninstaller.CLI
}
}
}
-
-
+
public static async Task> GetDefenderToggles()
{
var result = new List();
@@ -338,5 +374,113 @@ namespace TrustedUninstaller.CLI
});
return result;
}
+
+ public static void PrepareSystemCLI()
+ {
+ try
+ {
+ var defenderStop = new RunAction()
+ {
+ RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ Exe = $"NSudoLC.exe",
+ Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait cmd /c \"" +
+ "sc sdset \"WinDefend\" \"D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;CCLCSWRPLOCRRC;;;BA)(A;;CCLCSWRPLOCRRC;;;BU)(A;;CCLCSWRPLOCRRC;;;IU)(A;;CCLCSWRPLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-80-1913148863-3492339771-4165695881-2087618961-4109116736)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)\"&" +
+ "sc config WinDefend start=disabled&" +
+ "net stop WinDefend\"",
+ CreateWindow = false,
+ Timeout = 7500,
+ };
+ defenderStop.RunTask().Wait();
+ } catch (Exception e)
+ {
+ }
+
+ var defenderValues = new RunAction()
+ {
+ RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ Exe = $"NSudoLC.exe",
+ Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait cmd /c \"reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows Defender\" /v \"ProductAppDataPath\" /f &" +
+ " reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows Defender\" /v \"InstallLocation\" /f\"",
+ CreateWindow = false
+ };
+ defenderValues.RunTask().Wait();
+
+ var defenderKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows Defender");
+ if (defenderKey != null && defenderKey.GetValueNames().Contains("InstallLocation"))
+ {
+ throw new Exception("Could not remove defender install values.");
+ }
+
+ var defenderService = new RunAction()
+ {
+ RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ Exe = $"NSudoLC.exe",
+ Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait reg delete \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend\" /f",
+ CreateWindow = false
+ };
+ defenderService.RunTask().Wait();
+
+ if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
+ {
+ var disableDefender = new RunAction()
+ {
+ RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ Exe = $"NSudoLC.exe",
+ Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait reg add \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend\" /v \"Start\" /t REG_DWORD /d 4 /f",
+ CreateWindow = false
+ };
+ disableDefender.RunTask().Wait();
+
+ if (new RegistryValueAction() {KeyName = @"SYSTEM\CurrentControlSet\Services\WinDefend", Value = "Start", Data = 4, Type = RegistryValueType.REG_DWORD}.GetStatus() != UninstallTaskStatus.Completed)
+ throw new Exception("Could not disable WinDefend service.");
+ }
+
+ // MpOAV.dll normally in use by a lot of processes. This prevents that.
+ var MpOAVCLSID = new RunAction()
+ {
+ RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
+ Exe = $"NSudoLC.exe",
+ Arguments = @"-U:T -P:E -M:S -Priority:RealTime -ShowWindowMode:Hide -Wait reg delete ""HKCR\CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32"" /f",
+ CreateWindow = false
+ };
+ MpOAVCLSID.RunTask().Wait();
+
+ if (Registry.ClassesRoot.OpenSubKey(@"CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32") != null)
+ {
+ throw new Exception("Could not remove MpOAV mapping.");
+ }
+
+ // Can cause ProcessHacker driver warnings without this
+ AmeliorationUtil.SafeRunAction(new RegistryValueAction()
+ {
+ KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity",
+ Value = "Enabled",
+ Data = 0,
+ }).Wait();
+ AmeliorationUtil.SafeRunAction(new RegistryValueAction()
+ {
+ KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\CI\Config",
+ Value = "VulnerableDriverBlocklistEnable",
+ Data = 0,
+ }).Wait();
+ }
+
+ public static async Task UninstallDriver()
+ {
+ CmdAction cmdAction = new CmdAction();
+ try
+ {
+ Console.WriteLine("Removing driver...");
+ cmdAction.Command = Environment.Is64BitOperatingSystem
+ ? $"ProcessHacker\\x64\\ProcessHacker.exe -s -uninstallkph"
+ : $"ProcessHacker\\x86\\ProcessHacker.exe -s -uninstallkph";
+ await cmdAction.RunTask();
+ }
+ catch (Exception e)
+ {
+ ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "ProcessHacker ran into an Error while uninstalling the driver.");
+ throw;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z b/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z
index 53cd97e..ad024ba 100644
Binary files a/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z and b/TrustedUninstaller.CLI/Properties/resources/CLI-Resources.7z differ
diff --git a/TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj b/TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj
index 4471c37..1046dfc 100644
--- a/TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj
+++ b/TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj
@@ -32,6 +32,9 @@
false
true
true
+
+ *.xml
+
$([System.IO.Path]::GetFullPath('$(SolutionDir)'))=./
@@ -40,7 +43,7 @@
true
bin\x64\Debug\
DEBUG;TRACE
- full
+ embedded
x64
7.3
prompt
@@ -60,6 +63,13 @@
true
en
+
+ bin\x64\Release\
+ x64
+ true
+ embedded
+ SINGLE
+
B8F0A67800B779C5CEF49BEAB6E5247E373F9452
@@ -81,6 +91,15 @@
app.manifest
+
+ for /f "usebackq delims=" %%A in (`DIR /B /S /A:d "$(SolutionDir)" ^| FINDSTR /R /c:".*\\bin\\.*\\de$" /c:".*\\bin\\.*\\en$" /c:".*\\bin\\.*\\es$" /c:".*\\bin\\.*\\fr$" /c:".*\\bin\\.*\\it$" /c:".*\\bin\\.*\\ja$" /c:".*\\bin\\.*\\ko$" /c:".*\\bin\\.*\\ru$" /c:".*\\bin\\.*\\zh-Hans$" /c:".*\\bin\\.*\\zh-Hant$" /c:".*\\bin\\.*\\pl$" /c:".*\\bin\\.*\\zh-CN$"`) do (RMDIR /Q /S "%%A" & cmd /c "exit /b 0")
+ cmd /c "echo Compiled> "$(SolutionDir)\TrustedUninstaller.GUI\gui-builder\Compiled.txt""
+
+
+ PowerShell -NoP -C "Get-Process 'ame-builder' -EA SilentlyContinue | Wait-Process -EA SilentlyContinue; EXIT 0"
+ PowerShell -NoP -C "Start-Process '$(SolutionDir)\TrustedUninstaller.GUI\gui-builder\ame-builder.exe' -ArgumentList 'CLI' -WindowStyle Hidden"
+
+
for /f "usebackq delims=" %%A in (`DIR /B /S /A:d "$(SolutionDir)" ^| FINDSTR /R /c:".*\\bin\\.*\\de$" /c:".*\\bin\\.*\\en$" /c:".*\\bin\\.*\\es$" /c:".*\\bin\\.*\\fr$" /c:".*\\bin\\.*\\it$" /c:".*\\bin\\.*\\ja$" /c:".*\\bin\\.*\\ko$" /c:".*\\bin\\.*\\ru$" /c:".*\\bin\\.*\\zh-Hans$" /c:".*\\bin\\.*\\zh-Hant$" /c:".*\\bin\\.*\\pl$" /c:".*\\bin\\.*\\zh-CN$"`) do (RMDIR /Q /S "%%A" & cmd /c "exit /b 0")
@@ -104,16 +123,12 @@
-
- ..\Windows.winmd
-
-
diff --git a/TrustedUninstaller.Shared/Actions/AppxAction.cs b/TrustedUninstaller.Shared/Actions/AppxAction.cs
index 73bfa6e..7951ca2 100644
--- a/TrustedUninstaller.Shared/Actions/AppxAction.cs
+++ b/TrustedUninstaller.Shared/Actions/AppxAction.cs
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Threading.Tasks;
+//using Windows.ApplicationModel;
+//using Windows.Management.Deployment;
using TrustedUninstaller.Shared.Exceptions;
using TrustedUninstaller.Shared.Tasks;
using YamlDotNet.Serialization;
@@ -11,7 +13,8 @@ using System.Threading;
namespace TrustedUninstaller.Shared.Actions
{
- internal class AppxAction : ITaskAction
+ // Integrate ame-assassin later
+ internal class AppxAction : TaskAction, ITaskAction
{
public enum AppxOperation
{
diff --git a/TrustedUninstaller.Shared/Actions/CmdAction.cs b/TrustedUninstaller.Shared/Actions/CmdAction.cs
index b3ffd61..145d6b7 100644
--- a/TrustedUninstaller.Shared/Actions/CmdAction.cs
+++ b/TrustedUninstaller.Shared/Actions/CmdAction.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Text;
using System.Threading.Tasks;
using TrustedUninstaller.Shared.Exceptions;
using TrustedUninstaller.Shared.Tasks;
@@ -8,7 +9,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- public class CmdAction : ITaskAction
+ public class CmdAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "command")]
public string Command { get; set; }
@@ -84,8 +85,16 @@ namespace TrustedUninstaller.Shared.Actions
process.Dispose();
return true;
}
-
+
+ var error = new StringBuilder();
process.OutputDataReceived += ProcOutputHandler;
+ process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs args)
+ {
+ if (!String.IsNullOrEmpty(args.Data))
+ error.AppendLine(args.Data);
+ else
+ error.AppendLine();
+ };
process.BeginOutputReadLine();
@@ -104,7 +113,7 @@ namespace TrustedUninstaller.Shared.Actions
if (process.ExitCode != 0)
{
- StandardError = process.StandardError.ReadToEnd();
+ StandardError = error.ToString();
Console.WriteLine($"cmd instance exited with error code: {process.ExitCode}");
if (!String.IsNullOrEmpty(StandardError)) Console.WriteLine($"Error message: {StandardError}");
diff --git a/TrustedUninstaller.Shared/Actions/FileAction.cs b/TrustedUninstaller.Shared/Actions/FileAction.cs
index 7480967..a5dd9be 100644
--- a/TrustedUninstaller.Shared/Actions/FileAction.cs
+++ b/TrustedUninstaller.Shared/Actions/FileAction.cs
@@ -4,17 +4,20 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
+using System.Reflection;
+using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.ServiceProcess;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using System.Windows;
using TrustedUninstaller.Shared.Exceptions;
using TrustedUninstaller.Shared.Tasks;
using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- public class FileAction : ITaskAction
+ public class FileAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "path")]
public string RawPath { get; set; }
@@ -71,6 +74,9 @@ namespace TrustedUninstaller.Shared.Actions
return isFile || isDirectory ? UninstallTaskStatus.ToDo : UninstallTaskStatus.Completed;
}
+ [DllImport("Unlocker.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
+ private static extern bool EzUnlockFileW(string path);
+
private async Task DeleteFile(string file, bool log = false)
{
if (!TrustedInstaller)
@@ -79,15 +85,36 @@ namespace TrustedUninstaller.Shared.Actions
if (File.Exists(file))
{
+ try
+ {
+ EzUnlockFileW(file);
+ }
+ catch (Exception e)
+ {
+ ErrorLogger.WriteToErrorLog($"Error while unlocking file: " + e.Message, e.StackTrace,
+ $"FileAction Error", file);
+ }
+
+ try {await Task.Run(() => File.Delete(file));} catch {}
+
CmdAction delAction = new CmdAction()
{
- Command = $"del /q /f {file}"
+ Command = $"del /q /f \"{file}\""
};
await delAction.RunTask();
}
}
else if (File.Exists("NSudoLC.exe"))
{
+ try
+ {
+ EzUnlockFileW(file);
+ }
+ catch (Exception e)
+ {
+ ErrorLogger.WriteToErrorLog($"Error while unlocking file: " + e.Message, e.StackTrace,
+ $"FileAction Error", file);
+ }
RunAction tiDelAction = new RunAction()
{
Exe = "NSudoLC.exe",
@@ -259,15 +286,19 @@ namespace TrustedUninstaller.Shared.Actions
Console.WriteLine($"\r\nError: Could not get amount of services locking file.\r\nException: " + e.Message);
}
}
- if (svcCount > 8) Console.WriteLine("Amount of locking services exceeds 8, skipping...");
-
- while (processes.Any() && delay <= 800 && svcCount <= 8)
+
+ while (processes.Any() && delay <= 800)
{
Console.WriteLine("Processes locking the file:");
foreach (var process in processes)
{
Console.WriteLine(process.ProcessName);
}
+ if (svcCount > 10)
+ {
+ Console.WriteLine("Amount of locking services exceeds 10, skipping...");
+ break;
+ }
foreach (var process in processes)
{
diff --git a/TrustedUninstaller.Shared/Actions/LanguageAction.cs b/TrustedUninstaller.Shared/Actions/LanguageAction.cs
index 252a9be..034c77a 100644
--- a/TrustedUninstaller.Shared/Actions/LanguageAction.cs
+++ b/TrustedUninstaller.Shared/Actions/LanguageAction.cs
@@ -6,7 +6,7 @@ using TrustedUninstaller.Shared.Tasks;
namespace TrustedUninstaller.Shared.Actions
{
- class LanguageAction : ITaskAction
+ class LanguageAction : TaskAction, ITaskAction
{
public int ProgressWeight { get; set; } = 1;
public int GetProgressWeight() => ProgressWeight;
diff --git a/TrustedUninstaller.Shared/Actions/LineInFileAction.cs b/TrustedUninstaller.Shared/Actions/LineInFileAction.cs
index 954252e..fd4c053 100644
--- a/TrustedUninstaller.Shared/Actions/LineInFileAction.cs
+++ b/TrustedUninstaller.Shared/Actions/LineInFileAction.cs
@@ -14,7 +14,7 @@ namespace TrustedUninstaller.Shared.Actions
Delete = 0,
Add = 1
}
- internal class LineInFileAction : ITaskAction
+ internal class LineInFileAction : TaskAction, ITaskAction
{
[YamlMember(Alias = "path")]
public string RawPath { get; set; }
diff --git a/TrustedUninstaller.Shared/Actions/PowershellAction.cs b/TrustedUninstaller.Shared/Actions/PowershellAction.cs
index 0a17769..4f91867 100644
--- a/TrustedUninstaller.Shared/Actions/PowershellAction.cs
+++ b/TrustedUninstaller.Shared/Actions/PowershellAction.cs
@@ -2,7 +2,6 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Management.Automation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -13,7 +12,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- public class PowerShellAction : ITaskAction
+ public class PowerShellAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "command")]
public string Command { get; set; }
@@ -69,7 +68,7 @@ namespace TrustedUninstaller.Shared.Actions
RedirectStandardOutput = true,
CreateNoWindow = true
};
- if (ExeDir) startInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "\\Executables";
+ if (ExeDir) startInfo.WorkingDirectory = AmeliorationUtil.Playbook.Path + "\\Executables";
if (!Wait)
{
startInfo.RedirectStandardError = false;
diff --git a/TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs b/TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs
index 4c7466f..4f49994 100644
--- a/TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs
+++ b/TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs
@@ -19,7 +19,7 @@ namespace TrustedUninstaller.Shared.Actions
Delete = 0,
Add = 1
}
- public class RegistryKeyAction : ITaskAction
+ public class RegistryKeyAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "path")]
public string KeyName { get; set; }
diff --git a/TrustedUninstaller.Shared/Actions/RegistryValueAction.cs b/TrustedUninstaller.Shared/Actions/RegistryValueAction.cs
index 41460c4..3aa3ed5 100644
--- a/TrustedUninstaller.Shared/Actions/RegistryValueAction.cs
+++ b/TrustedUninstaller.Shared/Actions/RegistryValueAction.cs
@@ -36,7 +36,7 @@ namespace TrustedUninstaller.Shared.Actions
REG_UNKNOWN = RegistryValueKind.Unknown
}
- public class RegistryValueAction : ITaskAction
+ public class RegistryValueAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "path")]
public string KeyName { get; set; }
diff --git a/TrustedUninstaller.Shared/Actions/RunAction.cs b/TrustedUninstaller.Shared/Actions/RunAction.cs
index 1fade55..8b9e630 100644
--- a/TrustedUninstaller.Shared/Actions/RunAction.cs
+++ b/TrustedUninstaller.Shared/Actions/RunAction.cs
@@ -8,7 +8,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- public class RunAction : ITaskAction
+ public class RunAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "path")]
public string RawPath { get; set; } = null;
diff --git a/TrustedUninstaller.Shared/Actions/ScheduledTaskAction.cs b/TrustedUninstaller.Shared/Actions/ScheduledTaskAction.cs
index 193a871..0847619 100644
--- a/TrustedUninstaller.Shared/Actions/ScheduledTaskAction.cs
+++ b/TrustedUninstaller.Shared/Actions/ScheduledTaskAction.cs
@@ -19,7 +19,7 @@ namespace TrustedUninstaller.Shared.Actions
DeleteFolder = 3
}
- internal class ScheduledTaskAction : ITaskAction
+ internal class ScheduledTaskAction : TaskAction, ITaskAction
{
[YamlMember(typeof(ScheduledTaskOperation), Alias = "operation")]
public ScheduledTaskOperation Operation { get; set; } = ScheduledTaskOperation.Delete;
diff --git a/TrustedUninstaller.Shared/Actions/ServiceAction.cs b/TrustedUninstaller.Shared/Actions/ServiceAction.cs
index 9219cd1..2ae6c07 100644
--- a/TrustedUninstaller.Shared/Actions/ServiceAction.cs
+++ b/TrustedUninstaller.Shared/Actions/ServiceAction.cs
@@ -23,7 +23,7 @@ namespace TrustedUninstaller.Shared.Actions
Delete,
Change
}
- internal class ServiceAction : ITaskAction
+ internal class ServiceAction : TaskAction, ITaskAction
{
[YamlMember(typeof(ServiceOperation), Alias = "operation")]
public ServiceOperation Operation { get; set; } = ServiceOperation.Delete;
@@ -305,8 +305,8 @@ namespace TrustedUninstaller.Shared.Actions
else
{
cmdAction.Command = Environment.Is64BitOperatingSystem ?
- $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {ServiceName} -caction {Operation.ToString().ToLower()}" :
- $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {ServiceName} -caction {Operation.ToString().ToLower()}";
+ $"ProcessHacker\\x64\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction {Operation.ToString().ToLower()}" :
+ $"ProcessHacker\\x86\\ProcessHacker.exe -s -elevate -c -ctype service -cobject {service.ServiceName} -caction {Operation.ToString().ToLower()}";
await cmdAction.RunTask();
}
diff --git a/TrustedUninstaller.Shared/Actions/ShortcutAction.cs b/TrustedUninstaller.Shared/Actions/ShortcutAction.cs
index 07d21b3..7a727b4 100644
--- a/TrustedUninstaller.Shared/Actions/ShortcutAction.cs
+++ b/TrustedUninstaller.Shared/Actions/ShortcutAction.cs
@@ -8,7 +8,7 @@ using File = System.IO.File;
namespace TrustedUninstaller.Shared.Actions
{
- class ShortcutAction : ITaskAction
+ class ShortcutAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "path")]
public string RawPath { get; set; }
diff --git a/TrustedUninstaller.Shared/Actions/SystemPackageAction.cs b/TrustedUninstaller.Shared/Actions/SystemPackageAction.cs
index 756748a..aeaa65c 100644
--- a/TrustedUninstaller.Shared/Actions/SystemPackageAction.cs
+++ b/TrustedUninstaller.Shared/Actions/SystemPackageAction.cs
@@ -11,7 +11,8 @@ using System.Threading;
namespace TrustedUninstaller.Shared.Actions
{
- internal class SystemPackageAction : ITaskAction
+ // Integrate ame-assassin later
+ internal class SystemPackageAction : TaskAction, ITaskAction
{
public enum Architecture
{
diff --git a/TrustedUninstaller.Shared/Actions/TaskKillAction.cs b/TrustedUninstaller.Shared/Actions/TaskKillAction.cs
index 93382c1..99bd1ea 100644
--- a/TrustedUninstaller.Shared/Actions/TaskKillAction.cs
+++ b/TrustedUninstaller.Shared/Actions/TaskKillAction.cs
@@ -11,7 +11,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- class TaskKillAction : ITaskAction
+ class TaskKillAction : TaskAction, ITaskAction
{
[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -85,7 +85,7 @@ namespace TrustedUninstaller.Shared.Actions
.Where(process => process.ProcessName.EndsWith(ProcessName.TrimStart('*'), StringComparison.CurrentCultureIgnoreCase));
return Process.GetProcessesByName(ProcessName);
- }
+ }
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool IsProcessCritical(IntPtr hProcess, ref bool Critical);
@@ -252,7 +252,15 @@ namespace TrustedUninstaller.Shared.Actions
if (!RegexNotCritical.Any(x => Regex.Match(process.ProcessName, x, RegexOptions.IgnoreCase).Success))
{
bool isCritical = false;
- IsProcessCritical(process.Handle, ref isCritical);
+ try
+ {
+ IsProcessCritical(process.Handle, ref isCritical);
+ }
+ catch (InvalidOperationException e)
+ {
+ ErrorLogger.WriteToErrorLog("Could not check if process is critical.", e.StackTrace, "TaskKillAction Error", process.ProcessName);
+ return false;
+ }
if (isCritical)
{
Console.WriteLine($"{process.ProcessName} is a critical process, skipping...");
@@ -285,7 +293,15 @@ namespace TrustedUninstaller.Shared.Actions
if (!RegexNotCritical.Any(x => Regex.Match(process.ProcessName, x, RegexOptions.IgnoreCase).Success))
{
bool isCritical = false;
- IsProcessCritical(process.Handle, ref isCritical);
+ try
+ {
+ IsProcessCritical(process.Handle, ref isCritical);
+ }
+ catch (InvalidOperationException e)
+ {
+ ErrorLogger.WriteToErrorLog("Could not check if process is critical.", e.StackTrace, "TaskKillAction Error", process.ProcessName);
+ continue;
+ }
if (isCritical)
{
Console.WriteLine($"{process.ProcessName} is a critical process, skipping...");
diff --git a/TrustedUninstaller.Shared/Actions/UpdateAction.cs b/TrustedUninstaller.Shared/Actions/UpdateAction.cs
index b017f8b..ab1edc5 100644
--- a/TrustedUninstaller.Shared/Actions/UpdateAction.cs
+++ b/TrustedUninstaller.Shared/Actions/UpdateAction.cs
@@ -8,7 +8,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- internal class UpdateAction : ITaskAction
+ internal class UpdateAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "name")]
public string PackageName { get; set; }
diff --git a/TrustedUninstaller.Shared/Actions/UserAction.cs b/TrustedUninstaller.Shared/Actions/UserAction.cs
index 07be4ff..2a51c86 100644
--- a/TrustedUninstaller.Shared/Actions/UserAction.cs
+++ b/TrustedUninstaller.Shared/Actions/UserAction.cs
@@ -8,7 +8,7 @@ using System.Security.Principal;
namespace TrustedUninstaller.Shared.Actions
{
- public class UserAction : ITaskAction
+ public class UserAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "name")]
public string Username { get; set; } = "";
diff --git a/TrustedUninstaller.Shared/Actions/WriteStatusAction.cs b/TrustedUninstaller.Shared/Actions/WriteStatusAction.cs
index ee5689e..ef166ea 100644
--- a/TrustedUninstaller.Shared/Actions/WriteStatusAction.cs
+++ b/TrustedUninstaller.Shared/Actions/WriteStatusAction.cs
@@ -5,7 +5,7 @@ using YamlDotNet.Serialization;
namespace TrustedUninstaller.Shared.Actions
{
- public class WriteStatusAction : ITaskAction
+ public class WriteStatusAction : TaskAction, ITaskAction
{
[YamlMember(typeof(string), Alias = "status")]
public string Status { get; set; }
diff --git a/TrustedUninstaller.Shared/AmeliorationUtil.cs b/TrustedUninstaller.Shared/AmeliorationUtil.cs
index b8b38da..eb3455a 100644
--- a/TrustedUninstaller.Shared/AmeliorationUtil.cs
+++ b/TrustedUninstaller.Shared/AmeliorationUtil.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
@@ -11,6 +12,7 @@ using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using System.Windows;
using System.Xml;
using System.Xml.Serialization;
using TrustedUninstaller.Shared.Actions;
@@ -30,9 +32,23 @@ namespace TrustedUninstaller.Shared
public static readonly List ErrorDisplayList = new List();
- public static int GetProgressMaximum()
+ public static int GetProgressMaximum(List options)
{
- return Parser.Tasks.Sum(task => task.Actions.Sum(action => action.GetProgressWeight()));
+ return Parser.Tasks.Sum(task => task.Actions.Sum(action =>
+ {
+ var taskAction = (TaskAction)action;
+ if (!String.IsNullOrEmpty(taskAction.Option) && (options == null ||
+ (taskAction.Option.StartsWith("!") && options.Contains(taskAction.Option.Substring(1), StringComparer.OrdinalIgnoreCase)) ||
+ (!options.Contains(taskAction.Option, StringComparer.OrdinalIgnoreCase))))
+ return 0;
+
+ if (!String.IsNullOrEmpty(taskAction.Arch) && (
+ (taskAction.Arch.StartsWith("!") && String.Equals(taskAction.Arch, RuntimeInformation.ProcessArchitecture.ToString(), StringComparison.OrdinalIgnoreCase)) ||
+ (!String.Equals(taskAction.Arch, RuntimeInformation.ProcessArchitecture.ToString(), StringComparison.OrdinalIgnoreCase))))
+ return 0;
+
+ return action.GetProgressWeight();
+ }));
}
public static bool AddTasks(string configPath, string file)
@@ -89,16 +105,16 @@ namespace TrustedUninstaller.Shared
try
{
//If the privilege is admin and the program is running as TI, do not do the action.
- if (privilege == UninstallTaskPrivilege.Admin && WinUtil.IsTrustedInstaller())
- {
- return 0;
- }
+ //if (privilege == UninstallTaskPrivilege.Admin && WinUtil.IsTrustedInstaller())
+ //{
+ // return 0;
+ //}
- if (privilege == UninstallTaskPrivilege.TrustedInstaller && !WinUtil.IsTrustedInstaller())
+ if (!WinUtil.IsTrustedInstaller())
{
Console.WriteLine("Relaunching as Trusted Installer!");
- var mmf = MemoryMappedFile.CreateNew("ImgA", 5000000);
+ var mmf = MemoryMappedFile.CreateNew("ImgA", 30000000);
WinUtil.RelaunchAsTrustedInstaller();
if (NativeProcess.Process == null)
{
@@ -185,6 +201,18 @@ namespace TrustedUninstaller.Shared
//Check the Actions folder inside the Shared folder for reference.
foreach (ITaskAction action in task.Actions)
{
+ var taskAction = (TaskAction)action;
+
+ if (!String.IsNullOrEmpty(taskAction.Option) && (Playbook.Options == null ||
+ (taskAction.Option.StartsWith("!") && Playbook.Options.Contains(taskAction.Option.Substring(1), StringComparer.OrdinalIgnoreCase)) ||
+ (!Playbook.Options.Contains(taskAction.Option, StringComparer.OrdinalIgnoreCase))))
+ continue;
+
+ if (!String.IsNullOrEmpty(taskAction.Arch) && (
+ (taskAction.Arch.StartsWith("!") && String.Equals(taskAction.Arch, RuntimeInformation.ProcessArchitecture.ToString(), StringComparison.OrdinalIgnoreCase)) ||
+ (!String.Equals(taskAction.Arch, RuntimeInformation.ProcessArchitecture.ToString(), StringComparison.OrdinalIgnoreCase))))
+ continue;
+
int i = 0;
//var actionType = action.GetType().ToString().Replace("TrustedUninstaller.Shared.Actions.", "");
@@ -217,6 +245,7 @@ namespace TrustedUninstaller.Shared
break;
}
}
+ Thread.Sleep(300);
}
Console.WriteLine($"Status: {action.GetStatus()}");
if (i > 0) Thread.Sleep(50);
@@ -226,7 +255,8 @@ namespace TrustedUninstaller.Shared
catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.Message, e.StackTrace, "Critical error while running action.");
- Console.WriteLine($":AME-ERROR: Critical error while running action: " + e.Message);
+ if (!((TaskAction)action).IgnoreErrors)
+ Console.WriteLine($":AME-ERROR: Critical error while running action: " + e.Message);
}
if (i == 10)
@@ -235,7 +265,8 @@ namespace TrustedUninstaller.Shared
ErrorLogger.WriteToErrorLog(errorString, Environment.StackTrace, "Action failed to complete.");
// AmeliorationUtil.ErrorDisplayList.Add(errorString) would NOT work here since this
// might be a separate process, and thus has to be forwarded via the console
- Console.WriteLine($":AME-ERROR: {errorString}");
+ if (!((TaskAction)action).IgnoreErrors)
+ Console.WriteLine($":AME-ERROR: {errorString}");
//Environment.Exit(-2);
Console.WriteLine($"Action completed. Weight:{action.GetProgressWeight()}");
continue;
@@ -260,12 +291,32 @@ namespace TrustedUninstaller.Shared
Playbook pb;
XmlSerializer serializer = new XmlSerializer(typeof(Playbook));
+ /*serializer.UnknownElement += delegate(object sender, XmlElementEventArgs args)
+ {
+ MessageBox.Show(args.Element.Name);
+ };
+ serializer.UnknownAttribute += delegate(object sender, XmlAttributeEventArgs args)
+ {
+ MessageBox.Show(args.Attr.Name);
+ };*/
using (XmlReader reader = XmlReader.Create($"{dir}\\playbook.conf"))
{
pb = (Playbook)serializer.Deserialize(reader);
}
- pb.Path = dir;
+ var validateResult = pb.Validate();
+ if (validateResult != null)
+ throw new XmlException(validateResult);
+ if (File.Exists($"{dir}\\options.txt"))
+ {
+ pb.Options = new List();
+ using (var reader = new StreamReader($"{dir}\\options.txt"))
+ {
+ while (!reader.EndOfStream)
+ pb.Options.Add(reader.ReadLine());
+ }
+ }
+ pb.Path = dir;
return Task.FromResult(pb);
}
@@ -335,17 +386,19 @@ namespace TrustedUninstaller.Shared
if (Parser.Tasks.Any(x => x.Priority != Parser.Tasks.First().Priority))
Parser.Tasks.Sort(new TaskComparer());
- UninstallTaskPrivilege prevPriv = UninstallTaskPrivilege.Admin;
+ bool launched = false;
foreach (var task in Parser.Tasks.Where(task => task.Actions.Count != 0))
{
try
{
- if (prevPriv == UninstallTaskPrivilege.TrustedInstaller && task.Privilege == UninstallTaskPrivilege.TrustedInstaller && !WinUtil.IsTrustedInstaller())
+ //if (prevPriv == UninstallTaskPrivilege.TrustedInstaller && task.Privilege == UninstallTaskPrivilege.TrustedInstaller && !WinUtil.IsTrustedInstaller())
+ if (!WinUtil.IsTrustedInstaller() && launched)
{
continue;
}
+ launched = true;
await DoActions(task, task.Privilege);
- prevPriv = task.Privilege;
+ //prevPriv = task.Privilege;
}
catch (Exception ex)
{
diff --git a/TrustedUninstaller.Shared/Globals.cs b/TrustedUninstaller.Shared/Globals.cs
index 467ba4c..918ac7a 100644
--- a/TrustedUninstaller.Shared/Globals.cs
+++ b/TrustedUninstaller.Shared/Globals.cs
@@ -9,8 +9,8 @@ namespace TrustedUninstaller.Shared
{
public class Globals
{
- public const string CurrentVersion = "0.6.5";
- public const double CurrentVersionNumber = 0.65;
+ public const string CurrentVersion = "0.7";
+ public const double CurrentVersionNumber = 0.7;
#if DEBUG
public static readonly int WinVer = 19045;
#else
diff --git a/TrustedUninstaller.Shared/Playbook.cs b/TrustedUninstaller.Shared/Playbook.cs
index b168148..2f05939 100644
--- a/TrustedUninstaller.Shared/Playbook.cs
+++ b/TrustedUninstaller.Shared/Playbook.cs
@@ -1,10 +1,23 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Globalization;
using System.IO;
using System.Linq;
-using System.Text;
+using System.Management.Automation.Runspaces;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Security.Policy;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Xml.Linq;
using System.Xml.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using MessageBox = System.Windows.MessageBox;
namespace TrustedUninstaller.Shared
{
@@ -18,25 +31,360 @@ namespace TrustedUninstaller.Shared
public string Username { get; set; }
public string Details { get; set; }
public string Version { get; set; }
+
+ [XmlArray]
+ [XmlArrayItem(ElementName = "CheckboxPage", Type = typeof(CheckboxPage))]
+ [XmlArrayItem(ElementName = "RadioPage", Type = typeof(RadioPage))]
+ [XmlArrayItem(ElementName = "RadioImagePage", Type = typeof(RadioImagePage))]
+ public FeaturePage[] FeaturePages { get; set; }
public string ProgressText { get; set; } = "Deploying the selected Playbook configuration onto the system.";
public int EstimatedMinutes { get; set; } = 25;
#nullable enable
public string[]? SupportedBuilds { get; set; }
- public Requirements.Requirement[]? Requirements { get; set; }
+ public Requirements.Requirement[] Requirements { get; set; } = new Requirements.Requirement[] {};
public string? Git { get; set; }
public string? DonateLink { get; set; }
public string? Website { get; set; }
public string? ProductCode { get; set; }
public string? PasswordReplace { get; set; }
#nullable disable
+ public bool Overhaul { get; set; } = false;
public string Path { get; set; }
+
+ public List Options { get; set; } = null;
+
+ public string Validate()
+ {
+ if (FeaturePages == null)
+ return null;
+
+ foreach (var rawPage in FeaturePages)
+ {
+ if (rawPage.GetType() == typeof(CheckboxPage))
+ {
+ var page = (CheckboxPage)rawPage;
+
+ if (page.Options.Length > 2 && page.TopLine != null && page.BottomLine != null)
+ return @$"CheckboxPage with a TopLine and BottomLine must not have more than 2 options.";
+ if (page.Options.Length > 3 && (page.TopLine != null || page.BottomLine != null))
+ return @$"CheckboxPage with a TopLine or BottomLine must not have more than 3 options.";
+ if (page.Options.Length > 4)
+ return @$"CheckboxPage must not have more than 4 options.";
+ }
+ else if (rawPage.GetType() == typeof(RadioPage))
+ {
+ var page = (RadioPage)rawPage;
+
+ if (page.Options.Length > 2 && page.TopLine != null && page.BottomLine != null)
+ return @$"RadioPage with a TopLine and BottomLine must not have more than 2 options.";
+ if (page.Options.Length > 3 && (page.TopLine != null || page.BottomLine != null))
+ return @$"RadioPage with a TopLine or BottomLine must not have more than 3 options.";
+ if (page.Options.Length > 4)
+ return @$"RadioPage must not have more than 4 options.";
+
+ if (page.DefaultOption != null && !page.Options.Any(x => x.Name == page.DefaultOption))
+ return @$"No option matching DefaultOption {page.DefaultOption} in RadioPage.";
+ }
+ else if (rawPage.GetType() == typeof(RadioImagePage))
+ {
+ var page = (RadioImagePage)rawPage;
+
+ if (page.Options.Length > 4)
+ return @$"RadioImagePage must not have more than 4 options.";
+ if (page.DefaultOption != null && !page.Options.Any(x => x.Name == page.DefaultOption))
+ return @$"No option matching DefaultOption {page.DefaultOption} in RadioImagePage.";
+ }
+ }
+ return null;
+ }
+
+ public static double GetVersionNumber(string toBeParsed)
+ {
+ // Examples:
+ // 0.4
+ // 0.4 Alpha
+ // 1.0.5
+ // 1.0.5 Beta
+
+
+ // Remove characters after first space (and the space itself)
+ if (toBeParsed.IndexOf(' ') >= 0)
+ toBeParsed = toBeParsed.Substring(0, toBeParsed.IndexOf(' '));
+
+ if (toBeParsed.LastIndexOf('.') != toBeParsed.IndexOf('.'))
+ {
+ // Example: 1.0.5
+ toBeParsed = toBeParsed.Remove(toBeParsed.LastIndexOf('.'), 1);
+ // Result: 1.05
+ }
+
+ return double.Parse(toBeParsed, CultureInfo.InvariantCulture);
+ }
+
+ public double GetVersionNumber()
+ {
+ return GetVersionNumber(Version);
+ }
+
+ public async Task LatestPlaybookVersion()
+ {
+
+ if (!IsValidGit())
+ {
+ throw new ArgumentException("Link provided is not a proper Git link.");
+ }
+
+ string gitPlatform = GetPlaybookGitPlatform();
+
+ string repo = GetRepository();
+
+ using var httpClient = new HttpClient();
+ httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
+
+ string url = gitPlatform switch
+ {
+ "github.com" => $"https://api.github.com/repos/{repo}/releases",
+ "gitlab.com" => $"https://gitlab.com/api/v4/projects/{Uri.EscapeDataString(repo)}/releases",
+ _ => $"https://{gitPlatform}/api/v1/repos/{repo}/releases"
+ };
+
+ var response = await httpClient.GetAsync(url);
+
+ response.EnsureSuccessStatusCode();
+
+ var json = await response.Content.ReadAsStringAsync();
+ var array = JArray.Parse(json);
+
+ return (string) array.FirstOrDefault()?["tag_name"];
+ }
+ public async Task> GetPlaybookVersions()
+ {
+
+ if (!IsValidGit())
+ {
+ throw new ArgumentException("Link provided is not a proper Git link.");
+ }
+
+ string gitPlatform = GetPlaybookGitPlatform();
+
+ string repo = GetRepository();
+
+ using var httpClient = new HttpClient();
+ httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
+
+ string url = gitPlatform switch
+ {
+ "github.com" => $"https://api.github.com/repos/{repo}/releases",
+ "gitlab.com" => $"https://gitlab.com/api/v4/projects/{Uri.EscapeDataString(repo)}/releases",
+ _ => $"https://{gitPlatform}/api/v1/repos/{repo}/releases"
+ };
+
+ var response = await httpClient.GetAsync(url);
+
+ response.EnsureSuccessStatusCode();
+
+ var json = await response.Content.ReadAsStringAsync();
+ var array = JArray.Parse(json);
+
+ var result = new List();
+ foreach (var releaseToken in array)
+ result.Add((string)releaseToken["tag_name"]);
+
+ return result;
+ }
+ public async Task DownloadLatestPlaybook(BackgroundWorker worker = null)
+ {
+ string repo = GetRepository();
+ string gitPlatform = GetPlaybookGitPlatform();
+
+ var httpClient = new WinUtil.HttpProgressClient();
+ httpClient.Client.DefaultRequestHeaders.UserAgent.ParseAdd("curl/7.55.1"); //Required for GitHub
+
+ var downloadUrl = string.Empty;
+ var downloadDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "AME");
+ var downloadPath = System.IO.Path.Combine(downloadDir, "playbook.apbx");
+
+ string baseUrl;
+ string releasesUrl;
+ string assetsKey;
+ string browserDownloadUrlKey;
+
+ switch (gitPlatform)
+ {
+ case "github.com":
+ baseUrl = "https://api.github.com";
+ releasesUrl = $"{baseUrl}/repos/{repo}/releases";
+ assetsKey = "assets";
+ browserDownloadUrlKey = "browser_download_url";
+ break;
+
+ case "gitlab.com":
+ baseUrl = "https://gitlab.com/api/v4";
+ releasesUrl = $"{baseUrl}/projects/{Uri.EscapeDataString(repo)}/releases";
+ assetsKey = "assets.links";
+ browserDownloadUrlKey = "direct_asset_url";
+ break;
+
+ default:
+ baseUrl = $"https://{gitPlatform}/api/v1";
+ releasesUrl = $"{baseUrl}/repos/{repo}/releases";
+ assetsKey = "assets";
+ browserDownloadUrlKey = "browser_download_url";
+ break;
+ }
+
+ var releasesResponse = await httpClient.GetAsync(releasesUrl);
+ releasesResponse.EnsureSuccessStatusCode();
+
+ var releasesContent = await releasesResponse.Content.ReadAsStringAsync();
+ var releases = JArray.Parse(releasesContent);
+ var release = releases.FirstOrDefault();
+
+ long size = 3000000;
+
+ if (release?.SelectToken(assetsKey) is JArray assets)
+ {
+ var asset = assets.FirstOrDefault(a => a["name"].ToString().EndsWith(".apbx"));
+ if (asset != null)
+ {
+ downloadUrl = asset[browserDownloadUrlKey]?.ToString();
+
+ if (asset["size"] != null)
+ long.TryParse(asset["size"].ToString(), out size);
+ }
+ }
+
+ if (worker != null)
+ worker.ReportProgress(10);
+
+ // Download the release asset
+ if (!string.IsNullOrEmpty(downloadUrl))
+ {
+ httpClient.Client.DefaultRequestHeaders.Clear();
+
+ httpClient.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) => {
+ if (progressPercentage.HasValue && worker != null)
+ worker.ReportProgress((int)Math.Ceiling(10 + (progressPercentage.Value * 0.7)));
+ };
+
+ await httpClient.StartDownload(downloadUrl, downloadPath, size);
+ }
+ httpClient.Dispose();
+ }
+
+ public string GetRepository()
+ {
+ if (Git == null)
+ {
+ return null;
+ }
+
+ var urlSegments = Git.Replace("https://", "").Replace("http://", "").Split('/');
+ return urlSegments[1] +"/"+ urlSegments[2];
+ }
+
+ public string GetPlaybookGitPlatform()
+ {
+ if (this.Git == null)
+ {
+ throw new NullReferenceException("No Git link available.");
+ }
+
+ return new Uri(Git).Host;
+ }
+
+ public bool IsValidGit()
+ {
+ if (Git == null)
+ {
+ throw new NullReferenceException("No Git link available.");
+ }
+
+ return Regex.IsMatch(Git, "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.@\\:/\\-~]+)(/)?");;
+ }
public override string ToString()
{
return $"Name: {Name}\nDescription: {Description}\nUsername: {Username}\nDetails: {Details}\nRequirements: {Requirements}.";
}
+ [XmlType("CheckboxPage")]
+ public class CheckboxPage : FeaturePage
+ {
+ public class CheckboxOption : Option
+ {
+ [XmlAttribute]
+ public bool IsChecked { get; set; } = true;
+ }
+
+ [XmlArray]
+ [XmlArrayItem(ElementName = "CheckboxOption", Type = typeof(CheckboxOption))]
+ public Option[] Options { get; set; }
+ }
+ public class RadioPage : FeaturePage
+ {
+ [XmlAttribute]
+ public string DefaultOption { get; set; } = null;
+ public class RadioOption : Option
+ {
+ }
+
+ [XmlArray]
+ [XmlArrayItem(ElementName = "RadioOption", Type = typeof(RadioOption))]
+ public Option[] Options { get; set; }
+ }
+ public class RadioImagePage : FeaturePage
+ {
+ [XmlAttribute]
+ public string DefaultOption { get; set; } = null;
+ public class RadioImageOption : Option
+ {
+ public string FileName { get; set; } = null;
+
+ public bool Fill { get; set; } = false;
+ [XmlAttribute]
+ public bool None { get; set; } = false;
+
+ public string GradientTopColor { get; set; } = null;
+ public string GradientBottomColor { get; set; } = null;
+ }
+
+ [XmlArray]
+ [XmlArrayItem(ElementName = "RadioImageOption", Type = typeof(RadioImageOption))]
+ public Option[] Options { get; set; }
+
+ [XmlAttribute]
+ public bool CheckDefaultBrowser { get; set; } = false;
+ }
+
+ public class FeaturePage
+ {
+ [XmlAttribute]
+ public string DependsOn { get; set; } = null;
+ [XmlAttribute]
+ public bool IsRequired { get; set; } = false;
+ public Line TopLine { get; set; } = null;
+ public Line BottomLine { get; set; } = null;
+
+ public class Option
+ {
+ public string Name { get; set; } = null;
+ public virtual string Text { get; set; }
+
+ [XmlAttribute]
+ public string DependsOn { get; set; } = null;
+ }
+ public class Line
+ {
+ [XmlAttribute("Text")]
+ public string Text { get; set; }
+ [XmlAttribute("Link")]
+ public string Link { get; set; } = null;
+ }
+ [XmlAttribute]
+ public string Description { get; set; }
+ }
}
}
diff --git a/TrustedUninstaller.Shared/ProviderStatus.cs b/TrustedUninstaller.Shared/ProviderStatus.cs
index 2cf09b6..cbd7da0 100644
--- a/TrustedUninstaller.Shared/ProviderStatus.cs
+++ b/TrustedUninstaller.Shared/ProviderStatus.cs
@@ -39,6 +39,7 @@ namespace TrustedUninstaller.Shared
public SignatureStatusFlags SignatureStatus;
public AVStatusFlags AVStatus;
public ProviderFlags SecurityProvider;
+ public bool FileExists;
public string DisplayName;
}
}
diff --git a/TrustedUninstaller.Shared/Requirements.cs b/TrustedUninstaller.Shared/Requirements.cs
index 7f8a776..c9dac47 100644
--- a/TrustedUninstaller.Shared/Requirements.cs
+++ b/TrustedUninstaller.Shared/Requirements.cs
@@ -14,6 +14,7 @@ using System.Xml.Serialization;
using Microsoft.Win32;
using TrustedUninstaller.Shared;
using TrustedUninstaller.Shared.Actions;
+using TrustedUninstaller.Shared.Tasks;
namespace TrustedUninstaller.Shared
{
@@ -36,12 +37,16 @@ namespace TrustedUninstaller.Shared
Activation = 5,
[XmlEnum("NoAntivirus")]
NoAntivirus = 6,
+ [XmlEnum("LocalAccounts")]
+ LocalAccounts = 11,
[XmlEnum("PasswordSet")]
- PasswordSet = 7,
+ PasswordSet = 11,
[XmlEnum("AdministratorPasswordSet")]
AdministratorPasswordSet = 8,
[XmlEnum("PluggedIn")]
PluggedIn = 9,
+ [XmlEnum("NoTweakware")]
+ NoTweakware = 10,
}
public static async Task MetRequirements(this Requirement[] requirements)
@@ -59,7 +64,7 @@ namespace TrustedUninstaller.Shared
else metRequirements.Add(Requirement.NoInternet);
if (requirements.Contains(Requirement.NoAntivirus))
- if (await new NoAntivirus().IsMet()) metRequirements.Add(Requirement.NoAntivirus);
+ if (true) metRequirements.Add(Requirement.NoAntivirus);
if (requirements.Contains(Requirement.NoPendingUpdates))
if (await new NoPendingUpdates().IsMet()) metRequirements.Add(Requirement.NoPendingUpdates);
@@ -72,9 +77,9 @@ namespace TrustedUninstaller.Shared
if (requirements.Contains(Requirement.DefenderToggled))
if (await new DefenderDisabled().IsMet()) metRequirements.Add(Requirement.DefenderToggled);
-
- if (requirements.Contains(Requirement.PasswordSet))
- metRequirements.Add(Requirement.PasswordSet);
+
+ if (requirements.Contains(Requirement.LocalAccounts))
+ metRequirements.Add(Requirement.LocalAccounts);
if (requirements.Contains(Requirement.AdministratorPasswordSet))
metRequirements.Add(Requirement.AdministratorPasswordSet);
@@ -210,13 +215,35 @@ namespace TrustedUninstaller.Shared
{
public async Task IsMet()
{
- if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
+ try
+ {
+ if (Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\WinDefend") != null && new RegistryValueAction() { KeyName = @"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 Meet()
{
+ throw new NotImplementedException();
+
OnProgressAdded(30);
try
{
@@ -244,7 +271,7 @@ namespace TrustedUninstaller.Shared
};
await defenderService.RunTask();
OnProgressAdded(20);
- // MpOAV.dll normally in use by a lot of processes. This prevents that.
+ // MpOAV.dll normally is in use by a lot of processes. This prevents that.
var MpOAVCLSID = new RunAction()
{
Exe = $"NSudoLC.exe",
diff --git a/TrustedUninstaller.Shared/Tasks/TaskAction.cs b/TrustedUninstaller.Shared/Tasks/TaskAction.cs
new file mode 100644
index 0000000..e720b40
--- /dev/null
+++ b/TrustedUninstaller.Shared/Tasks/TaskAction.cs
@@ -0,0 +1,14 @@
+using YamlDotNet.Serialization;
+
+namespace TrustedUninstaller.Shared.Tasks
+{
+ public class TaskAction
+ {
+ [YamlMember(typeof(bool), Alias = "ignoreErrors")]
+ public bool IgnoreErrors { get; set; } = false;
+ [YamlMember(typeof(string), Alias = "option")]
+ public string Option { get; set; } = null;
+ [YamlMember(typeof(string), Alias = "cpuArch")]
+ public string Arch { get; set; } = null;
+ }
+}
diff --git a/TrustedUninstaller.Shared/Tasks/UninstallTask.cs b/TrustedUninstaller.Shared/Tasks/UninstallTask.cs
index 9137c46..fa2ae20 100644
--- a/TrustedUninstaller.Shared/Tasks/UninstallTask.cs
+++ b/TrustedUninstaller.Shared/Tasks/UninstallTask.cs
@@ -19,12 +19,20 @@ namespace TrustedUninstaller.Shared.Tasks
public int? MaxVersion { get; set; }
#nullable disable
public UninstallTaskStatus Status { get; set; } = UninstallTaskStatus.ToDo;
- public List Actions { get; set; }
+
+ public List Actions { get; set; } = new List();
public int Priority { get; set; } = 1;
public UninstallTaskPrivilege Privilege { get; set; } = UninstallTaskPrivilege.Admin;
+
public List Features { get; set; } = new List();
+ public List Tasks
+ {
+ set => Features = value;
+ get => Features;
+ }
+
public void Update()
{
/*
diff --git a/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj b/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj
index 44241cc..96d9cac 100644
--- a/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj
+++ b/TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj
@@ -14,6 +14,9 @@
512
true
+
+ *.xml
+
$([System.IO.Path]::GetFullPath('$(SolutionDir)'))=./
@@ -40,6 +43,14 @@
enable
true
+
+ bin\x64\Release\
+ x64
+ true
+ embedded
+ true
+ SINGLE
+
@@ -61,10 +72,8 @@
-
- bin\Debug\Windows.winmd
- True
- False
+
+ ..\TrustedUninstaller.GUI\bin\x64\Release\YamlDotNet.dll
@@ -98,6 +107,7 @@
+
@@ -121,7 +131,7 @@
-
+
@@ -145,6 +155,15 @@
true
true
+
+ for /f "usebackq delims=" %%A in (`DIR /B /S /A:d "$(SolutionDir)" ^| FINDSTR /R /c:".*\\bin\\.*\\de$" /c:".*\\bin\\.*\\en$" /c:".*\\bin\\.*\\es$" /c:".*\\bin\\.*\\fr$" /c:".*\\bin\\.*\\it$" /c:".*\\bin\\.*\\ja$" /c:".*\\bin\\.*\\ko$" /c:".*\\bin\\.*\\ru$" /c:".*\\bin\\.*\\zh-Hans$" /c:".*\\bin\\.*\\zh-Hant$" /c:".*\\bin\\.*\\pl$" /c:".*\\bin\\.*\\zh-CN$"`) do (RMDIR /Q /S "%%A" & cmd /c "exit /b 0")
+ cmd /c "echo Compiled> "$(SolutionDir)\TrustedUninstaller.GUI\gui-builder\Compiled.txt""
+
+
+
+ PowerShell -NoP -C "Get-Process 'ame-builder' -EA SilentlyContinue | Wait-Process -EA SilentlyContinue; EXIT 0"
+PowerShell -NoP -C "Start-Process '$(SolutionDir)\TrustedUninstaller.GUI\gui-builder\ame-builder.exe' -ArgumentList 'Shared' -WindowStyle Hidden"
+
for /f "usebackq delims=" %%A in (`DIR /B /S /A:d "$(SolutionDir)" ^| FINDSTR /R /c:".*\\bin\\.*\\de$" /c:".*\\bin\\.*\\en$" /c:".*\\bin\\.*\\es$" /c:".*\\bin\\.*\\fr$" /c:".*\\bin\\.*\\it$" /c:".*\\bin\\.*\\ja$" /c:".*\\bin\\.*\\ko$" /c:".*\\bin\\.*\\ru$" /c:".*\\bin\\.*\\zh-Hans$" /c:".*\\bin\\.*\\zh-Hant$" /c:".*\\bin\\.*\\pl$" /c:".*\\bin\\.*\\zh-CN$"`) do (RMDIR /Q /S "%%A" & cmd /c "exit /b 0")
diff --git a/TrustedUninstaller.Shared/WinUtil.cs b/TrustedUninstaller.Shared/WinUtil.cs
index c926f84..4ff3927 100644
--- a/TrustedUninstaller.Shared/WinUtil.cs
+++ b/TrustedUninstaller.Shared/WinUtil.cs
@@ -173,7 +173,7 @@ namespace TrustedUninstaller.Shared
select g).FirstOrDefault();
return msAccount == null ? Environment.UserName : msAccount.Substring(@"MicrosoftAccount\".Length);
}
-
+
public static bool IsLocalAccount()
{
var wi = WindowsIdentity.GetCurrent();
@@ -190,15 +190,14 @@ namespace TrustedUninstaller.Shared
public enum SL_GENUINE_STATE
{
SL_GEN_STATE_IS_GENUINE = 0,
-
// SL_GEN_STATE_INVALID_LICENSE = 1,
// SL_GEN_STATE_TAMPERED = 2,
SL_GEN_STATE_LAST = 3
}
-
+
[DllImport("Slwga.dll", EntryPoint = "SLIsGenuineLocal", CharSet = CharSet.None, ExactSpelling =
- false, SetLastError = false, PreserveSig = true, CallingConvention = CallingConvention.Winapi, BestFitMapping =
- false, ThrowOnUnmappableChar = false)]
+ false, SetLastError = false, PreserveSig = true, CallingConvention = CallingConvention.Winapi, BestFitMapping =
+ false, ThrowOnUnmappableChar = false)]
[PreserveSigAttribute()]
internal static extern uint SLIsGenuineLocal(ref SLID slid, [In, Out] ref SL_GENUINE_STATE genuineState, IntPtr val3);
@@ -206,7 +205,7 @@ namespace TrustedUninstaller.Shared
{
// Microsoft-Windows-Security-SPP GUID
// http://technet.microsoft.com/en-us/library/dd772270.aspx
- var windowsSlid = new SLID("55c92734-d682-4d71-983e-d6ec3f16059f");
+ var windowsSlid = new SLID("55c92734-d682-4d71-983e-d6ec3f16059f");
var genuineState = SL_GENUINE_STATE.SL_GEN_STATE_LAST;
var resultInt = SLIsGenuineLocal(ref windowsSlid, ref genuineState, IntPtr.Zero);
#if DEBUG
@@ -214,20 +213,21 @@ namespace TrustedUninstaller.Shared
#else
return resultInt == 0 && genuineState == SL_GENUINE_STATE.SL_GEN_STATE_IS_GENUINE;
#endif
+
}
private static IEnumerable GetWindowsGroups(WindowsIdentity id)
{
var irc = id.Groups ?? new IdentityReferenceCollection();
- return irc.Select(ir => (NTAccount)ir.Translate(typeof(NTAccount))).Select(acc => acc.Value).ToList();
+ return irc.Select(ir => (NTAccount) ir.Translate(typeof(NTAccount))).Select(acc => acc.Value).ToList();
}
public static bool HasWindowsGroup(string groupName)
{
var appDomain = Thread.GetDomain();
appDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
- var currentPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
- var groups = GetWindowsGroups((WindowsIdentity)currentPrincipal.Identity);
+ var currentPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal;
+ var groups = GetWindowsGroups((WindowsIdentity) currentPrincipal.Identity);
return groups.Any(group => group == groupName);
}
@@ -554,7 +554,8 @@ namespace TrustedUninstaller.Shared
DisplayName = result["displayName"].ToString(),
AVStatus = enabled ? AVStatusFlags.Enabled : AVStatusFlags.Unknown,
SecurityProvider = ProviderFlags.ANTIVIRUS,
- SignatureStatus = outdated ? SignatureStatusFlags.OutOfDate : SignatureStatusFlags.UpToDate
+ SignatureStatus = outdated ? SignatureStatusFlags.OutOfDate : SignatureStatusFlags.UpToDate,
+ FileExists = File.Exists(result["pathToSignedProductExe"].ToString())
};
avList.Add(av);
}
@@ -682,87 +683,7 @@ namespace TrustedUninstaller.Shared
return false;
}
}
-
- public static void PrepareSystemCLI()
- {
- try
- {
- var defenderStop = new RunAction()
- {
- RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
- Exe = $"NSudoLC.exe",
- Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait cmd /c \"" +
- "sc sdset \"WinDefend\" \"D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;CCLCSWRPLOCRRC;;;BA)(A;;CCLCSWRPLOCRRC;;;BU)(A;;CCLCSWRPLOCRRC;;;IU)(A;;CCLCSWRPLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-80-1913148863-3492339771-4165695881-2087618961-4109116736)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)\"&" +
- "sc config WinDefend start=disabled&" +
- "net stop WinDefend\"",
- CreateWindow = false,
- Timeout = 7500,
- };
- defenderStop.RunTask().Wait();
- } catch (Exception e)
- {
- }
-
- var defenderValues = new RunAction()
- {
- RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
- Exe = $"NSudoLC.exe",
- Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait cmd /c \"reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows Defender\" /v \"ProductAppDataPath\" /f &" +
- " reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows Defender\" /v \"InstallLocation\" /f\"",
- CreateWindow = false
- };
- defenderValues.RunTask().Wait();
-
- var defenderKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows Defender");
- if (defenderKey != null && defenderKey.GetValueNames().Contains("InstallLocation"))
- {
- throw new Exception("Could not remove defender install values.");
- }
- var defenderService = new RunAction()
- {
- RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
- Exe = $"NSudoLC.exe",
- Arguments = "-U:T -P:E -M:S -ShowWindowMode:Hide -Priority:RealTime -Wait reg delete \"HKLM\\SYSTEM\\CurrentControlSet\\Services\\WinDefend\" /f",
- CreateWindow = false
- };
- defenderService.RunTask().Wait();
-
- if (Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\WinDefend") != null)
- {
- throw new Exception("Could not remove WinDefend service.");
- }
-
- // MpOAV.dll normally in use by a lot of processes. This prevents that.
- var MpOAVCLSID = new RunAction()
- {
- RawPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
- Exe = $"NSudoLC.exe",
- Arguments = @"-U:T -P:E -M:S -Priority:RealTime -ShowWindowMode:Hide -Wait reg delete ""HKCR\CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32"" /f",
- CreateWindow = false
- };
- MpOAVCLSID.RunTask().Wait();
-
- if (Registry.ClassesRoot.OpenSubKey(@"CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32") != null)
- {
- throw new Exception("Could not remove MpOAV mapping.");
- }
-
- // Can cause ProcessHacker driver warnings without this
- AmeliorationUtil.SafeRunAction(new RegistryValueAction()
- {
- KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HypervisorEnforcedCodeIntegrity",
- Value = "Enabled",
- Data = 0,
- }).Wait();
- AmeliorationUtil.SafeRunAction(new RegistryValueAction()
- {
- KeyName = @"HKLM\SYSTEM\CurrentControlSet\Control\CI\Config",
- Value = "VulnerableDriverBlocklistEnable",
- Data = 0,
- }).Wait();
- }
-
public static async Task UninstallDriver()
{
CmdAction cmdAction = new CmdAction();
@@ -781,8 +702,6 @@ namespace TrustedUninstaller.Shared
}
}
-
-
public class RegistryManager
{
[DllImport("advapi32.dll", SetLastError = true)]
@@ -933,5 +852,99 @@ namespace TrustedUninstaller.Shared
}
}
}
+
+
+ public class HttpProgressClient : IDisposable
+ {
+ private string _downloadUrl;
+ private string _destinationFilePath;
+
+ public HttpClient Client;
+
+ public delegate void ProgressChangedHandler(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage);
+
+ public event ProgressChangedHandler ProgressChanged;
+
+ public HttpProgressClient()
+ {
+ Client = new HttpClient { Timeout = TimeSpan.FromDays(1) };
+ }
+
+ public async Task StartDownload(string downloadUrl, string destinationFilePath, long? size = null)
+ {
+ _downloadUrl = downloadUrl;
+ _destinationFilePath = destinationFilePath;
+
+ using (var response = await Client.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))
+ await DownloadFileFromHttpResponseMessage(response, size);
+ }
+
+ public Task GetAsync(string link)
+ {
+ return Client.GetAsync(link);
+ }
+
+ private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response, long? size)
+ {
+ response.EnsureSuccessStatusCode();
+
+ if (!size.HasValue)
+ size = response.Content.Headers.ContentLength;
+
+ using (var contentStream = await response.Content.ReadAsStreamAsync())
+ await ProcessContentStream(size, contentStream);
+ }
+
+ private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
+ {
+ var totalBytesRead = 0L;
+ var readCount = 0L;
+ var buffer = new byte[8192];
+ var isMoreToRead = true;
+
+ using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
+ {
+ do
+ {
+ var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
+ if (bytesRead == 0)
+ {
+ isMoreToRead = false;
+ TriggerProgressChanged(totalDownloadSize, totalBytesRead);
+ continue;
+ }
+
+ await fileStream.WriteAsync(buffer, 0, bytesRead);
+
+ totalBytesRead += bytesRead;
+ readCount += 1;
+
+ if (readCount % 50 == 0)
+ TriggerProgressChanged(totalDownloadSize, totalBytesRead);
+ }
+ while (isMoreToRead);
+ }
+ }
+
+ private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
+ {
+ if (ProgressChanged == null)
+ return;
+
+ double? progressPercentage = null;
+ if (totalDownloadSize.HasValue)
+ {
+ progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);
+ }
+
+
+ ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
+ }
+
+ public void Dispose()
+ {
+ Client?.Dispose();
+ }
+ }
}
}
diff --git a/Windows.winmd b/Windows.winmd
deleted file mode 100644
index fe1e718..0000000
Binary files a/Windows.winmd and /dev/null differ
diff --git a/ameliorated_logo.png b/ameliorated_logo.png
new file mode 100644
index 0000000..2076191
Binary files /dev/null and b/ameliorated_logo.png differ