├── README.md ├── SeroXen Removal Tool.sln └── SeroXen Removal Tool ├── App.config ├── FodyWeavers.xml ├── FodyWeavers.xsd ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── SeroXen Removal Tool.csproj ├── Unhook.cs └── packages.config /README.md: -------------------------------------------------------------------------------- 1 | # SeroXen Removal Tool 2 | 3 | This tool is used to find and remove all traces of the SeroXen Remote Administration Tool. 4 | 5 | Tested on version **v3.1.5** (latest at the time of writing). 6 | 7 | This is a updated version of SeroXen-Removal-Tool by a good friend DaXcess, you can find the original project that used to be on SeroXen's website here: https://github.com/DaXcess/SeroXen-Removal-Tool. 8 | -------------------------------------------------------------------------------- /SeroXen Removal Tool.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34330.188 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeroXen Removal Tool", "SeroXen Removal Tool\SeroXen Removal Tool.csproj", "{FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|x64.ActiveCfg = Debug|x64 21 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|x64.Build.0 = Debug|x64 22 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|x86.ActiveCfg = Debug|Any CPU 23 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Debug|x86.Build.0 = Debug|Any CPU 24 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|x64.ActiveCfg = Release|x64 27 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|x64.Build.0 = Release|x64 28 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|x86.ActiveCfg = Release|Any CPU 29 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E}.Release|x86.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {D9CDCB2F-042E-462B-82A1-2283593568A2} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 23 | 24 | 25 | 26 | 27 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 28 | 29 | 30 | 31 | 32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 38 | 39 | 40 | 41 | 42 | The order of preloaded assemblies, delimited with line breaks. 43 | 44 | 45 | 46 | 47 | 48 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 49 | 50 | 51 | 52 | 53 | Controls if .pdbs for reference assemblies are also embedded. 54 | 55 | 56 | 57 | 58 | Controls if runtime assemblies are also embedded. 59 | 60 | 61 | 62 | 63 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. 64 | 65 | 66 | 67 | 68 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 69 | 70 | 71 | 72 | 73 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 74 | 75 | 76 | 77 | 78 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 79 | 80 | 81 | 82 | 83 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 84 | 85 | 86 | 87 | 88 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 89 | 90 | 91 | 92 | 93 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 94 | 95 | 96 | 97 | 98 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 99 | 100 | 101 | 102 | 103 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. 104 | 105 | 106 | 107 | 108 | A list of unmanaged 32 bit assembly names to include, delimited with |. 109 | 110 | 111 | 112 | 113 | A list of unmanaged 64 bit assembly names to include, delimited with |. 114 | 115 | 116 | 117 | 118 | The order of preloaded assemblies, delimited with |. 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 127 | 128 | 129 | 130 | 131 | A comma-separated list of error codes that can be safely ignored in assembly verification. 132 | 133 | 134 | 135 | 136 | 'false' to turn off automatic generation of the XML Schema file. 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using Microsoft.Win32.TaskScheduler; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | using System.Security.Principal; 11 | using System.Threading; 12 | using System.Windows.Forms; 13 | using static SeroXen_Removal_Tool.Native; 14 | 15 | namespace SeroXen_Removal_Tool 16 | { 17 | internal class Program 18 | { 19 | static unsafe void Main(string[] args) 20 | { 21 | if (!IsAdmin()) 22 | { 23 | if (!Confirm("[?] You must run this tool with Administrator privileges, would you like to do that?", true)) 24 | return; 25 | 26 | try 27 | { 28 | Restart(true); 29 | } 30 | catch 31 | { 32 | Console.WriteLine("[-] Failed to restart with administrator privileges. Press any key to exit..."); 33 | Console.ReadKey(true); 34 | } 35 | 36 | return; 37 | } 38 | 39 | try 40 | { 41 | using (TaskService ts = new TaskService()) 42 | { 43 | if (ts.RootFolder.Tasks.Exists(@"SeroXen Removal Task") == false) 44 | { 45 | DialogResult dialogResult = MessageBox.Show(@"To initalize the SeroXen Removal Tool we need to reboot your PC, do you want to reboot now?", @"SeroXen Removal Tool", MessageBoxButtons.YesNo); 46 | if (dialogResult == DialogResult.Yes) 47 | { 48 | TaskDefinition td = ts.NewTask(); 49 | td.Triggers.Add(new LogonTrigger()); 50 | td.Actions.Add(new ExecAction(Application.ExecutablePath, @"--force", null)); 51 | td.Settings.DisallowStartIfOnBatteries = false; 52 | td.Principal.RunLevel = TaskRunLevel.Highest; 53 | ts.RootFolder.RegisterTaskDefinition(@"SeroXen Removal Task", td); 54 | 55 | ProcessStartInfo startInfo = new ProcessStartInfo(); 56 | startInfo.WindowStyle = ProcessWindowStyle.Hidden; 57 | startInfo.UseShellExecute = true; 58 | startInfo.Arguments = @"/r /f /t 0"; 59 | startInfo.FileName = @"shutdown.exe"; 60 | Process.Start(startInfo); 61 | Environment.Exit(-1); 62 | } 63 | else if (dialogResult == DialogResult.No) 64 | { 65 | Environment.Exit(-1); 66 | } 67 | } 68 | else 69 | { 70 | ts.RootFolder.DeleteTask(@"SeroXen Removal Task", false); 71 | } 72 | } 73 | } 74 | catch 75 | { 76 | } 77 | 78 | Process.EnterDebugMode(); 79 | 80 | var iocs = ScanIOCs(); 81 | 82 | if (iocs.Length > 0) 83 | { 84 | Console.WriteLine("\n[*] One or multiple indicators of compromise were detected."); 85 | 86 | if (iocs.Contains(IndicatorOfCompromise.Process)) 87 | { 88 | IOCCleaner.CleanProcesses(); 89 | } 90 | 91 | foreach (var ioc in iocs) 92 | { 93 | switch (ioc) 94 | { 95 | case IndicatorOfCompromise.Files: 96 | IOCCleaner.CleanFiles(); 97 | break; 98 | 99 | case IndicatorOfCompromise.ScheduledTask: 100 | IOCCleaner.CleanScheduledTask(); 101 | break; 102 | 103 | case IndicatorOfCompromise.Environment: 104 | IOCCleaner.CleanEnvironment(); 105 | break; 106 | 107 | case IndicatorOfCompromise.Registry: 108 | IOCCleaner.CleanRegistry(); 109 | break; 110 | } 111 | } 112 | 113 | Console.WriteLine("[+] Cleaned up the mess."); 114 | 115 | Console.WriteLine("[!] It is recommended to reboot your PC to flush out the rootkit entirely.\n"); 116 | Console.WriteLine("[*] Press any key to exit..."); 117 | } 118 | else 119 | { 120 | Console.WriteLine("[+] No indicators of compromise found. Press any key to exit..."); 121 | } 122 | 123 | Console.ReadKey(true); 124 | } 125 | 126 | static bool Confirm(string prompt, bool @default = false) 127 | { 128 | while (true) { 129 | Console.Write($"{prompt} [{(@default ? "Y" : "y")}/{(@default ? "n" : "N")}] "); 130 | 131 | var key = Console.ReadKey(true); 132 | 133 | if (key.Key == ConsoleKey.Enter) 134 | { 135 | Console.WriteLine(@default ? "Yes" : "No"); 136 | return @default; 137 | } 138 | 139 | switch (key.KeyChar.ToString().ToLower()) 140 | { 141 | case "y": 142 | Console.WriteLine("Yes"); 143 | return true; 144 | 145 | case "n": 146 | Console.WriteLine("No"); 147 | return false; 148 | 149 | default: 150 | Console.WriteLine(); 151 | break; 152 | } 153 | } 154 | } 155 | 156 | static bool IsAdmin() 157 | { 158 | var identity = WindowsIdentity.GetCurrent(); 159 | var principal = new WindowsPrincipal(identity); 160 | return principal.IsInRole(WindowsBuiltInRole.Administrator); 161 | } 162 | 163 | public static void Restart(bool runas = false, string args = "") 164 | { 165 | Process.Start(new ProcessStartInfo() 166 | { 167 | FileName = Assembly.GetExecutingAssembly().Location, 168 | Arguments = args, 169 | Verb = runas ? "runas" : "", 170 | }); 171 | 172 | Environment.Exit(0); 173 | } 174 | 175 | static IndicatorOfCompromise[] ScanIOCs() 176 | { 177 | var list = new List(); 178 | 179 | if (IOCDetector.RootkitIOC()) 180 | { 181 | Console.WriteLine("[!] SeroXen rootkit detected in memory."); 182 | list.Add(IndicatorOfCompromise.Rootkit); 183 | 184 | IOCCleaner.DetachRootkit(); 185 | } 186 | 187 | if (IOCDetector.FilesIOC()) 188 | { 189 | Console.WriteLine("[!] SeroXen detected in the File System."); 190 | list.Add(IndicatorOfCompromise.Files); 191 | } 192 | 193 | if (IOCDetector.ScheduledTaskIOC()) 194 | { 195 | Console.WriteLine("[!] SeroXen detected in the Task Scheduler."); 196 | list.Add(IndicatorOfCompromise.ScheduledTask); 197 | } 198 | 199 | if (IOCDetector.RegistryIOC()) 200 | { 201 | Console.WriteLine("[!] SeroXen detected in the Windows Registry."); 202 | list.Add(IndicatorOfCompromise.Registry); 203 | } 204 | 205 | if (IOCDetector.EnvironmentIOC()) 206 | { 207 | Console.WriteLine("[!] SeroXen detected in the Environment Variables."); 208 | list.Add(IndicatorOfCompromise.Environment); 209 | } 210 | 211 | if (IOCDetector.ProcessesIOC()) 212 | { 213 | Console.WriteLine("[!] SeroXen detected in running processes."); 214 | list.Add(IndicatorOfCompromise.Process); 215 | } 216 | 217 | return list.ToArray(); 218 | } 219 | } 220 | 221 | internal enum IndicatorOfCompromise 222 | { 223 | Files, 224 | ScheduledTask, 225 | Registry, 226 | Environment, 227 | Process, 228 | Rootkit 229 | } 230 | 231 | internal static class IOCDetector 232 | { 233 | public static bool FilesIOC() 234 | { 235 | var windows = Environment.GetFolderPath(Environment.SpecialFolder.Windows); 236 | 237 | var mstha = Path.Combine(windows, "$sxr-mshta.exe"); 238 | var cmd = Path.Combine(windows, "$sxr-cmd.exe"); 239 | var powershell = Path.Combine(windows, "$sxr-powershell.exe"); 240 | 241 | var any = Directory.GetFiles(windows).Any(filename => filename.ToLower().StartsWith("$sxr") && filename.ToLower().EndsWith(".exe")); 242 | 243 | return File.Exists(mstha) || File.Exists(cmd) || File.Exists(powershell) || any; 244 | } 245 | 246 | public static bool ScheduledTaskIOC() 247 | { 248 | using var sched = new TaskService(); 249 | 250 | if (sched.RootFolder.Tasks.Any(task => task.Name.ToLower().StartsWith("$sxr"))) 251 | return true; 252 | 253 | return false; 254 | } 255 | 256 | public unsafe static bool RootkitIOC() 257 | { 258 | var module = Native.GetModuleHandle(null); 259 | if (module == IntPtr.Zero) 260 | return false; 261 | 262 | var signature = *(ushort*)(module.ToInt64() + 64); 263 | 264 | return signature == 0x7260; 265 | } 266 | 267 | public static bool RegistryIOC() 268 | { 269 | return Registry.LocalMachine.OpenSubKey("SOFTWARE").GetValueNames().Any(name => name.ToLower().StartsWith("$sxr")); 270 | } 271 | 272 | public static bool EnvironmentIOC() 273 | { 274 | foreach (var key in Environment.GetEnvironmentVariables().Keys) { 275 | if (key.ToString().ToLower().StartsWith("$sxr")) 276 | return true; 277 | } 278 | 279 | return false; 280 | } 281 | 282 | public static bool ProcessesIOC() 283 | { 284 | var names = new string[] { "$sxr-cmd", "$sxr-mshta", "$sxr-powershell" }; 285 | 286 | return Process.GetProcesses().Any(proc => names.Contains(proc.ProcessName)); 287 | } 288 | } 289 | 290 | internal static class IOCCleaner 291 | { 292 | public static void CleanFiles() 293 | { 294 | var windows = Environment.GetFolderPath(Environment.SpecialFolder.Windows); 295 | var files = Directory.GetFiles(windows, "$sxr*.exe"); 296 | 297 | Console.WriteLine("[*] Deleting files..."); 298 | 299 | foreach (var file in files) 300 | { 301 | Thread.Sleep(1000); 302 | try 303 | { 304 | File.Delete(file); 305 | } 306 | catch (Exception ex) 307 | { 308 | Console.WriteLine($"[-] Failed to delete file {file}: {ex.Message}!"); 309 | } 310 | } 311 | } 312 | 313 | public static void CleanScheduledTask() 314 | { 315 | using var sched = new TaskService(); 316 | 317 | Console.WriteLine("[*] Removing scheduled tasks..."); 318 | 319 | var tasks = sched.AllTasks.Where(task => task.Name.ToLower().StartsWith("$sxr")); 320 | 321 | foreach (var task in tasks) 322 | task.Folder.DeleteTask(task.Name); 323 | } 324 | 325 | public static void CleanRegistry() 326 | { 327 | using var key = Registry.LocalMachine.OpenSubKey("SOFTWARE", true); 328 | var names = key.GetValueNames().Where(name => name.ToLower().StartsWith("$sxr")); 329 | 330 | Console.WriteLine("[*] Removing registry values..."); 331 | 332 | foreach (var name in names) 333 | key.DeleteValue(name); 334 | } 335 | 336 | public static void CleanEnvironment() 337 | { 338 | Console.WriteLine("[*] Cleaning up environment variables..."); 339 | 340 | foreach (var key in Environment.GetEnvironmentVariables().Keys) 341 | if (key.ToString().ToLower().StartsWith("$sxr")) 342 | { 343 | Environment.SetEnvironmentVariable(key.ToString(), null, EnvironmentVariableTarget.Machine); 344 | Environment.SetEnvironmentVariable(key.ToString(), null, EnvironmentVariableTarget.Process); 345 | } 346 | } 347 | 348 | public static void CleanProcesses() 349 | { 350 | var names = new string[] { "$sxr-cmd", "$sxr-mshta", "$sxr-powershell" }; 351 | var processes = Process.GetProcesses().Where(proc => names.Contains(proc.ProcessName)); 352 | 353 | int value = 0; 354 | 355 | Console.WriteLine("[*] Shutting down processes..."); 356 | 357 | foreach (var process in processes) 358 | Native.NtSetInformationProcess(process.Handle, 0x1D, ref value, sizeof(int)); 359 | 360 | foreach (var process in processes) 361 | process.Kill(); 362 | } 363 | 364 | public static void DetachRootkit() 365 | { 366 | Console.WriteLine("[*] Reloading ntdll.dll and kernel32.dll to circumvent hooks..."); 367 | 368 | Unhook.UnhookDll("ntdll.dll"); 369 | Unhook.UnhookDll("kernel32.dll"); 370 | Unhook.UnhookDll("advapi32.dll"); 371 | Unhook.UnhookDll("sechost.dll"); 372 | Unhook.UnhookDll("taskschd.dll"); 373 | Unhook.UnhookDll("pdh.dll"); 374 | } 375 | } 376 | 377 | internal static class Native 378 | { 379 | public const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; 380 | public const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x20007; 381 | 382 | [DllImport("ntdll.dll", SetLastError = true)] 383 | public static extern int NtSetInformationProcess(IntPtr hProcess, int processInformationClass, ref int processInformation, int processInformationLength); 384 | 385 | [DllImport("kernel32.dll")] 386 | public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, long dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); 387 | 388 | [DllImport("kernel32.dll")] 389 | public static extern IntPtr GetModuleHandle(string lpModuleName); 390 | 391 | [DllImport("kernel32.dll")] 392 | [return: MarshalAs(UnmanagedType.Bool)] 393 | public static extern bool CreateProcess( 394 | string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, 395 | IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, 396 | IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, 397 | out PROCESS_INFORMATION lpProcessInformation); 398 | 399 | [DllImport("kernel32.dll", SetLastError = true)] 400 | [return: MarshalAs(UnmanagedType.Bool)] 401 | public static extern bool UpdateProcThreadAttribute( 402 | IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, 403 | IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize); 404 | 405 | [DllImport("kernel32.dll", SetLastError = true)] 406 | [return: MarshalAs(UnmanagedType.Bool)] 407 | public static extern bool InitializeProcThreadAttributeList( 408 | IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize); 409 | 410 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 411 | public struct STARTUPINFOEX 412 | { 413 | public STARTUPINFO StartupInfo; 414 | public IntPtr lpAttributeList; 415 | } 416 | 417 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 418 | public struct STARTUPINFO 419 | { 420 | public Int32 cb; 421 | public string lpReserved; 422 | public string lpDesktop; 423 | public string lpTitle; 424 | public Int32 dwX; 425 | public Int32 dwY; 426 | public Int32 dwXSize; 427 | public Int32 dwYSize; 428 | public Int32 dwXCountChars; 429 | public Int32 dwYCountChars; 430 | public Int32 dwFillAttribute; 431 | public Int32 dwFlags; 432 | public Int16 wShowWindow; 433 | public Int16 cbReserved2; 434 | public IntPtr lpReserved2; 435 | public IntPtr hStdInput; 436 | public IntPtr hStdOutput; 437 | public IntPtr hStdError; 438 | } 439 | 440 | [StructLayout(LayoutKind.Sequential)] 441 | public struct PROCESS_INFORMATION 442 | { 443 | public IntPtr hProcess; 444 | public IntPtr hThread; 445 | public int dwProcessId; 446 | public int dwThreadId; 447 | } 448 | 449 | [StructLayout(LayoutKind.Sequential)] 450 | public struct SECURITY_ATTRIBUTES 451 | { 452 | public int nLength; 453 | public IntPtr lpSecurityDescriptor; 454 | public int bInheritHandle; 455 | } 456 | } 457 | } 458 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SeroXen Removal Tool")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SeroXen Removal Tool")] 13 | [assembly: AssemblyCopyright("Copyright © 2024")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fdc8f2d7-2e6f-4eea-a28d-42ead251ba4e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/SeroXen Removal Tool.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {FDC8F2D7-2E6F-4EEA-A28D-42EAD251BA4E} 9 | Exe 10 | SeroXen_Removal_Tool 11 | SeroXen_Removal_Tool 12 | v4.7.2 13 | 512 14 | true 15 | true 16 | 17 | 18 | 19 | 20 | AnyCPU 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | true 29 | false 30 | 31 | 32 | AnyCPU 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | false 40 | true 41 | 42 | 43 | true 44 | bin\x64\Debug\ 45 | DEBUG;TRACE 46 | full 47 | x64 48 | 7.3 49 | prompt 50 | true 51 | true 52 | 53 | 54 | bin\x64\Release\ 55 | TRACE 56 | true 57 | pdbonly 58 | x64 59 | 7.3 60 | prompt 61 | true 62 | true 63 | 64 | 65 | 66 | ..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll 67 | 68 | 69 | ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll 70 | True 71 | True 72 | 73 | 74 | ..\packages\TaskScheduler.2.10.1\lib\net452\Microsoft.Win32.TaskScheduler.dll 75 | 76 | 77 | 78 | ..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll 79 | True 80 | True 81 | 82 | 83 | 84 | ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll 85 | True 86 | True 87 | 88 | 89 | 90 | ..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll 91 | 92 | 93 | ..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll 94 | True 95 | True 96 | 97 | 98 | 99 | ..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll 100 | True 101 | True 102 | 103 | 104 | ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll 105 | True 106 | True 107 | 108 | 109 | ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll 110 | True 111 | True 112 | 113 | 114 | 115 | ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll 116 | True 117 | True 118 | 119 | 120 | ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll 121 | True 122 | True 123 | 124 | 125 | ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll 126 | True 127 | True 128 | 129 | 130 | ..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll 131 | True 132 | True 133 | 134 | 135 | ..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll 136 | True 137 | True 138 | 139 | 140 | ..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll 141 | True 142 | True 143 | 144 | 145 | ..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll 146 | True 147 | True 148 | 149 | 150 | 151 | ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll 152 | True 153 | True 154 | 155 | 156 | ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll 157 | True 158 | True 159 | 160 | 161 | ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll 162 | True 163 | True 164 | 165 | 166 | ..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll 167 | True 168 | True 169 | 170 | 171 | ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll 172 | True 173 | True 174 | 175 | 176 | ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll 177 | True 178 | True 179 | 180 | 181 | ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll 182 | True 183 | True 184 | 185 | 186 | ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll 187 | True 188 | True 189 | 190 | 191 | ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll 192 | True 193 | True 194 | 195 | 196 | ..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll 197 | True 198 | True 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll 208 | True 209 | True 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 9.0 224 | 225 | 226 | 227 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/Unhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace SeroXen_Removal_Tool 5 | { 6 | public static class Unhook 7 | { 8 | /// 9 | /// Unhooks a DLL by replacing the .text section with the original DLL section. 10 | /// The bitness of the current process must match the bitness of the operating system. 11 | /// 12 | /// The name of the DLL to unhook. 13 | public static unsafe void UnhookDll(string name) 14 | { 15 | try 16 | { 17 | // Get original DLL handle. This DLL is possibly hooked by AV/EDR solutions. 18 | IntPtr dll = GetModuleHandle(name); 19 | if (dll != IntPtr.Zero) 20 | { 21 | if (GetModuleInformation(GetCurrentProcess(), dll, out MODULEINFO moduleInfo, (uint)sizeof(MODULEINFO))) 22 | { 23 | // Retrieve a clean copy of the DLL file. 24 | IntPtr dllFile = CreateFileA(@"C:\Windows\System32\" + name, 0x80000000, 1, IntPtr.Zero, 3, 0, IntPtr.Zero); 25 | if (dllFile != (IntPtr)(-1)) 26 | { 27 | // Map the clean DLL into memory 28 | IntPtr dllMapping = CreateFileMapping(dllFile, IntPtr.Zero, 0x1000002, 0, 0, null); 29 | if (dllMapping != IntPtr.Zero) 30 | { 31 | IntPtr dllMappedFile = MapViewOfFile(dllMapping, 4, 0, 0, IntPtr.Zero); 32 | if (dllMappedFile != IntPtr.Zero) 33 | { 34 | int ntHeaders = Marshal.ReadInt32((IntPtr)((long)moduleInfo.BaseOfDll + 0x3c)); 35 | short numberOfSections = Marshal.ReadInt16((IntPtr)((long)dll + ntHeaders + 0x6)); 36 | short sizeOfOptionalHeader = Marshal.ReadInt16(dll, ntHeaders + 0x14); 37 | 38 | for (short i = 0; i < numberOfSections; i++) 39 | { 40 | IntPtr sectionHeader = (IntPtr)((long)dll + ntHeaders + 0x18 + sizeOfOptionalHeader + i * 0x28); 41 | 42 | // Find the .text section of the hooked DLL and overwrite it with the original DLL section 43 | if (Marshal.ReadByte(sectionHeader) == '.' && 44 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 1)) == 't' && 45 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 2)) == 'e' && 46 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 3)) == 'x' && 47 | Marshal.ReadByte((IntPtr)((long)sectionHeader + 4)) == 't') 48 | { 49 | int virtualAddress = Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0xc)); 50 | uint virtualSize = (uint)Marshal.ReadInt32((IntPtr)((long)sectionHeader + 0x8)); 51 | 52 | VirtualProtect((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, 0x40, out uint oldProtect); 53 | memcpy((IntPtr)((long)dll + virtualAddress), (IntPtr)((long)dllMappedFile + virtualAddress), (IntPtr)virtualSize); 54 | VirtualProtect((IntPtr)((long)dll + virtualAddress), (IntPtr)virtualSize, oldProtect, out _); 55 | break; 56 | } 57 | } 58 | } 59 | 60 | CloseHandle(dllMapping); 61 | } 62 | 63 | CloseHandle(dllFile); 64 | } 65 | } 66 | 67 | FreeLibrary(dll); 68 | } 69 | } 70 | catch 71 | { 72 | // Do not abort initialization, if unhooking failed. 73 | } 74 | } 75 | 76 | [StructLayout(LayoutKind.Sequential)] 77 | private struct MODULEINFO 78 | { 79 | public IntPtr BaseOfDll; 80 | public uint SizeOfImage; 81 | public IntPtr EntryPoint; 82 | } 83 | 84 | [DllImport("kernel32.dll")] 85 | private static extern IntPtr GetCurrentProcess(); 86 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 87 | private static extern IntPtr GetModuleHandle(string moduleName); 88 | [DllImport("kernel32.dll", SetLastError = true)] 89 | private static extern bool CloseHandle(IntPtr handle); 90 | [DllImport("kernel32.dll", SetLastError = true)] 91 | [return: MarshalAs(UnmanagedType.Bool)] 92 | private static extern bool FreeLibrary(IntPtr module); 93 | [DllImport("kernel32.dll")] 94 | private static extern int VirtualProtect(IntPtr address, IntPtr size, uint newProtect, out uint oldProtect); 95 | [DllImport("kernel32.dll", SetLastError = true)] 96 | private static extern IntPtr CreateFileA(string fileName, uint desiredAccess, uint shareMode, IntPtr securityAttributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile); 97 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 98 | private static extern IntPtr CreateFileMapping(IntPtr file, IntPtr fileMappingAttributes, uint protect, uint maximumSizeHigh, uint maximumSizeLow, [MarshalAs(UnmanagedType.LPStr)] string name); 99 | [DllImport("kernel32.dll")] 100 | private static extern IntPtr MapViewOfFile(IntPtr fileMappingObject, uint desiredAccess, uint fileOffsetHigh, uint fileOffsetLow, IntPtr numberOfBytesToMap); 101 | [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] 102 | private static extern IntPtr memcpy(IntPtr dest, IntPtr src, IntPtr count); 103 | [DllImport("psapi.dll", SetLastError = true)] 104 | private static extern bool GetModuleInformation(IntPtr process, IntPtr module, out MODULEINFO moduleInfo, uint size); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /SeroXen Removal Tool/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | --------------------------------------------------------------------------------