Download multiple DLLs from a server, dynamically load them into memory, and invoke their functions

Program.cs

using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Windows.Forms;
using XuanHe.Toolkit.Helper;

namespace WindowsFormsApp1
{
    public static class Program
    {
        static async Task Main()
        {
            var _loadedAssemblies = await BatchLoadAssembly();

            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
                var assemblyName = new AssemblyName(args.Name).Name;
                if(_loadedAssemblies.TryGetValue(assemblyName, out byte[] bytes))
                {
                    try
                    {
                        return Assembly.Load(bytes);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"Load assembly {assemblyName} failure: {ex.Message}");
                    }
                }
                return null;
            };

            var mainAssemblyBytes = _loadedAssemblies["XuanHe.Client"];
            Assembly assembly = Assembly.Load(mainAssemblyBytes);
            Type programType = assembly.GetType("XuanHe.Client.Program");
            MethodInfo runMethod = programType.GetMethod("RunAppplication",
                BindingFlags.Static | BindingFlags.Public);
            if (runMethod != null)
            {
                runMethod.Invoke(null, null);
            }
            else
            {
                MessageBox.Show("can not found RunApplication method.");
            }
        }

        static async Task<IDictionary<string, byte[]>> BatchLoadAssembly()
        {
            return await Task.Run(() =>
            {
                var _loadedAssemblies = new Dictionary<string, byte[]>();

                var assemblyNames = new[]
                {
                    "XuanHe.Client",
                    "XuanHe.Common",
                    "protobuf-net",
                    "BouncyCastle.Crypto",
                    "Mono.Cecil",
                    "Mono.Cecil.Mdb",
                    "Mono.Cecil.Pdb",
                    "Mono.Cecil.Rocks",
                    "Vestris.ResourceLib",
                    "Gma.System.MouseKeyHook",
                    "Open.Nat"
                };
                foreach (var assemblyName in assemblyNames)
                {
                    var webClient = new WebClient();
                    var bytes = webClient.DownloadData($"http://192.168.1.101:8080/{assemblyName}.dll");

                    // decryto
                    //var password = "MySecretPassword123";
                    //var ivString = "1234567890123456";
                    //var encryptor = new AesEncryptoHelper(password, ivString);
                    //encryptor.Mode = CipherMode.CBC;
                    //encryptor.Padding = PaddingMode.PKCS7;
                    //bytes = encryptor.Decrypt(bytes);

                    _loadedAssemblies[assemblyName] = bytes;
                }
                return _loadedAssemblies;

            });
        }
    }
}

AesEncryptoHelper.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace XuanHe.Toolkit.Helper
{
    /// <summary>
    /// Aes加解密助手类
    /// https://baike.baidu.com/item/%E9%AB%98%E7%BA%A7%E5%8A%A0%E5%AF%86%E6%A0%87%E5%87%86/468774
    /// </summary>
    public class AesEncryptoHelper : IDisposable
    {
        private readonly Aes _aes;
        private bool _disposed = false;

        // 构造函数,使用指定的密钥和初始化向量
        public AesEncryptoHelper(byte[] key, byte[] iv = null)
        {
            _aes = Aes.Create();
            _aes.Key = key;

            if (iv != null)
            {
                _aes.IV = iv;
            }
            else
            {
                // 如果未提供IV,则生成一个随机IV
                _aes.GenerateIV();
            }
        }

        // 构造函数,使用指定的密钥和初始化向量(字符串形式)
        public AesEncryptoHelper(string key, string iv = null, Encoding encoding = null)
        {
            encoding = encoding ?? Encoding.UTF8;
            _aes = Aes.Create();

            // 确保密钥长度符合AES要求(128、192或256位)
            _aes.Key = AdjustKeySize(encoding.GetBytes(key), _aes.LegalKeySizes);

            if (!string.IsNullOrEmpty(iv))
            {
                _aes.IV = AdjustIvSize(encoding.GetBytes(iv), _aes.BlockSize);
            }
            else
            {
                _aes.GenerateIV();
            }
        }

        // 获取当前使用的初始化向量
        public byte[] IV => _aes.IV;

        // 设置加密模式
        public CipherMode Mode
        {
            get => _aes.Mode;
            set => _aes.Mode = value;
        }

        // 设置填充模式
        public PaddingMode Padding
        {
            get => _aes.Padding;
            set => _aes.Padding = value;
        }

        // 加密字节数组
        public byte[] Encrypt(byte[] data)
        {
            if (data == null || data.Length == 0)
                return new byte[0];

            using (var encryptor = _aes.CreateEncryptor())
            using (var ms = new MemoryStream())
            using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            {
                cs.Write(data, 0, data.Length);
                cs.FlushFinalBlock();
                return ms.ToArray();
            }
        }

        // 解密字节数组
        public byte[] Decrypt(byte[] encryptedData)
        {
            if (encryptedData == null || encryptedData.Length == 0)
                return new byte[0];

            using (var decryptor = _aes.CreateDecryptor())
            using (var ms = new MemoryStream(encryptedData))
            using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
            using (var resultMs = new MemoryStream())
            {
                var buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = cs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    resultMs.Write(buffer, 0, bytesRead);
                }
                return resultMs.ToArray();
            }
        }

        // 加密字符串
        public string Encrypt(string data, Encoding encoding = null)
        {
            encoding = encoding ?? Encoding.UTF8;
            var dataBytes = encoding.GetBytes(data);
            var encryptedBytes = Encrypt(dataBytes);
            return Convert.ToBase64String(encryptedBytes);
        }

        // 解密字符串
        public string Decrypt(string encryptedData, Encoding encoding = null)
        {
            encoding = encoding ?? Encoding.UTF8;
            var encryptedBytes = Convert.FromBase64String(encryptedData);
            var decryptedBytes = Decrypt(encryptedBytes);
            return encoding.GetString(decryptedBytes);
        }

        // 调整密钥大小以符合AES要求
        private byte[] AdjustKeySize(byte[] key, KeySizes[] legalKeySizes)
        {
            // 计算密钥的位数
            int keyBits = key.Length * 8;

            // 查找符合要求的密钥大小
            foreach (var keySize in legalKeySizes)
            {
                if (keyBits >= keySize.MinSize && keyBits <= keySize.MaxSize &&
                    keyBits % keySize.SkipSize == 0)
                {
                    return key;
                }
            }

            // 如果密钥大小不符合要求,创建一个新的符合要求的密钥
            using (var aes = Aes.Create())
            {
                aes.KeySize = legalKeySizes[0].MaxSize;
                Array.Copy(key, aes.Key, Math.Min(key.Length, aes.Key.Length));
                return aes.Key;
            }
        }

        // 调整初始化向量大小以符合AES要求
        private byte[] AdjustIvSize(byte[] iv, int blockSize)
        {
            int blockBytes = blockSize / 8;

            if (iv.Length == blockBytes)
                return iv;

            // 创建新的IV并复制原始数据(如有必要截断或填充)
            var newIv = new byte[blockBytes];
            Array.Copy(iv, newIv, Math.Min(iv.Length, blockBytes));
            return newIv;
        }

        // 实现IDisposable接口
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _aes?.Dispose();
                }
                _disposed = true;
            }
        }

        ~AesEncryptoHelper()
        {
            Dispose(false);
        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容