Browse Source

Update to v0.7.1

master 0.7.1
Styris 9 months ago
parent
commit
7147425b5d
5 changed files with 1807 additions and 136 deletions
  1. +134
    -133
      TrustedUninstaller.CLI/CLI.cs
  2. +1
    -1
      TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj
  3. +53
    -2
      TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs
  4. +1618
    -0
      TrustedUninstaller.Shared/Defender.cs
  5. +1
    -0
      TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj

+ 134
- 133
TrustedUninstaller.CLI/CLI.cs View File

@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Win32;
@ -22,6 +23,11 @@ namespace TrustedUninstaller.CLI
//After the auto start up.
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
if (args.Length == 1 && args[0] == "-DisableDefender")
{
return DisableDefender();
}
DualOut.Init();
if (!WinUtil.IsAdministrator())
@ -44,19 +50,19 @@ namespace TrustedUninstaller.CLI
Console.WriteLine("No Playbook selected.");
return -1;
}
AmeliorationUtil.Playbook = await AmeliorationUtil.DeserializePlaybook(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.");
Console.WriteLine($"Current directory: {Directory.GetCurrentDirectory()}");
return -1;
}
ExtractResourceFolder("resources", Directory.GetCurrentDirectory());
if (!WinUtil.IsTrustedInstaller())
{
Console.WriteLine("Checking requirements...\r\n");
@ -64,7 +70,7 @@ namespace TrustedUninstaller.CLI
{
Console.WriteLine("Internet must be connected to run this Playbook.");
}
if (AmeliorationUtil.Playbook.Requirements.Contains(Requirements.Requirement.DefenderDisabled) && Process.GetProcessesByName("MsMpEng").Any())
{
bool first = true;
@ -74,9 +80,9 @@ 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();
}
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
@ -103,8 +109,8 @@ namespace TrustedUninstaller.CLI
Console.WriteLine("Error preparing system: " + e.Message);
Environment.Exit(-1);
}
}
if (AmeliorationUtil.Playbook.Requirements.Contains(Requirements.Requirement.Internet) && !await (new Requirements.Internet()).IsMet())
{
Console.WriteLine("Internet must be connected to run this Playbook.");
@ -147,28 +153,29 @@ namespace TrustedUninstaller.CLI
try
{
File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CLI-Resources.7z"));
} catch (Exception e)
{
}
catch (Exception e) { }
}
}
catch (Exception e)
} catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.Message,
e.StackTrace, "Error extracting resources.");
Console.WriteLine($":AME-Fatal Error: Error extracting resources.");
return -1;
}
await AmeliorationUtil.StartAmelioration();
return 0;
}
public static void ExtractArchive(string file, string targetDir)
{
RunCommand($"x \"{file}\" -o\"{targetDir}\" -p\"wizard\" -y -aos");
}
private static void RunCommand(string command)
{
var proc = new Process();
@ -181,15 +188,15 @@ namespace TrustedUninstaller.CLI
FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "7za.exe"),
RedirectStandardError = true,
};
proc.StartInfo = startInfo;
proc.Start();
StringBuilder errorOutput = new StringBuilder("");
proc.ErrorDataReceived += (sender, args) => { errorOutput.Append("\r\n" + args.Data); };
proc.BeginErrorReadLine();
proc.WaitForExit();
proc.CancelErrorRead();
@ -199,7 +206,8 @@ namespace TrustedUninstaller.CLI
if (proc.ExitCode > 1)
throw new ArgumentOutOfRangeException("Error running 7zip: " + errorOutput.ToString());
}
public static void ExtractResourceFolder(string resource, string dir, bool overwrite = false)
public static void ExtractResourceFolder(string resource, string dir, bool overwrite = false)
{
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
@ -216,7 +224,7 @@ namespace TrustedUninstaller.CLI
var file = dir + $"\\{obj.Substring($"TrustedUninstaller.CLI.Properties.{resource}.".Length).Replace("---", "\\")}";
if (file.EndsWith(".gitkeep")) continue;
var fileDir = Path.GetDirectoryName(file);
if (fileDir != null && !Directory.Exists(fileDir)) Directory.CreateDirectory(fileDir);
@ -226,8 +234,7 @@ namespace TrustedUninstaller.CLI
try
{
File.Delete(file);
}
catch (Exception e)
} catch (Exception e)
{
if (!Directory.Exists(Directory.GetCurrentDirectory() + "\\Logs"))
Directory.CreateDirectory(Directory.GetCurrentDirectory() + "\\Logs");
@ -237,6 +244,7 @@ namespace TrustedUninstaller.CLI
writer.WriteLine("\r\nDate/Time: " + DateTime.Now);
writer.WriteLine("============================================");
}
continue;
}
}
@ -264,7 +272,7 @@ namespace TrustedUninstaller.CLI
}
}
}
public static async Task<List<bool>> GetDefenderToggles()
{
var result = new List<bool>();
@ -281,32 +289,31 @@ namespace TrustedUninstaller.CLI
try
{
realtimePolicy = policiesKey.OpenSubKey("Real-Time Protection");
} catch (Exception e)
{
}
catch (Exception e) { }
if (realtimePolicy != null)
realtimeKey = realtimePolicy;
else
realtimeKey = defenderKey.OpenSubKey("Real-Time Protection");
}
catch
} catch
{
result.Add(false);
}
if (realtimeKey != null)
{
try
{
result.Add((int)realtimeKey.GetValue("DisableRealtimeMonitoring") != 1);
}
catch (Exception exception)
} catch (Exception exception)
{
try
{
realtimeKey = defenderKey.OpenSubKey("Real-Time Protection");
result.Add((int)realtimeKey.GetValue("DisableRealtimeMonitoring") != 1);
}
catch (Exception e)
} catch (Exception e)
{
result.Add(true);
}
@ -317,12 +324,13 @@ namespace TrustedUninstaller.CLI
{
RegistryKey spynetPolicy = null;
RegistryKey spynetKey = null;
try
{
spynetPolicy = policiesKey.OpenSubKey("SpyNet");
} catch (Exception e)
{
}
catch (Exception e) { }
if (spynetPolicy != null)
spynetKey = spynetPolicy;
@ -334,19 +342,18 @@ namespace TrustedUninstaller.CLI
try
{
reporting = (int)spynetKey.GetValue("SpyNetReporting");
}
catch (Exception e)
} catch (Exception e)
{
if (spynetPolicy != null)
{
reporting = (int)defenderKey.OpenSubKey("SpyNet").GetValue("SpyNetReporting");
}
}
try
{
consent = (int)spynetKey.GetValue("SubmitSamplesConsent");
}
catch (Exception e)
} catch (Exception e)
{
if (spynetPolicy != null)
{
@ -356,131 +363,125 @@ namespace TrustedUninstaller.CLI
result.Add(reporting != 0);
result.Add(consent != 0 && consent != 2 && consent != 4);
}
catch
} catch
{
result.Add(false);
result.Add(false);
}
try
{
int tamper = (int)defenderKey.OpenSubKey("Features").GetValue("TamperProtection");
result.Add(tamper != 4 && tamper != 0);
}
catch
} catch
{
result.Add(false);
}
});
return result;
}
public static void PrepareSystemCLI()
private static int DisableDefender()
{
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)
{
Defender.Disable();
}
var defenderValues = new RunAction()
catch (Exception ex)
{
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();
ErrorLogger.WriteToErrorLog(ex.GetType() + ": " + ex.Message, ex.StackTrace,
$"First Defender disable failed from second process.");
Defender.Kill();
try
{
Defender.Disable();
}
catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.GetType() + ": " + e.Message, e.StackTrace,
$"Could not disable Windows Defender from second process.");
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.");
return 1;
}
}
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)
return 0;
}
public static void PrepareSystemCLI()
{
try
{
var disableDefender = new RunAction()
if (!Defender.Kill())
{
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 = @"HKLM\SYSTEM\CurrentControlSet\Services\WinDefend", Value = "Start", Data = 4, Type = RegistryValueType.REG_DWORD}.GetStatus() != UninstallTaskStatus.Completed)
throw new Exception("Could not disable WinDefend service.");
}
ErrorLogger.WriteToErrorLog("Unknown reason", null, "Could not kill Defender");
// 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();
try
{
var process = Defender.StartElevatedProcess(Assembly.GetExecutingAssembly().Location, $@"-DisableDefender");
var exitCode = Defender.WaitForProcessExit(process, 10000);
if (exitCode != 0)
throw new Exception("Exit code was nonzero.");
} catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.GetType() + ": " + e.Message, e.StackTrace, "First Defender disable failed");
if (Registry.ClassesRoot.OpenSubKey(@"CLSID\{2781761E-28E0-4109-99FE-B9D127C57AFE}\InprocServer32") != null)
{
throw new Exception("Could not remove MpOAV mapping.");
}
Thread.Sleep(1000);
if (!Defender.Kill())
{
Thread.Sleep(3000);
Defender.Kill();
}
// 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()
try
{
var process = Defender.StartElevatedProcess(Assembly.GetExecutingAssembly().Location, $@"-DisableDefender");
var exitCode = Defender.WaitForProcessExit(process, 10000);
if (exitCode != 0)
throw new Exception("Exit code was nonzero.");
} catch (Exception exception)
{
ErrorLogger.WriteToErrorLog(e.GetType() + ": " + e.Message, e.StackTrace, "Second Defender disable failed");
Defender.Disable();
}
}
}
else
{
try
{
var process = Defender.StartElevatedProcess(Assembly.GetExecutingAssembly().Location, $@"-DisableDefender");
var exitCode = Defender.WaitForProcessExit(process, 15000);
if (exitCode != 0)
throw new Exception("Exit code was nonzero.");
} catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.GetType() + ": " + e.Message, e.StackTrace, "First Defender disable failed");
Defender.Disable();
}
}
} catch
{
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;
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;
}
}
}
}
}
}

