public void LoadGame() { lzf_Compression = new LZF(); gameWorldData = new GameData(); //파일 생성. BinaryFormatter bf = new BinaryFormatter(); FileStream fileStream = File.Open(fileDirectory, FileMode.Open); // DeSerialzing ( decode..) gameWorldData = (GameData)bf.Deserialize(fileStream); gameWorldData.MemoryAllocLoadArray(); // loadArray의 경우 serializing 이 되지 않았으므로, 다시 재할당한다. fileStream.Close(); // 압축해제 작업. lzf_Compression.Decompress(gameWorldData.GetSaveByteArray(), ConstantGroup.saveBtyeArraySize, gameWorldData.GetLoadByteArray(), ConstantGroup.loadByteArraySize); // Load가 완료되었으므로, true로 값을 설정. IsLoadedData = true; UnityThreadHelper.Dispatcher.Dispatch(() => { Application.LoadLevel("LoadingNextScene"); }); }
public void Send(int id, byte[] bytes) { try { var compress = bytes.Length > 75; //Because there is lots of overhead, we don't compress below 75 B byte[] compressedData = null; if (compress) { compressedData = LZF.Compress(bytes, 0); } lock (WriterLock) { BinaryWriter.Write( (byte)(compress ? FromAdministrationPackage.SendCommandCompressed : FromAdministrationPackage.SendCommand)); BinaryWriter.Write((compress ? compressedData.Length : bytes.Length) + 5); BinaryWriter.Write(BitConverter.GetBytes(id)); BinaryWriter.Write((byte)SendingType.Command); BinaryWriter.Write(compress ? compressedData : bytes); BinaryWriter.Flush(); } } catch (Exception) { // ignored } }
public void SendDynamicCommand(byte[] bytes) { try { byte[] compressedData = null; var compressed = false; if (bytes.Length > 75) //Because there is a lot of overhead, we don't compress below 75 B { compressedData = LZF.Compress(bytes, 0); if (bytes.Length > compressedData.Length) { //If the compression isn't larger than the source, we will send the compressed data compressed = true; } } lock (WriterLock) { Connection.BinaryWriter.Write( (byte) (compressed ? FromAdministrationPackage.SendDynamicCommandCompressed : FromAdministrationPackage.SendDynamicCommand)); Connection.BinaryWriter.Write(compressed ? compressedData.Length : bytes.Length); Connection.BinaryWriter.Write(compressed ? compressedData : bytes); Connection.BinaryWriter.Flush(); } } catch (Exception) { // ignored } }
public void SaveGame() { lzf_Compression = new LZF(); UnityThreadHelper.Dispatcher.Dispatch(() => { // 월드 오브젝트에서 컴포넌트 추출. getWorld = GameObject.Find("World"); m_world = getWorld.GetComponent("World") as World; }); // Init GameData class gameWorldData = new GameData(); // 게임월드 배열을 저장 게임데이터로 옴긴다. gameWorldData.Flatten3dArray(m_world); // 압축시작. lzf_Compression.Compress(gameWorldData.GetWorldData(), gameWorldData.GetWorldData().Length, gameWorldData.GetSaveByteArray(), ConstantGroup.saveBtyeArraySize); // 파일 생성. BinaryFormatter bf = new BinaryFormatter(); FileStream fileStream = File.Open(fileDirectory, FileMode.OpenOrCreate); // 시리얼라이징. bf.Serialize(fileStream, gameWorldData); fileStream.Close(); UnityThreadHelper.Dispatcher.Dispatch(() => { SysLogManager.SetLogMessage("<SYSTEM> : 현재 내용이 저장되었습니다. "); }); }
public static string DescribeSentData(byte[] data, int index) { data = LZF.Decompress(data, index); var functionNameLength = BitConverter.ToInt32(data, 16); var functionName = Encoding.UTF8.GetString(data, 20, functionNameLength); return(functionName); }
public unsafe byte[] Compress(IntPtr scan0, int stride, Size imageSize, PixelFormat pixelFormat) { var data = new byte[stride * imageSize.Height]; fixed(byte *dataPtr = data) memcpy(dataPtr, (byte *)scan0, (UIntPtr)data.Length); return(LZF.Compress(data, 0)); }
public unsafe byte[] Decompress(IntPtr dataPtr, uint length, PixelFormat pixelFormat) { var buffer = new byte[length]; fixed(byte *bufferPtr = buffer) memcpy(bufferPtr, (byte *)dataPtr, new UIntPtr(length)); return(LZF.Decompress(buffer, 0)); }
public void PushExceptions(byte[] exceptions) { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.SubmitExceptions); var data = LZF.Compress(exceptions, 0); BinaryWriter.Write(data.Length); BinaryWriter.Write(data); } }
public unsafe void Compress(IntPtr scan0, int stride, Size imageSize, PixelFormat pixelFormat, Stream outStream) { var data = new byte[stride * imageSize.Height]; fixed(byte *dataPtr = data) memcpy(dataPtr, (byte *)scan0, (UIntPtr)data.Length); int compressedLength; var compressed = LZF.Compress(data, 0, out compressedLength); outStream.Write(compressed, 0, compressedLength); }
public unsafe void Decompress(IntPtr dataPtr, uint length, IntPtr outputPtr, int outputLength, PixelFormat pixelFormat) { var buffer = new byte[length]; fixed(byte *bufferPtr = buffer) memcpy(bufferPtr, (byte *)dataPtr, new UIntPtr(length)); var decompressedBuffer = LZF.Decompress(buffer, 0); fixed(byte *decompressedBufferPtr = decompressedBuffer) memcpy((byte *)outputPtr, decompressedBufferPtr, (UIntPtr)decompressedBuffer.Length); }
private static byte[] ReadCompressedString(BinaryReader reader) { int compressedLength = reader.ReadVariableLengthInt32(); int uncompressedLength = reader.ReadVariableLengthInt32(); byte[] compressed = reader.ReadBytes(compressedLength); var lzf = new LZF(); byte[] uncompressed = new byte[uncompressedLength]; lzf.Decompress(compressed, compressedLength, uncompressed, uncompressedLength); return(uncompressed); }
/// <summary> /// Receive data from the server and process it /// </summary> /// <param name="data">The data received by the server</param> /// <param name="position">The start position</param> public void Receive(byte[] data, int position) { data = LZF.Decompress(data, position); var guid = new Guid(data.Take(16).ToArray()); MethodCaller methodCaller; if (guid == FunctionNotFoundExceptionGuid) { var sessionGuid = new Guid(data.Skip(16).Take(16).ToArray()); if (!_methodDictionary.TryGetValue(sessionGuid, out methodCaller)) { throw new InvalidOperationException("Session was not registered"); } _exceptionResponses.Add(sessionGuid, new InvalidOperationException( $"Method or function with name {Encoding.UTF8.GetString(data, 32, data.Length - 32)} not found")); methodCaller.AutoResetEvent.Set(); return; } if (guid == ExceptionGuid) { var errorReport = new Serializer(typeof(DtpException)).Deserialize <DtpException>(data, 16); if (!_methodDictionary.TryGetValue(errorReport.SessionGuid, out methodCaller)) { throw new InvalidOperationException("Session was not registered"); } _exceptionResponses.Add(errorReport.SessionGuid, new ServerException(errorReport)); methodCaller.AutoResetEvent.Set(); return; } if (!_methodDictionary.TryGetValue(guid, out methodCaller)) { throw new InvalidOperationException("Session was not registered"); } var valueLength = BitConverter.ToInt32(data, 16); if (valueLength > 0) { var buffer = new byte[valueLength]; Array.Copy(data, 20, buffer, 0, valueLength); _methodResponses.Add(guid, buffer); } methodCaller.AutoResetEvent.Set(); }
public static byte[] Decompress(byte[] data) { if (data.Length == 0) { return(data); } LZF decompressor = new LZF(); int decompressedLength = decompressor.Decompress(data, data.Length, OutputBuffer, OutputBuffer.Length); byte[] result = new byte[decompressedLength]; System.Array.Copy(OutputBuffer, result, decompressedLength); return(result); }
public void Response(byte[] package, ResponseType responseType, PackageCompression packageCompression = PackageCompression.Auto) { if (_isFailed) { return; } byte[] compressedData = null; var compressed = false; if ((package.Length > 75 && packageCompression == PackageCompression.Auto) || packageCompression == PackageCompression.Compress) //Because there is a lot of overhead, we don't compress below 75 B { compressedData = LZF.Compress(package, 0); if (package.Length > compressedData.Length) { //If the compression isn't larger than the source, we will send the compressed data compressed = true; } } lock (_sendLock) { try { ServerConnection.BinaryWriter.Write( (byte) (compressed ? FromClientPackage.ResponseToAdministrationCompressed : FromClientPackage.ResponseToAdministration)); ServerConnection.BinaryWriter.Write((compressed ? compressedData.Length : package.Length) + 3); //1 for the responseType and 2 for the ushort ServerConnection.BinaryWriter.Write(BitConverter.GetBytes(AdministrationId)); ServerConnection.BinaryWriter.Write((byte)responseType); ServerConnection.BinaryWriter.Write(compressed ? compressedData : package); ServerConnection.BinaryWriter.Flush(); } catch (Exception) { OnFailed(); } } }
public void LargeDataCompressionTest() { var sampleData = new byte[104857600]; //100 MiB var random = new Random(); random.NextBytes(sampleData); var sw = Stopwatch.StartNew(); var compressedData = LZF.Compress(sampleData, 0); Trace.WriteLine($"Compressed 100 MiB randomly generated bytes in {sw.ElapsedMilliseconds} ms"); Assert.IsFalse(sampleData.SequenceEqual(compressedData)); sw.Restart(); var uncompressed = LZF.Decompress(compressedData, 0); Trace.WriteLine($"Decompressed 100 MiB randomly generated bytes in {sw.ElapsedMilliseconds} ms"); Assert.IsTrue(sampleData.SequenceEqual(uncompressed)); }
public void SendCommand(int id, byte[] bytes, PackageCompression packageCompression = PackageCompression.Auto) { try { byte[] compressedData = null; var compressed = false; if ((bytes.Length > 75 && packageCompression == PackageCompression.Auto) || packageCompression == PackageCompression.Compress) //Because there is a lot of overhead, we don't compress below 75 B { compressedData = LZF.Compress(bytes, 0); if (bytes.Length > compressedData.Length) { //If the compression isn't larger than the source, we will send the compressed data compressed = true; } } lock (WriterLock) { Connection.BinaryWriter.Write( (byte) (compressed ? FromAdministrationPackage.SendCommandCompressed : FromAdministrationPackage.SendCommand)); Connection.BinaryWriter.Write((compressed ? compressedData.Length : bytes.Length) + 5); Connection.BinaryWriter.Write(BitConverter.GetBytes(id)); Connection.BinaryWriter.Write((byte)SendingType.Command); Connection.BinaryWriter.Write(compressed ? compressedData : bytes); Connection.BinaryWriter.Flush(); } if (compressed) { Debug.Print( $"Saved {bytes.Length - compressedData.Length} ({compressedData.Length}/{bytes.Length}"); } } catch (Exception) { // ignored } }
public string DescribeReceivedData(byte[] data, int position) { data = LZF.Decompress(data, position); var guid = new Guid(data.Take(16).ToArray()); MethodCaller methodCaller; if (guid == FunctionNotFoundExceptionGuid) { var sessionGuid = new Guid(data.Skip(16).Take(16).ToArray()); if (!_methodDictionary.TryGetValue(sessionGuid, out methodCaller)) { return("Function not found (Session not registered)"); } return($"Function not found ({methodCaller.MethodName})"); } if (guid == ExceptionGuid) { var errorReport = new Serializer(typeof(DtpException)).Deserialize <DtpException>(data, 16); if (!_methodDictionary.TryGetValue(errorReport.SessionGuid, out methodCaller)) { return("Exception occurred (Session not registered)"); } return($"Exception occurred ({methodCaller.MethodName})"); } if (!_methodDictionary.TryGetValue(guid, out methodCaller)) { return("Session not registered"); } return(methodCaller.MethodName); }
public void SendImageCompressed() { uint maxsize = 1024 * 64; LZF lzf = new LZF(); uint compressSize = 0; uint originalSize = 0; var bss = linker.LinkerSections[(int)SectionKind.BSS]; var message = new DebugMessage(DebugCode.ClearMemory, new int[] { (int)bss.VirtualAddress, (int)bss.Size }); SendMessageAndWait(message); var compressed = new byte[maxsize * 2]; foreach (var section in linker.LinkerSections) { if (section.SectionKind == SectionKind.BSS) { continue; } var stream = new MemoryStream((int)section.Size); // similar code in the Section.WriteTo method foreach (var symbol in section.Symbols) { stream.Seek(symbol.SectionOffset, SeekOrigin.Begin); if (symbol.IsDataAvailable) { symbol.Stream.Position = 0; symbol.Stream.WriteTo(stream); } } stream.WriteZeroBytes((int)(section.AlignedSize - stream.Position)); stream.Position = 0; var array = stream.ToArray(); uint at = 0; while (at < array.Length) { uint size = (uint)array.Length - at; if (size > maxsize) { size = maxsize; } // compress var raw = new byte[size]; Array.Copy(array, at, raw, 0, size); uint crc = CRC.InitialCRC; for (int i = 0; i < size; i++) { crc = CRC.Update(crc, raw[i]); } var len = lzf.Compress(raw, raw.Length, compressed, compressed.Length); compressSize = compressSize + (uint)len; originalSize = originalSize + size; // data var data = new byte[len + 16]; uint address = (uint)(section.VirtualAddress + at); data[0] = (byte)(address & 0xFF); data[1] = (byte)((address >> 8) & 0xFF); data[2] = (byte)((address >> 16) & 0xFF); data[3] = (byte)((address >> 24) & 0xFF); data[4] = (byte)(len & 0xFF); data[5] = (byte)((len >> 8) & 0xFF); data[6] = (byte)((len >> 16) & 0xFF); data[7] = (byte)((len >> 24) & 0xFF); data[8] = (byte)(size & 0xFF); data[9] = (byte)((size >> 8) & 0xFF); data[10] = (byte)((size >> 16) & 0xFF); data[11] = (byte)((size >> 24) & 0xFF); data[12] = (byte)(crc & 0xFF); data[13] = (byte)((crc >> 8) & 0xFF); data[14] = (byte)((crc >> 16) & 0xFF); data[15] = (byte)((crc >> 24) & 0xFF); Array.Copy(compressed, 0, data, 16, len); message = new DebugMessage(DebugCode.CompressedWriteMemory, data); Console.WriteLine(section.SectionKind.ToString() + " @ 0x" + address.ToString("X") + " [size: " + size.ToString() + " compressed: " + len.ToString() + "]"); SendMessageAndWait(message); at = at + size; } } Console.WriteLine("Original: " + originalSize.ToString()); Console.WriteLine("Compressed: " + compressSize.ToString()); Console.WriteLine("Compacted: " + (compressSize * 100 / originalSize).ToString()); kernelInit = false; imageSent = true; }
public static Stream Compress(Stream inputStream, CompressionMethod level = CompressionMethod.Default) { switch (level) { // bypass compression case CompressionMethod.None: return(inputStream); // average compression using DeflateStream case CompressionMethod.DeflateStream: { var stream = new SmallBlockMemoryStream(); using (var output = new DeflateStream(stream, CompressionMode.Compress, true)) { int read; var buffer = new byte[BufferSize]; while ((read = inputStream.Read(buffer, 0, BufferSize)) > 0) { output.Write(buffer, 0, read); } } stream.Seek(0, SeekOrigin.Begin); return(stream); } // fast compression using LZF case CompressionMethod.LZF: { var buffer = new byte[BufferSize]; var output = new byte[BufferSize * 2]; // safe value for uncompressible data var outStream = new SmallBlockMemoryStream(); var lzf = new LZF(); while (true) { var readCount = (short)inputStream.Read(buffer, 0, buffer.Length); if (readCount == 0) { break; } var writeCount = (short)lzf.Compress(buffer, readCount, output, output.Length); if (writeCount == 0) { throw new InvalidOperationException("Cannot compress input stream."); } // write source size var temp = BitConverter.GetBytes(readCount); outStream.Write(temp, 0, ShortSize); // write destination size temp = BitConverter.GetBytes(writeCount); outStream.Write(temp, 0, ShortSize); // write data chunk outStream.Write(output, 0, writeCount); } // rewind the output stream outStream.Seek(0, SeekOrigin.Begin); return(outStream); } } // unknown compression method throw new InvalidOperationException(); }
public static Stream Decompress(Stream inputStream, CompressionMethod level = CompressionMethod.Default) { switch (level) { // bypass decompression case CompressionMethod.None: return(inputStream); // decompress using DeflateStream case CompressionMethod.DeflateStream: { var stream = new SmallBlockMemoryStream(); using (var output = new DeflateStream(inputStream, CompressionMode.Decompress, true)) { int read; var buffer = new byte[BufferSize]; while ((read = output.Read(buffer, 0, BufferSize)) > 0) { stream.Write(buffer, 0, read); } } stream.Seek(0, SeekOrigin.Begin); return(stream); } // decompress using LZF case CompressionMethod.LZF: { var buffer = new byte[BufferSize * 2]; var output = new byte[BufferSize]; var temp = new byte[ShortSize * 2]; var outStream = new SmallBlockMemoryStream(); var lzf = new LZF(); while (true) { // read chunk sizes if (inputStream.Read(temp, 0, ShortSize * 2) == 0) { break; } var sourceSize = BitConverter.ToInt16(temp, 0); var destSize = BitConverter.ToInt16(temp, ShortSize); var readCount = inputStream.Read(buffer, 0, destSize); if (readCount != destSize) { throw new InvalidOperationException("Cannot read input stream."); } var writeCount = lzf.Decompress(buffer, readCount, output, output.Length); if (writeCount != sourceSize) { throw new InvalidOperationException("Cannot decompress input stream."); } outStream.Write(output, 0, writeCount); } // rewind the output stream outStream.Seek(0, SeekOrigin.Begin); return(outStream); } } // unknown compression method throw new InvalidOperationException(); }
private void EndRead(IAsyncResult asyncResult) { try { var parameter = _readByteDelegate.EndInvoke(asyncResult); var size = Sender.BinaryReader.ReadInt32(); var bytes = Sender.BinaryReader.ReadBytes(size); switch ((FromClientPackage)parameter) { case FromClientPackage.ResponseToAdministration: case FromClientPackage.ResponseToAdministrationCompressed: var data = parameter == (byte)FromClientPackage.ResponseToAdministrationCompressed ? LZF.Decompress(bytes, 1) : bytes.Skip(1).ToArray(); if (CurrentController != null) { CurrentController.PackageReceived(bytes[0], data); } break; case FromClientPackage.ResponseLoginOpen: var clientId = BitConverter.ToInt32(bytes, 0); var client = Clients.FirstOrDefault(x => x.Id == clientId); if (client == null) { break; } CurrentController = new ClientController(client, _tcpClient, Sender); if (AttackOpened != null) { AttackOpened.Invoke(this, EventArgs.Empty); } break; case FromClientPackage.NewClientConnected: lock (_clientListLock) { ConnectClient(new Serializer(new[] { typeof(ClientInformation), typeof(OnlineClientInformation) }).Deserialize <OnlineClientInformation>(bytes)); } break; case FromClientPackage.ClientConnected: lock (_clientListLock) { ConnectClient(new Serializer(new[] { typeof(ClientInformation), typeof(OnlineClientInformation) }).Deserialize <OnlineClientInformation>(bytes)); } break; case FromClientPackage.ClientDisconnected: lock (_clientListLock) { var disconnectedClientId = BitConverter.ToInt32(bytes, 0); var disconnectedClient = Clients .FirstOrDefault(x => x.Id == disconnectedClientId); if (disconnectedClient == null) { break; } if (CurrentController != null && CurrentController.Client == disconnectedClient) { CurrentController.Dispose(); CurrentController = null; } Clients.Remove(disconnectedClient); if (ClientListChanged != null) { ClientListChanged.Invoke(this, EventArgs.Empty); } if (ClientDisconnected != null) { ClientDisconnected.Invoke(this, disconnectedClient); } } break; case FromClientPackage.DataTransferProtocolResponse: DataTransferProtocolFactory.Receive(bytes); break; default: break; } _readByteDelegate.BeginInvoke(EndRead, null); } catch (Exception) { Dispose(); if (Disconnected != null) { Disconnected.Invoke(this, EventArgs.Empty); } } }
private void EndRead(IAsyncResult asyncResult) { try { var parameter = _readByteDelegate.EndInvoke(asyncResult); var size = BinaryReader.ReadInt32(); switch ((FromAdministrationPackage)parameter) { case FromAdministrationPackage.SendCommand: case FromAdministrationPackage.SendCommandCompressed: var bytes = BinaryReader.ReadBytes(size); //don't execute in a thread because it wants to be synchronized var administrationId = BitConverter.ToUInt16(bytes, 0); var isCompressed = parameter == (byte)FromAdministrationPackage.SendCommandCompressed; var packageData = isCompressed ? LZF.Decompress(bytes, 3) : bytes; AdministrationConnections.FirstOrDefault(x => x.Id == administrationId)? .PackageReceived(bytes[2], packageData, isCompressed ? 0 : 3); break; case FromAdministrationPackage.SendPlugin: administrationId = BinaryReader.ReadUInt16(); var pluginLength = BinaryReader.ReadInt32(); var pluginGuid = new Guid(BinaryReader.ReadBytes(16)); var hash = BinaryReader.ReadBytes(16); var versionData = BinaryReader.ReadBytes(BinaryReader.ReadInt32()); var version = Encoding.ASCII.GetString(versionData); try { var pluginReceiver = new PluginReceiver(administrationId, pluginGuid, hash, version); var buffer = new byte[8192]; int read; while (pluginLength > 0 && (read = BinaryReader.Read(buffer, 0, Math.Min(buffer.Length, pluginLength))) > 0) { pluginReceiver.FileStream.Write(buffer, 0, read); pluginLength -= read; } if (pluginReceiver.ImportPlugin() && LoadPlugin(pluginReceiver.Guid, PluginVersion.Parse(pluginReceiver.Version))) { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoaded); BinaryWriter.Write(16 + versionData.Length); BinaryWriter.Write(pluginGuid.ToByteArray()); BinaryWriter.Write(versionData); } } else { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoadFailed); BinaryWriter.Write(2 + 16 + versionData.Length); BinaryWriter.Write(BitConverter.GetBytes(pluginReceiver.AdministrationId)); //administration id BinaryWriter.Write(pluginGuid.ToByteArray()); BinaryWriter.Write(versionData); } } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, $"void ProcessResponse || Parameter: {(FromAdministrationPackage) parameter}, Size: {size} B"); } break; case FromAdministrationPackage.SendLibraries: administrationId = BinaryReader.ReadUInt16(); try { var portableLibraries = (List <PortableLibraryInfo>) new Serializer(typeof(List <PortableLibraryInfo>)).Deserialize( BinaryReader.BaseStream); var loadedLibraries = PortableLibrary.None; foreach (var portableLibraryInfo in portableLibraries) { try { LibraryLoader.Current.LoadLibrary(portableLibraryInfo.Library, _sslStream, portableLibraryInfo.Length); } catch (Exception) { continue; } loadedLibraries |= portableLibraryInfo.Library; } lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseLibraryLoadingResult); BinaryWriter.Write(2 + 4); BinaryWriter.Write(BitConverter.GetBytes(administrationId)); BinaryWriter.Write(BitConverter.GetBytes((int)loadedLibraries)); } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, $"void ProcessResponse || Parameter: {(FromAdministrationPackage) parameter}, Size: {size} B"); } break; default: bytes = BinaryReader.ReadBytes(size); ThreadPool.QueueUserWorkItem(state => { try { ProcessResponse(parameter, size, bytes); } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, $"void ProcessResponse || Parameter: {(FromAdministrationPackage) parameter}, Size: {size} B"); } }); break; } _readByteDelegate.BeginInvoke(EndRead, null); } catch (Exception) { Dispose(); } }
private void ProcessResponse(byte parameter, int size, byte[] bytes) { switch ((FromAdministrationPackage)parameter) { case FromAdministrationPackage.InitializeNewSession: var id = BitConverter.ToUInt16(bytes, 0); var connection = new AdministrationConnection(id, this, _clientInfo); connection.SendFailed += (sender, args) => Dispose(); AdministrationConnections.Add(connection); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseLoginOpen); BinaryWriter.Write(2); BinaryWriter.Write(BitConverter.GetBytes(id)); } break; case FromAdministrationPackage.SendStaticCommand: var potentialCommand = new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(bytes, 0); StaticCommandSelector.Current.ExecuteCommand(potentialCommand); break; case FromAdministrationPackage.SendStaticCommandCompressed: potentialCommand = new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(LZF.Decompress(bytes, 0), 0); StaticCommandSelector.Current.ExecuteCommand(potentialCommand); break; case FromAdministrationPackage.LoadPlugin: var guid = new Guid(bytes.Skip(2).Take(16).ToArray()); var version = new Serializer(typeof(PluginVersion)).Deserialize <PluginVersion>(bytes, 18); var versionData = Encoding.ASCII.GetBytes(version.ToString()); if (LoadPlugin(guid, version)) { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoaded); BinaryWriter.Write(16 + versionData.Length); BinaryWriter.Write(guid.ToByteArray()); BinaryWriter.Write(versionData); } } else { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoadFailed); BinaryWriter.Write(2 + 16 + versionData.Length); BinaryWriter.Write(bytes, 0, 2); //administration id BinaryWriter.Write(guid.ToByteArray()); BinaryWriter.Write(versionData); } } break; case FromAdministrationPackage.CloseSession: var closingSessionId = BitConverter.ToUInt16(bytes, 0); var session = AdministrationConnections.FirstOrDefault(x => x.Id == closingSessionId); if (session != null) { AdministrationConnections.Remove(session); session.Dispose(); } break; case FromAdministrationPackage.GetActiveWindow: try { string windowTitle = ""; var lastInPut = new LASTINPUTINFO(); lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut); //15 min if (NativeMethods.GetLastInputInfo(ref lastInPut) && (uint)Environment.TickCount - lastInPut.dwTime > 900000) { windowTitle += "[Idle] "; } windowTitle += ActiveWindowHook.GetActiveWindowTitle() ?? ""; var windowTitleData = Encoding.UTF8.GetBytes(windowTitle); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseActiveWindow); BinaryWriter.Write(windowTitleData.Length + 2); BinaryWriter.Write(bytes); BinaryWriter.Write(windowTitleData); } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, "case FromAdministrationPackage.GetActiveWindow"); } break; case FromAdministrationPackage.GetScreen: try { using (var compressor = new JpgCompression(75)) { byte[] screenshotData; using (var memoryStream = new MemoryStream()) using (var screenshot = ScreenHelper.TakeScreenshot()) { compressor.Compress(screenshot, memoryStream); screenshotData = memoryStream.ToArray(); } lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseScreenshot); BinaryWriter.Write(screenshotData.Length + 2); BinaryWriter.Write(bytes); BinaryWriter.Write(screenshotData); } } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, "case FromAdministrationPackage.GetScreen"); } break; case FromAdministrationPackage.AcceptPush: FileTransferAccepted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes))); break; case FromAdministrationPackage.TransferCompleted: FileTransferCompleted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes))); break; case FromAdministrationPackage.IsAlive: lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.StillAlive); BinaryWriter.Write(0); } break; case FromAdministrationPackage.SendStaticCommandPlugin: var pluginDirectory = new DirectoryInfo(Consts.StaticCommandPluginsDirectory); if (!pluginDirectory.Exists) { pluginDirectory.Create(); } var filename = FileExtensions.GetUniqueFileName(pluginDirectory.FullName); using (var fileStream = new FileStream(filename, FileMode.CreateNew, FileAccess.Write)) fileStream.Write(bytes, 4, bytes.Length - 4); StaticCommandPluginReceived?.Invoke(this, new StaticCommandPluginReceivedEventArgs(filename, BitConverter.ToInt32(bytes, 0))); break; case FromAdministrationPackage.RequestLibraryInformation: var libraries = (PortableLibrary)BitConverter.ToInt32(bytes, 2); var libraryHashes = (size - 6) / 16; var hashes = new List <byte[]>(libraryHashes); for (int i = 0; i < libraryHashes; i++) { var hash = new byte[16]; Buffer.BlockCopy(bytes, 6 + i * 16, hash, 0, 16); hashes.Add(hash); } var result = LibraryLoader.Current.CheckLibraries(libraries, hashes); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseLibraryInformation); BinaryWriter.Write(6); BinaryWriter.Write(bytes, 0, 2); //administration id BinaryWriter.Write(BitConverter.GetBytes((int)result)); } break; case FromAdministrationPackage.StopActiveCommand: StaticCommandSelector.Current.StopActiveCommand(BitConverter.ToInt32(bytes, 0)); break; } }
private void EndRead(IAsyncResult asyncResult) { try { byte parameter; try { parameter = _readByteDelegate.EndInvoke(asyncResult); //no data available } catch (IOException) { Dispose(); return; } var size = _binaryReader.ReadInt32(); var bytes = _binaryReader.ReadBytes(size); LastAnswer = DateTime.UtcNow; ushort administrationId; switch ((FromClientPackage)parameter) { case FromClientPackage.ResponseToAdministration: case FromClientPackage.ResponseToAdministrationCompressed: administrationId = BitConverter.ToUInt16(bytes, 0); Logger.Debug("Client CI-{0} sends command response to administration AI-{1}", Id, administrationId); SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(administrationId, parameter, new WriterCall(bytes, 2, bytes.Length - 2))); break; case FromClientPackage.ResponseLoginOpen: administrationId = BitConverter.ToUInt16(bytes, 0); Logger.Debug("Client CI-{0} opened session with AI-{1}", Id, administrationId); SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(administrationId, (byte)FromClientPackage.ResponseLoginOpen, new WriterCall(BitConverter.GetBytes(Id)))); break; case FromClientPackage.SubmitExceptions: //log handled in server ExceptionsReveived?.Invoke(this, new ExceptionsReveivedEventArgs( ExceptionInfosSerializer.Value.Deserialize <List <ExceptionInfo> >(LZF.Decompress(bytes, 0)))); break; case FromClientPackage.ServerPackage: //log handled in server ProcessServerPackage(ServerPackageSerializer.Value.Deserialize <ServerPackage>(bytes)); break; case FromClientPackage.ResponseStaticCommandResult: var dynamicCommandId = BitConverter.ToInt32(bytes, 0); var message = ""; ActivityType activityType; if (ComputerInformation.ClientVersion >= 19) { activityType = (ActivityType)bytes[4]; } else { activityType = bytes[4] == 0 ? ActivityType.Succeeded : ActivityType.Failed; } if (ComputerInformation.ClientVersion >= 13) { message = Encoding.UTF8.GetString(bytes, 5, bytes.Length - 5); } ReceivedStaticCommandResult?.Invoke(this, new DynamicCommandEvent { ClientId = Id, DynamicCommand = dynamicCommandId, Timestamp = DateTime.UtcNow, Message = message, Status = activityType }); break; case FromClientPackage.PluginLoaded: var pluginInfo = new PluginInfo { Guid = new Guid(bytes.Take(16).ToArray()), Version = Encoding.ASCII.GetString(bytes, 16, bytes.Length - 16), IsLoaded = true }; Logger.Debug("Client CI-{0} loaded plugin {1:D} successfully", Id, pluginInfo.Guid); ComputerInformation.Plugins.Add(pluginInfo); PluginLoaded?.Invoke(this, new PluginLoadedEventArgs(pluginInfo)); break; case FromClientPackage.PluginLoadFailed: Logger.Debug("Client CI-{0} was unable to load plugin", Id); SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(BitConverter.ToUInt16(bytes, 0), (byte)FromClientPackage.PluginLoadFailed, new WriterCall(2 + bytes.Length, writer => { writer.Write(Id); writer.Write(bytes, 2, bytes.Length - 2); }))); break; case FromClientPackage.ResponseActiveWindow: administrationId = BitConverter.ToUInt16(bytes, 0); //+ 4 because of client id int, -2 because of administration id ushort SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(administrationId, (byte)FromClientPackage.ResponseActiveWindow, new WriterCall(bytes.Length + 2, writer => { writer.Write(Id); writer.Write(bytes, 2, bytes.Length - 2); }))); break; case FromClientPackage.ResponseScreenshot: administrationId = BitConverter.ToUInt16(bytes, 0); //+ 4 because of client id int, -2 because of administration id ushort SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(administrationId, (byte)FromClientPackage.ResponseScreenshot, new WriterCall(bytes.Length + 2, writer => { writer.Write(Id); writer.Write(bytes, 2, bytes.Length - 2); }))); break; case FromClientPackage.InitializePushFile: //log handled in PushManager _tcpServerInfo.PushManager.PushRequest(new Guid(bytes), this); break; case FromClientPackage.PushHeader: FilePush?.Invoke(this, new FilePushEventArgs(FilePushPackageType.Header, bytes, new Guid(bytes.Take(16).ToArray()))); break; case FromClientPackage.PushFileData: FilePush?.Invoke(this, new FilePushEventArgs(FilePushPackageType.Data, bytes, new Guid(bytes.Take(16).ToArray()))); break; case FromClientPackage.StillAlive: break; case FromClientPackage.RequestStaticCommandPlugin: _tcpServerInfo.DynamicCommandManager.DynamicCommandPluginSender.RequestPlugin(this, BitConverter.ToInt32(bytes, 0)); break; case FromClientPackage.ResponseLibraryInformation: Logger.Debug("Client CI-{0} requests more detailed information about library", Id); SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(BitConverter.ToUInt16(bytes, 0), (byte)FromClientPackage.ResponseLibraryInformation, new WriterCall(2 + bytes.Length, writer => { writer.Write(Id); writer.Write(bytes, 2, bytes.Length - 2); }))); break; case FromClientPackage.ResponseLibraryLoadingResult: Logger.Debug("Client CI-{0} responded with the result of the library loading operation", Id); SendToAdministration?.Invoke(this, new SendPackageToAdministrationEventArgs(BitConverter.ToUInt16(bytes, 0), (byte)FromClientPackage.ResponseLibraryLoadingResult, new WriterCall(2 + bytes.Length, writer => { writer.Write(Id); writer.Write(bytes, 2, bytes.Length - 2); }))); break; case FromClientPackage.CheckStillAlive: break; //do nothing, TCP already responded when this package is here default: throw new ArgumentOutOfRangeException(); } _readByteDelegate.BeginInvoke(EndRead, null); } catch (Exception ex) { if (IsDisposed) { return; } Logger.Fatal(ex, "Error on reading data from client CI-{0}", Id); Dispose(); } }
public static Stream Decompress(Stream inputStream, CompressionMethod level = CompressionMethod.Default) { switch (level) { // bypass decompression case CompressionMethod.None: return inputStream; // decompress using DeflateStream case CompressionMethod.DeflateStream: { var stream = new MemoryStream(); using (var output = new DeflateStream(inputStream, CompressionMode.Decompress, true)) { int read; var buffer = new byte[BufferSize]; while ((read = output.Read(buffer, 0, BufferSize)) > 0) { stream.Write(buffer, 0, read); } } stream.Seek(0, SeekOrigin.Begin); return stream; } // decompress using LZF case CompressionMethod.LZF: { var buffer = new byte[BufferSize * 2]; var output = new byte[BufferSize]; var temp = new byte[ShortSize * 2]; var outStream = new MemoryStream(); var lzf = new LZF(); while (true) { // read chunk sizes if (inputStream.Read(temp, 0, ShortSize * 2) == 0) { break; } var sourceSize = BitConverter.ToInt16(temp, 0); var destSize = BitConverter.ToInt16(temp, ShortSize); var readCount = inputStream.Read(buffer, 0, destSize); if (readCount != destSize) { throw new InvalidOperationException("Cannot read input stream."); } var writeCount = lzf.Decompress(buffer, readCount, output, output.Length); if (writeCount != sourceSize) { throw new InvalidOperationException("Cannot decompress input stream."); } outStream.Write(output, 0, writeCount); } // rewind the output stream outStream.Seek(0, SeekOrigin.Begin); return outStream; } } // unknown compression method throw new InvalidOperationException(); }
/// <summary> /// Execute a function on the server /// </summary> /// <typeparam name="T">The response type</typeparam> /// <param name="functionName">The name of the function</param> /// <param name="specialParameterTypes"> /// Types which aren't obvious (e. g. if abstract classes are used) for the parameter /// in order to serialize it correctly /// </param> /// <param name="specialReturnTypes"> /// Types which aren't obvious (e. g. if abstract classes are used) for the response in /// order to deserialize it correctly /// </param> /// <param name="parameters">The parameters of the function</param> /// <returns>Returns the response from the server</returns> public T ExecuteFunction <T>(string functionName, List <Type> specialParameterTypes, List <Type> specialReturnTypes, params object[] parameters) { var methodGuid = Guid.NewGuid(); while (methodGuid == ExceptionGuid || methodGuid == FunctionNotFoundExceptionGuid) //possibilities are everywhere { methodGuid = Guid.NewGuid(); } var parameterData = new List <byte[]>(); foreach (var parameter in parameters) { var parameterType = parameter.GetType(); var types = new Type[1 + (specialParameterTypes?.Count ?? 0)]; types[0] = parameterType; if (specialParameterTypes != null && specialParameterTypes.Count > 0) { for (int i = 0; i < specialParameterTypes.Count; i++) { types[i + 1] = specialParameterTypes[i]; } } parameterData.Add(GetSerializer(parameterType, types).Serialize(parameter)); } var functionNameData = Encoding.UTF8.GetBytes(functionName); var data = new byte[16 + 4 + functionNameData.Length + 4 + parameterData.Count * 4 + parameterData.Sum(x => x.Length) ]; //Protocol //HEAD - 16 Bytes - Guid //HEAD - 4 Bytes - Function Name Length //HEAD - UTF8(FunctionName).Length - Function Name //INFO - 4 Bytes - Parameter count //PINF - COUNT(Paramters)*4 - Information about the length of the parameters //DATA - SUM(Parameters.Length) - The parameter data Buffer.BlockCopy(methodGuid.ToByteArray(), 0, data, 0, 16); Buffer.BlockCopy(BitConverter.GetBytes(functionNameData.Length), 0, data, 16, 4); Buffer.BlockCopy(functionNameData, 0, data, 20, functionNameData.Length); Buffer.BlockCopy(BitConverter.GetBytes(parameters.Length), 0, data, 20 + functionNameData.Length, 4); for (int i = 0; i < parameterData.Count; i++) { Buffer.BlockCopy(BitConverter.GetBytes(parameterData[i].Length), 0, data, 24 + functionNameData.Length + i * 4, 4); } int offset = 0; foreach (var parameter in parameterData) { Buffer.BlockCopy(parameter, 0, data, 24 + functionNameData.Length + parameterData.Count * 4 + offset, parameter.Length); offset += parameter.Length; } using (var autoResetEvent = new AutoResetEvent(false)) { _methodDictionary.Add(methodGuid, new MethodCaller(functionName, autoResetEvent)); _sendDataAction.Invoke(LZF.Compress(data, 0)); if (!autoResetEvent.WaitOne(Timeout)) { throw new InvalidOperationException("Timeout"); } _methodDictionary.Remove(methodGuid); Exception exception; if (_exceptionResponses.TryGetValue(methodGuid, out exception)) { _exceptionResponses.Remove(methodGuid); throw exception; } byte[] response; if (_methodResponses.TryGetValue(methodGuid, out response)) { _methodResponses.Remove(methodGuid); var types = new Type[1 + (specialReturnTypes?.Count ?? 0)]; types[0] = typeof(T); if (specialReturnTypes != null && specialReturnTypes.Count > 0) { for (int i = 0; i < specialReturnTypes.Count; i++) { types[i + 1] = specialReturnTypes[i]; } } return(GetSerializer(typeof(T), types).Deserialize <T>(response)); } return(default(T)); } }
public static Stream Compress(Stream inputStream, CompressionMethod level = CompressionMethod.Default) { switch (level) { // bypass compression case CompressionMethod.None: return inputStream; // average compression using DeflateStream case CompressionMethod.DeflateStream: { var stream = new MemoryStream(); using (var output = new DeflateStream(stream, CompressionMode.Compress, true)) { int read; var buffer = new byte[BufferSize]; while ((read = inputStream.Read(buffer, 0, BufferSize)) > 0) { output.Write(buffer, 0, read); } } stream.Seek(0, SeekOrigin.Begin); return stream; } // fast compression using LZF case CompressionMethod.LZF: { var buffer = new byte[BufferSize]; var output = new byte[BufferSize * 2]; // safe value for uncompressible data var outStream = new MemoryStream(); var lzf = new LZF(); while (true) { var readCount = (short)inputStream.Read(buffer, 0, buffer.Length); if (readCount == 0) { break; } var writeCount = (short)lzf.Compress(buffer, readCount, output, output.Length); if (writeCount == 0) { throw new InvalidOperationException("Cannot compress input stream."); } // write source size var temp = BitConverter.GetBytes(readCount); outStream.Write(temp, 0, ShortSize); // write destination size temp = BitConverter.GetBytes(writeCount); outStream.Write(temp, 0, ShortSize); // write data chunk outStream.Write(output, 0, writeCount); } // rewind the output stream outStream.Seek(0, SeekOrigin.Begin); return outStream; } } // unknown compression method throw new InvalidOperationException(); }
public static SqliteConnection UpgradeDatabase(string fileName, SqliteConnection sqliteConnection) { sqliteConnection.Close(); //we don't need that sqliteConnection.Dispose(); Logger.Info("Create new database"); var newDatabase = new FileInfo(Path.Combine(Path.GetDirectoryName(fileName), Guid.NewGuid().ToString("N"))); SqliteConnection.CreateFile(newDatabase.FullName); using (var newDatabaseConnection = new SqliteConnection($"Data Source={newDatabase.FullName};Version=3;")) { newDatabaseConnection.Open(); Logger.Info("Create tables"); DatabaseBuilder.CreateTables(newDatabaseConnection); Logger.Info("Import data"); //attach old database using ( var command = new SqliteCommand($"ATTACH DATABASE '{fileName}' AS 'OldDatabase'", newDatabaseConnection) ) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.Client (Id, UserName, HardwareId, ClientGroup, OSName, OSType, Language, LastSeen) SELECT Id, UserName, HardwareId, ClientGroup, OperatingSystemName, OSType, Language, LastSeen FROM OldDatabase.Client", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.Exception SELECT * FROM OldDatabase.Exception", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.RecoveredPassword SELECT * FROM OldDatabase.RecoveredPassword", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.RecoveredCookie SELECT * FROM OldDatabase.RecoveredCookies", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.NewClientsStatistic SELECT * FROM OldDatabase.NewClientsStatistics", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.ClientsConnected SELECT * FROM OldDatabase.ClientsConnected", newDatabaseConnection)) command.ExecuteNonQuery(); using (var command = new SqliteCommand("INSERT INTO main.ClientsConnectedStatistic SELECT * FROM OldDatabase.ClientsConnectedStatistics", newDatabaseConnection)) command.ExecuteNonQuery(); DirectoryInfo dataDirectory = null; using (var command = new SqliteCommand("SELECT ClientId, Data, Timestamp FROM OldDatabase.KeyLog", newDatabaseConnection)) using (var reader = command.ExecuteReader()) { while (reader.Read()) { if (dataDirectory == null) { dataDirectory = new DirectoryInfo("data"); if (!dataDirectory.Exists) { dataDirectory.Create(); } } Guid fileNameGuid; var dataFileName = Path.Combine(dataDirectory.FullName, (fileNameGuid = Guid.NewGuid()).ToString("D")); while (File.Exists(dataFileName)) { dataFileName = Path.Combine(dataDirectory.FullName, (fileNameGuid = Guid.NewGuid()).ToString("D")); } var data = LZF.Decompress((byte[])reader["Data"], 0); File.WriteAllBytes(dataFileName, data); using ( var command2 = new SqliteCommand( $"INSERT INTO main.Data (ClientId, Timestamp, Length, FileName, DataMode, EntryName, IsCsvData) VALUES ({reader.GetInt32(0)}, @timestamp, {data.Length}, '{fileNameGuid.ToString("N")}', 'e10e9542f6324f68bdf6f0ef1c9d04d2', @entryName, 0)", newDatabaseConnection) ) { command2.Parameters.AddWithValue("@timestamp", DateTime.Parse(reader.GetString(2), CultureInfo.InvariantCulture)); command2.Parameters.AddWithValue("@entryName", "Automatic Key Log"); command2.ExecuteNonQuery(); } } } using (var command = new SqliteCommand("SELECT Id, Succeeded, Failed, SentTo, Done, DynamicCommand, Parameter FROM OldDatabase.DynamicCommand", newDatabaseConnection)) using (var reader = command.ExecuteReader()) { var types = DynamicCommandInfo.RequiredTypes.ToList(); types.Remove(typeof(EveryClientOnceTransmissionEvent)); var serializer = new Serializer(types); var xmlSerializer = new XmlSerializer(typeof(DynamicCommand)); using (var transaction = newDatabaseConnection.BeginTransaction()) using (var command2 = newDatabaseConnection.CreateCommand()) { command2.Transaction = transaction; while (reader.Read()) { //no reason to reuse the StringWriter using (var stringWriter = new StringWriter()) { command2.CommandText = $"INSERT INTO main.DynamicCommand (Id, Succeeded, Failed, SentTo, Done, DynamicCommand, Parameter) VALUES ({reader.GetInt32(0)}, {reader.GetInt32(1)}, {reader.GetInt32(2)}, {reader.GetInt32(3)}, {reader.GetInt32(4)}, @dynamicCommand, @parameter)"; DynamicCommand dynamicCommand; try { dynamicCommand = serializer.Deserialize <DynamicCommand>((byte[])reader["DynamicCommand"]); } catch (Exception) { continue; } xmlSerializer.Serialize(stringWriter, dynamicCommand); command2.Parameters.AddWithValue("@dynamicCommand", stringWriter.ToString()); command2.Parameters.AddWithValue("@parameter", reader["Parameter"]); command2.ExecuteNonQuery(); command2.Parameters.Clear(); } } transaction.Commit(); } } } Logger.Info("Upgrade finished, cleaning up"); GC.Collect(); //necessary to free the database file, see here: https://stackoverflow.com/questions/8511901/system-data-sqlite-close-not-releasing-database-file GC.WaitForPendingFinalizers(); File.Delete(fileName); newDatabase.MoveTo(fileName); var connection = new SqliteConnection($"Data Source={fileName};Version=3;"); connection.Open(); Logger.Info("Database opened"); return(connection); }
private static List <int> ExecuteStaticCommand(IEnumerable <Client> clients, PotentialCommand potentialCommand) { Logger.Debug("Execute static command {0}", potentialCommand.CallbackId); var data = new Serializer(typeof(PotentialCommand)).Serialize(potentialCommand); var isCompressed = false; if (data.Length > 512) { var compressedData = LZF.Compress(data, 0); if (compressedData.Length < data.Length) { isCompressed = true; data = compressedData; } } var updateCommandCompatibilityParameter = new Lazy <byte[]>(() => CompatibilityManager.UpdateCommandToOldUpdateCommand(potentialCommand)); var updateFromUrlCompatibilityParameter = new Lazy <byte[]>( () => CompatibilityManager.UpdateFromUrlCommandToOldUpdateFromUrlCommand(potentialCommand)); var compatibilityData = new Lazy <byte[]>(() => CompatibilityManager.GetOldPotentialCommand(potentialCommand)); var clientList = new List <int>(); foreach (var client in clients) { try { if (client.ComputerInformation.ClientVersion >= 19) { client.SendStaticCommand(data, isCompressed); clientList.Add(client.Id); } else if (client.ComputerInformation.ClientVersion >= 13 && client.ComputerInformation.ClientVersion <= 18) { client.SendStaticCommand(compatibilityData.Value, isCompressed); clientList.Add(client.Id); } else { //UpdateCommand if (potentialCommand.CommandId == new Guid(0xafd0841b, 0x0035, 0x7045, 0x96, 0x32, 0x36, 0x98, 0x6c, 0xb1, 0x83, 0x1c)) { client.SendStaticCommand(updateCommandCompatibilityParameter.Value, false); clientList.Add(client.Id); } //UpdateFromUrlCommand else if (potentialCommand.CommandId == new Guid(0xe08e79f0, 0xcaea, 0xe341, 0x8a, 0xb2, 0xef, 0x84, 0xe1, 0x8f, 0xa2, 0x5f)) { client.SendStaticCommand(updateFromUrlCompatibilityParameter.Value, false); clientList.Add(client.Id); } } } catch (Exception) { // ignored } } Logger.Debug("Static command {0} successfully executed on {1} clients", potentialCommand.CallbackId, clientList.Count); return(clientList); }
/// <summary> /// Process the received data from a <see cref="DtpFactory" /> /// </summary> /// <param name="data">The data which was given using the <see cref="DtpFactory.SendDataAction" /> delegate</param> /// <param name="start">The start position of the byte array</param> /// <returns>Returns the response which must get processed in <see cref="DtpFactory.Receive" /></returns> public byte[] Receive(byte[] data, int start) { data = LZF.Decompress(data, start); var functionNameLength = BitConverter.ToInt32(data, 16); var functionName = Encoding.UTF8.GetString(data, 20, functionNameLength); if (!_procedures.ContainsKey(functionName) && !_functions.ContainsKey(functionName)) { ExceptionOccurred?.Invoke(this, new UnhandledExceptionEventArgs( new InvalidOperationException($"Method with name {functionName} not found"))); var errorResponse = new byte[16 + functionNameLength]; Array.Copy(DtpFactory.FunctionNotFoundExceptionGuid.ToByteArray(), errorResponse, 16); Array.Copy(data, 20, errorResponse, 16, functionNameLength); return(errorResponse); } var parameterCount = BitConverter.ToInt32(data, 20 + functionNameLength); var parameterLengths = new List <int>(); var parameters = new Dictionary <int, byte[]>(); for (int i = 0; i < parameterCount; i++) { parameterLengths.Add(BitConverter.ToInt32(data, 24 + functionNameLength + i * 4)); } var offset = 0; for (int i = 0; i < parameterCount; i++) { var parameterData = new byte[parameterLengths[i]]; Array.Copy(data, 24 + functionNameLength + parameterCount * 4 + offset, parameterData, 0, parameterData.Length); parameters.Add(i, parameterData); offset += parameterData.Length; } var dtpParameters = new DtpParameters(parameters); byte[] result = null; try { DtpProcedure procedure; if (_procedures.TryGetValue(functionName, out procedure)) { procedure.Invoke(dtpParameters); } else { DtpFunction function; if (_functions.TryGetValue(functionName, out function)) { var returnedObject = function.Invoke(dtpParameters); if (returnedObject != null) { var typeList = new List <Type> { returnedObject.GetType() }; Type[] specialTypes; if (_specialTypes.TryGetValue(functionName, out specialTypes)) { typeList.AddRange(specialTypes); } result = new Serializer(typeList).Serialize(returnedObject); } } } } catch (Exception ex) { var exception = new DtpException { Message = ex.Message, StackTrace = ex.StackTrace, FunctionName = functionName, ParameterInformation = string.Join(", ", parameters.Select(x => x.Key + " - " + x.Value.Length + " B").ToArray()), SessionGuid = new Guid(data.Take(16).ToArray()) }; var exceptionData = new Serializer(typeof(DtpException)).Serialize(exception); var errorResponse = new byte[16 + exceptionData.Length]; Array.Copy(DtpFactory.ExceptionGuid.ToByteArray(), errorResponse, 16); Array.Copy(exceptionData, 0, errorResponse, 16, exceptionData.Length); ExceptionOccurred?.Invoke(this, new UnhandledExceptionEventArgs(ex)); return(LZF.Compress(errorResponse, 0)); } var response = new byte[16 + 4 + (result?.Length ?? 0)]; //Protocol //HEAD - 16 Bytes - Guid //HEAD - 4 Bytes - Response Length //DATA - result.Length - Result Length Array.Copy(data, 0, response, 0, 16); //copy guid Array.Copy(BitConverter.GetBytes(result?.Length ?? 0), 0, response, 16, 4); if (result != null) { Array.Copy(result, 0, response, 20, result.Length); } return(LZF.Compress(response, 0)); }
private void EndRead(IAsyncResult asyncResult) { try { var parameter = _readByteDelegate.EndInvoke(asyncResult); var size = Sender.Connection.BinaryReader.ReadInt32(); var bytes = Sender.Connection.BinaryReader.ReadBytes(size); Serializer serializer; OnlineClientInformation client; int clientId; PackageInformation packageInformation = null; if (PackageReceived != null) { packageInformation = new PackageInformation { Size = bytes.Length + 1, Timestamp = DateTime.Now, IsReceived = true } } ; switch ((FromClientPackage)parameter) { case FromClientPackage.ResponseToAdministration: case FromClientPackage.ResponseToAdministrationCompressed: var isCompressed = parameter == (byte)FromClientPackage.ResponseToAdministrationCompressed; var data = isCompressed ? LZF.Decompress(bytes, 1) : bytes; if (packageInformation != null) { packageInformation.Description = (FromClientPackage)parameter + " " + CurrentController.DescribePackage(bytes[0], data, isCompressed ? 0 : 1); } CurrentController?.PackageReceived(bytes[0], data, isCompressed ? 0 : 1); break; case FromClientPackage.ResponseLoginOpen: clientId = BitConverter.ToInt32(bytes, 0); client = _loginsPending.FirstOrDefault(x => x.Id == clientId); if (client == null) { Logger.Error((string)Application.Current.Resources["CouldNotFindClient"]); break; } _loginsPending.Remove(client); Application.Current.Dispatcher.BeginInvoke(new Action(() => { CurrentController = new ClientController(client, Sender, this); ((Commander)CurrentController.Commander).ConnectionInfo.PackageSent += _packageSentEventHandler; LoginOpened?.Invoke(this, EventArgs.Empty); })); break; case FromClientPackage.NewClientConnected: serializer = new Serializer(new[] { typeof(ClientInformation), typeof(OnlineClientInformation) }); client = serializer.Deserialize <OnlineClientInformation>(bytes); Logger.Info(string.Format((string)Application.Current.Resources["NewClientConnected"], client.IpAddress, client.Port, client.UserName)); lock (_clientListUpdateLock) Application.Current.Dispatcher.Invoke(() => ClientProvider.NewClientConnected(client)); NewClientConnected?.Invoke(this, client); break; case FromClientPackage.ClientConnected: serializer = new Serializer(new[] { typeof(ClientInformation), typeof(OnlineClientInformation) }); client = serializer.Deserialize <OnlineClientInformation>(bytes); Logger.Info(string.Format((string)Application.Current.Resources["NewClientConnected"], client.IpAddress, client.Port, client.UserName)); lock (_clientListUpdateLock) Application.Current.Dispatcher.Invoke(() => ClientProvider.ClientConnected(client)); ClientConnected?.Invoke(this, client); break; case FromClientPackage.ClientDisconnected: var disconnectedClientId = BitConverter.ToInt32(bytes, 0); if (CurrentController != null && CurrentController.Client.Id == disconnectedClientId) { CurrentController.Dispose(); CurrentController = null; } lock (_clientListUpdateLock) Application.Current.Dispatcher.Invoke( () => ClientProvider.ClientDisconnected(disconnectedClientId)); ClientDisconnected?.Invoke(this, disconnectedClientId); break; case FromClientPackage.ComputerInformationAvailable: var clientWithComputerInformationId = BitConverter.ToInt32(bytes, 0); Application.Current.Dispatcher.BeginInvoke( new Action( () => ClientProvider.ComputerInformationAvailable(clientWithComputerInformationId))); break; case FromClientPackage.PasswordsAvailable: var clientWithPasswordsId = BitConverter.ToInt32(bytes, 0); ClientProvider.PasswordsAvailable(clientWithPasswordsId); break; case FromClientPackage.GroupChanged: var newGroupNameLength = BitConverter.ToInt32(bytes, 0); var newGroupName = Encoding.UTF8.GetString(bytes, 4, newGroupNameLength); var clients = new Serializer(typeof(List <int>)).Deserialize <List <int> >(bytes, 4 + newGroupNameLength); ClientProvider.ClientGroupChanged(clients, newGroupName); Logger.Receive((string)Application.Current.Resources["GroupChanged"]); break; case FromClientPackage.ClientsRemoved: serializer = new Serializer(typeof(List <int>)); var removedClientsIds = serializer.Deserialize <List <int> >(bytes); lock (_clientListUpdateLock) Application.Current.Dispatcher.Invoke( () => ClientProvider.ClientRemoved(removedClientsIds)); if (removedClientsIds.Count == 1) { Logger.Receive((string)Application.Current.Resources["ClientRemoved"]); } else { Logger.Receive(string.Format((string)Application.Current.Resources["ClientsRemoved"], removedClientsIds.Count)); } break; case FromClientPackage.DynamicCommandsRemoved: DynamicCommandsRemoved?.Invoke(this, new Serializer(typeof(List <int>)).Deserialize <List <int> >(bytes)); break; case FromClientPackage.PluginLoaded: clientId = BitConverter.ToInt32(bytes, 0); var pluginInfo = new Serializer(typeof(PluginInfo)).Deserialize <PluginInfo>(bytes, 4); ClientProvider.ClientPluginAvailable(clientId, pluginInfo); PluginLoaded?.Invoke(this, new PluginLoadedEventArgs(clientId, pluginInfo.Guid, pluginInfo.Version, true)); break; case FromClientPackage.PluginLoadFailed: clientId = BitConverter.ToInt32(bytes, 0); PluginLoadingFailed?.Invoke(this, new PluginLoadedEventArgs(clientId, new Guid(bytes.Skip(4).Take(16).ToArray()), Encoding.ASCII.GetString(bytes.Skip(20).ToArray()), false)); break; case FromClientPackage.DataTransferProtocolResponse: if (packageInformation != null) { packageInformation.Description = "DataTransferProtocolResponse - " + DataTransferProtocolFactory.DescribeReceivedData(bytes, 0); } DataTransferProtocolFactory.Receive(bytes); break; case FromClientPackage.ResponseActiveWindow: clientId = BitConverter.ToInt32(bytes, 0); var clientViewModel = ClientProvider.Clients.FirstOrDefault(x => x.Id == clientId); if (clientViewModel != null) { clientViewModel.ActiveWindow = Encoding.UTF8.GetString(bytes, 4, bytes.Length - 4); } break; case FromClientPackage.ResponseScreenshot: clientId = BitConverter.ToInt32(bytes, 0); var clientViewModel2 = ClientProvider.Clients.FirstOrDefault(x => x.Id == clientId); if (clientViewModel2 != null) { using (var stream = new MemoryStream(bytes, 4, bytes.Length - 4)) using (var image = (Bitmap)Image.FromStream(stream)) clientViewModel2.Thumbnail = BitmapConverter.ToBitmapSource(image); } break; case FromClientPackage.DataRemoved: DataRemoved?.Invoke(this, new Serializer(typeof(List <int>)).Deserialize <List <int> >(bytes)); break; case FromClientPackage.PasswordsRemoved: var clientIds = new Serializer(typeof(List <int>)).Deserialize <List <int> >(bytes); foreach (var id in clientIds) { ClientProvider.PasswordsRemoved(id); } PasswordsRemoved?.Invoke(this, clientIds); break; case FromClientPackage.DataDownloadPackage: DownloadDataReceived?.Invoke(this, bytes); break; case FromClientPackage.StaticCommandPluginReceived: StaticCommandReceived?.Invoke(this, bytes); break; case FromClientPackage.StaticCommandPluginTransmissionFailed: StaticCommandTransmissionFailed?.Invoke(this, bytes); break; case FromClientPackage.DynamicCommandAdded: DynamicCommandAdded?.Invoke(this, new Serializer(RegisteredDynamicCommand.RequiredTypes).Deserialize <RegisteredDynamicCommand>(bytes)); break; case FromClientPackage.DynamicCommandEventsAdded: DynamicCommandEventsAdded?.Invoke(this, new Serializer(typeof(List <DynamicCommandEvent>)).Deserialize <List <DynamicCommandEvent> >( bytes)); break; case FromClientPackage.DynamicCommandStatusUpdate: DynamicCommandStatusUpdated?.Invoke(this, new DynamicCommandStatusUpdatedEventArgs(BitConverter.ToInt32(bytes, 0), (DynamicCommandStatus)bytes[4])); break; case FromClientPackage.ResponseLibraryInformation: LibraryInformationReceived?.Invoke(this, new LibraryInformationEventArgs(BitConverter.ToInt32(bytes, 0), (PortableLibrary)BitConverter.ToInt32(bytes, 4))); break; case FromClientPackage.ResponseLibraryLoadingResult: LibraryLoadingResultReceived?.Invoke(this, new LibraryInformationEventArgs(BitConverter.ToInt32(bytes, 0), (PortableLibrary)BitConverter.ToInt32(bytes, 4))); break; case FromClientPackage.ActiveCommandsChanged: ActiveCommandsChanged?.Invoke(this, new Serializer(typeof(ActiveCommandsUpdate)).Deserialize <ActiveCommandsUpdate>(bytes, 0)); break; default: throw new ArgumentOutOfRangeException(); } if (packageInformation != null) { if (string.IsNullOrEmpty(packageInformation.Description)) { packageInformation.Description = ((FromClientPackage)parameter).ToString(); } PackageReceived?.Invoke(this, packageInformation); } _readByteDelegate.BeginInvoke(EndRead, null); } catch (Exception ex) { if (!(ex is IOException) || ex.HResult != -2147024858) { LogManager.GetCurrentClassLogger().Warn(ex, "Disconnected from server"); if (Application.Current != null) { Logger.Error(string.Format((string)Application.Current.Resources["DisconnectedFromServerException"], ex.Message)); } } else if (Application.Current != null) { Logger.Warn((string)Application.Current.Resources["DisconnectedFromServer"]); } else { LogManager.GetCurrentClassLogger().Warn("NullReference"); } Dispose(); Disconnected?.Invoke(this, EventArgs.Empty); } }
private void Read(BinaryReader binaryReader) { Logger.Debug("Begin reading data from stream of administration AI-{0}", Id); try { while (true) { var parameter = binaryReader.ReadByte(); var size = Connection.BinaryReader.ReadInt32(); var bytes = new Lazy <byte[]>(() => Connection.BinaryReader.ReadBytes(size)); int clientId; switch ((FromAdministrationPackage)parameter) { case FromAdministrationPackage.InitializeNewSession: clientId = BitConverter.ToInt32(bytes.Value, 0); SendPackageToClient?.Invoke(this, new SendPackageToClientEventArgs(clientId, (byte)FromAdministrationPackage.InitializeNewSession, new WriterCall(2, writer => writer.Write(Id)))); _openClientSessions.Add(clientId); Logger.Info("Administration AI-{0} initializes session with client CI-{1}", Id, clientId); break; case FromAdministrationPackage.CloseSession: clientId = BitConverter.ToInt32(bytes.Value, 0); _openClientSessions.Remove(clientId); SendPackageToClient?.Invoke(this, new SendPackageToClientEventArgs(clientId, (byte)FromAdministrationPackage.CloseSession, new WriterCall(2, writer => writer.Write(Id)))); Logger.Info("Administration AI-{0} closed session with client CI-{1}", Id, clientId); break; case FromAdministrationPackage.SendCommandCompressed: case FromAdministrationPackage.SendCommand: clientId = BitConverter.ToInt32(bytes.Value, 0); Logger.Debug("Administration AI-{0} sends command to client CI-{1}", Id, clientId); SendPackageToClient?.Invoke(this, new SendPackageToClientEventArgs(clientId, parameter, new WriterCall(bytes.Value.Length - 2, writer => { writer.Write(Id); writer.Write(bytes.Value, 4, bytes.Value.Length - 4); }))); break; case FromAdministrationPackage.SendDynamicCommand: DynamicCommandReceived( new Serializer(DynamicCommandInfo.RequiredTypes).Deserialize <DynamicCommand>( bytes.Value, 0)); break; case FromAdministrationPackage.SendDynamicCommandCompressed: DynamicCommandReceived( new Serializer(DynamicCommandInfo.RequiredTypes).Deserialize <DynamicCommand>( LZF.Decompress(bytes.Value, 0))); break; case FromAdministrationPackage.LoadPlugin: clientId = BitConverter.ToInt32(bytes.Value, 0); Logger.Debug("Administration AI-{0} requests plugin loading on client CI-{1}", Id, clientId); SendPackageToClient?.Invoke(this, new SendPackageToClientEventArgs(clientId, parameter, new WriterCall(bytes.Value.Length - 2, writer => { writer.Write(Id); writer.Write(bytes.Value, 4, bytes.Value.Length - 4); }))); break; case FromAdministrationPackage.DataTransferProtocol: Logger.Debug("Data Transfer Protocol package received"); var result = _dtpProcessor.Receive(bytes.Value); Logger.Debug("Data Transfer Protocol package processed"); lock (_sendLock) { Connection.BinaryWriter.Write((byte)FromClientPackage.DataTransferProtocolResponse); Connection.BinaryWriter.Write(result.Length); Connection.BinaryWriter.Write(result); } break; case FromAdministrationPackage.SendStaticCommandPlugin: Logger.Debug("Send dynamic command plugin with size {0} B", size); ReceiveStaticCommandPlugin(binaryReader, size); break; case FromAdministrationPackage.ClientRedirect: ClientRedirect(binaryReader, size); break; default: throw new ArgumentOutOfRangeException(); } } } catch (Exception ex) { if (Logger.IsDebugEnabled) { Logger.Debug(ex, "Exception occurred in administration AI-{0} receive handler", Id); } else if (!(ex is EndOfStreamException)) { Logger.Fatal(ex, "Exception occurred in administration AI-{0} receive handler", Id); } if (_openClientSessions.Count > 0) { Logger.Info( "Administration AI-{0} is disconnecting but has still opened sessions. Closing open sessions ({1} session{2})", Id, _openClientSessions.Count, _openClientSessions.Count > 1 ? "s" : ""); foreach (var openClientSession in _openClientSessions) { SendPackageToClient?.Invoke(this, new SendPackageToClientEventArgs(openClientSession, (byte)FromAdministrationPackage.CloseSession, new WriterCall(BitConverter.GetBytes(Id)))); } Logger.Debug("Open sessions closed"); _openClientSessions.Clear(); } Dispose(); } }