+ 1
- 1
TrustedUninstaller.CLI/TrustedUninstaller.CLI.csproj View File

@ -152,7 +152,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.0" />
<PackageReference Include="Microsoft.PowerShell.5.ReferenceAssemblies" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="SQLitePCLRaw.core" Version="2.0.7" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.CodeDom" Version="6.0.0" />


+ 53
- 2
TrustedUninstaller.Shared/Actions/RegistryKeyAction.cs View File

@ -4,8 +4,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.Win32;
using TrustedUninstaller.Shared.Exceptions;
using TrustedUninstaller.Shared.Tasks;
@ -34,6 +36,36 @@ namespace TrustedUninstaller.Shared.Actions
public int ProgressWeight { get; set; } = 1;
public int GetProgressWeight() => ProgressWeight;
static Dictionary<RegistryHive, UIntPtr> HiveKeys = new Dictionary<RegistryHive, UIntPtr> {
{ RegistryHive.ClassesRoot, new UIntPtr(0x80000000u) },
{ RegistryHive.CurrentConfig, new UIntPtr(0x80000005u) },
{ RegistryHive.CurrentUser, new UIntPtr(0x80000001u) },
{ RegistryHive.DynData, new UIntPtr(0x80000006u) },
{ RegistryHive.LocalMachine, new UIntPtr(0x80000002u) },
{ RegistryHive.PerformanceData, new UIntPtr(0x80000004u) },
{ RegistryHive.Users, new UIntPtr(0x80000003u) }
};
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
[DllImport("advapi32.dll", EntryPoint = "RegDeleteKeyEx", SetLastError = true)]
private static extern int RegDeleteKeyEx(
UIntPtr hKey,
string lpSubKey,
uint samDesired, // see Notes below
uint Reserved);
private static void DeleteKeyTreeWin32(string key, RegistryHive hive)
{
var openedKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default).OpenSubKey(key);
if (openedKey == null)
return;
openedKey.GetSubKeyNames().ToList().ForEach(subKey => DeleteKeyTreeWin32(key + "\\" + subKey, hive));
openedKey.Close();
RegDeleteKeyEx(HiveKeys[hive], key, 0x0100, 0);
}
private bool InProgress { get; set; }
public void ResetProgress() => InProgress = false;
@ -153,7 +185,7 @@ namespace TrustedUninstaller.Shared.Actions
public async Task<bool> RunTask()
{
Console.WriteLine($"{Operation.ToString().TrimEnd('e')}ing registry key '{KeyName}'...");
var roots = GetRoots();
foreach (var _root in roots)
@ -184,7 +216,26 @@ namespace TrustedUninstaller.Shared.Actions
}
if (Operation == RegistryKeyOperation.Delete)
{
root.DeleteSubKeyTree(subKey, false);
try
{
root.DeleteSubKeyTree(subKey, false);
}
catch (Exception e)
{
ErrorLogger.WriteToErrorLog(e.GetType() + ": " + e.Message,
e.StackTrace, "RegistryKeyAction Warning", root?.Name + "\\" + subKey);
var rootHive = root.Name.Split('\\').First() switch
{
"HKEY_CURRENT_USER" => RegistryHive.CurrentUser,
"HKEY_LOCAL_MACHINE" => RegistryHive.LocalMachine,
"HKEY_CLASSES_ROOT" => RegistryHive.ClassesRoot,
"HKEY_USERS" => RegistryHive.Users,
_ => throw new ArgumentException($"Unable to parse: " + root.Name.Split('\\').First())
};
DeleteKeyTreeWin32(root.Name.StartsWith("HKEY_USERS") ? root.Name.Split('\\')[1] + "\\" + subKey: subKey, rootHive);
}
}
}
catch (Exception e)


+ 1618
- 0
TrustedUninstaller.Shared/Defender.cs
File diff suppressed because it is too large
View File


+ 1
- 0
TrustedUninstaller.Shared/TrustedUninstaller.Shared.csproj View File

@ -95,6 +95,7 @@
<Compile Include="Actions\UserAction.cs" />
<Compile Include="Actions\WriteStatusAction.cs" />
<Compile Include="AmeliorationUtil.cs" />
<Compile Include="Defender.cs" />
<Compile Include="DualOut.cs" />
<Compile Include="Globals.cs" />
<Compile Include="Playbook.cs" />


Loading…
Cancel
Save