C#NET内存DLL加载 MemoryModuleSX

加载内存中的dll/exe 并且支持AnyCPU编译!
使用方法可以看解决方案中的Test项目

 1 #pragma warning disable IDE0001
 2 using System;
 3 using System.Collections.Generic;
 4 using System.IO;
 5 using System.Linq;
 6 using System.Reflection;
 7 using System.Runtime.InteropServices;
 8 using System.Threading;
 9 using MemoryModuleSX;
10 using size_t = System.IntPtr;
11 
12 namespace Test
13 {
14     public static class MemoryModuleSXTest
15     {
16         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
17         private delegate size_t FastLzma2CompressProc(byte[] dst, size_t dstCapacity, byte[] src, size_t srcSize, int compressionLevel, uint nbThreads);
18 
19         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
20         private delegate size_t FastLzma2DecompressProc(byte[] dst, size_t dstCapacity, byte[] src, size_t compressedSize);
21 
22         private static FastLzma2CompressProc FastLzma2Compress;
23 
24         private static FastLzma2DecompressProc FastLzma2Decompress;
25 
26         public static void Test()
27         {
28             MemoryModule memoryModule;
29             byte[] src;
30             byte[] deced;
31 
32             using (BinaryReader binaryReader = new BinaryReader(Assembly.GetExecutingAssembly().GetManifestResourceStream($"Test.FLzma2_{(Environment.Is64BitProcess ? "64" : "32")}.dll")))
33                 memoryModule = MemoryModule.Create(binaryReader.ReadBytes((int)binaryReader.BaseStream.Length));
34             FastLzma2Compress = memoryModule.GetProcDelegate<FastLzma2CompressProc>("FL2_compressMt");
35             FastLzma2Decompress = memoryModule.GetProcDelegate<FastLzma2DecompressProc>("FL2_decompress");
36             List<byte> byteList = new List<byte>();
37             foreach (string filePath in Directory.EnumerateFiles(Environment.CurrentDirectory))
38                 byteList.AddRange(File.ReadAllBytes(filePath));
39             src = byteList.ToArray();
40             Compress(src);
41             deced = Decompress((size_t)src.Length);
42             Console.WriteLine(src.SequenceEqual(deced));
43             GC.Collect();
44             while (true)
45                 Thread.Sleep(int.MaxValue);
46         }
47 
48         private static void Compress(byte[] src)
49         {
50             byte[] tmp;
51             size_t size;
52             byte[] dest;
53 
54             tmp = new byte[src.Length + 0x4000];
55             size = FastLzma2Compress(tmp, (size_t)tmp.Length, src, (size_t)src.Length, 100, 0);
56             dest = new byte[(ulong)size];
57             Buffer.BlockCopy(tmp, 0, dest, 0, dest.Length);
58             File.WriteAllBytes("enced", dest);
59         }
60 
61         private static byte[] Decompress(size_t length)
62         {
63             byte[] src;
64             byte[] dest;
65 
66             src = File.ReadAllBytes("enced");
67             dest = new byte[(ulong)length];
68             FastLzma2Decompress(dest, (size_t)dest.Length, src, (size_t)src.Length);
69             return dest;
70         }
71     }
72 }
73 #pragma warning restore IDE0001
  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Runtime.InteropServices;
  5 
  6 namespace MemoryModuleSX
  7 {
  8     /// <summary>
  9     /// Load dll/exe from memory
 10     /// </summary>
 11     public unsafe class MemoryModule
 12     {
 13         private MEMORYMODULE _internalModule;
 14 
 15         private MemoryModule(MEMORYMODULE internalModule) => _internalModule = internalModule;
 16 
 17         /// <summary>
 18         /// Create an instance of the <see cref="MemoryModule"/>
 19         /// </summary>
 20         /// <param name="data">A pointer to dll/exe</param>
 21         /// <param name="size">The size of data</param>
 22         /// <returns></returns>
 23         public static MemoryModule Create(void* data, uint size)
 24         {
 25             if (data == null)
 26                 throw new ArgumentNullException();
 27             if (size <= 0)
 28                 throw new ArgumentOutOfRangeException();
 29 
 30             MEMORYMODULE internalModule;
 31 
 32             internalModule = MemoryModuleC.MemoryLoadLibrary(data, (void*)size);
 33             if (internalModule == null)
 34                 return null;
 35             else
 36                 return new MemoryModule(internalModule);
 37         }
 38 
 39         /// <summary>
 40         /// Create an instance of the <see cref="MemoryModule"/>
 41         /// </summary>
 42         /// <param name="data"></param>
 43         /// <returns></returns>
 44         public static MemoryModule Create(byte[] data)
 45         {
 46             if (data == null || data.Length == 0)
 47                 throw new ArgumentNullException();
 48 
 49             fixed (byte* p = data)
 50                 return Create(p, (uint)data.Length);
 51         }
 52 
 53         /// <summary>
 54         /// Create an instance of the <see cref="MemoryModule"/>
 55         /// </summary>
 56         /// <param name="stream"></param>
 57         /// <returns></returns>
 58         public static MemoryModule Create(Stream stream)
 59         {
 60             return Create(StreamReadAllBytes(stream));
 61         }
 62 
 63         private static byte[] StreamReadAllBytes(Stream stream)
 64         {
 65             if (!stream.CanRead)
 66                 throw new ArgumentException("Can't read the stream");
 67 
 68             int length;
 69             byte[] buffer;
 70             List<byte> byteList;
 71             int count;
 72 
 73             try
 74             {
 75                 try
 76                 {
 77                     length = (int)stream.Length;
 78                     buffer = new byte[length];
 79                     stream.Read(buffer, 0, buffer.Length);
 80                     return buffer;
 81                 }
 82                 catch
 83                 {
 84                     buffer = new byte[0x1000];
 85                     byteList = new List<byte>();
 86                     for (int i = 0; i < int.MaxValue; i++)
 87                     {
 88                         count = stream.Read(buffer, 0, buffer.Length);
 89                         if (count == 0x1000)
 90                             byteList.AddRange(buffer);
 91                         else if (count == 0)
 92                             return byteList.ToArray();
 93                         else
 94                             for (int j = 0; j < count; j++)
 95                                 byteList.Add(buffer[j]);
 96                     }
 97                 }
 98             }
 99             catch
100             {
101                 return null;
102             }
103             throw new OutOfMemoryException();
104         }
105 
106         /// <summary>
107         /// Free current instance of the <see cref="MemoryModule"/>
108         /// </summary>
109         public void FreeLibrary()
110         {
111             MemoryModuleC.MemoryFreeLibrary(_internalModule);
112         }
113 
114         /// <summary>
115         /// Retrieves the address of an exported function from current instance of the <see cref="MemoryModule"/>
116         /// </summary>
117         /// <param name="functionName">The function name</param>
118         /// <returns></returns>
119         public IntPtr GetProcAddress(string functionName)
120         {
121             return (IntPtr)MemoryModuleC.MemoryGetProcAddress(_internalModule, functionName);
122         }
123 
124         /// <summary>
125         /// Get the delegate of an exported function from current instance of the <see cref="MemoryModule"/>
126         /// </summary>
127         /// <typeparam name="T"></typeparam>
128         /// <param name="functionName">The function name</param>
129         /// <returns></returns>
130         public T GetProcDelegate<T>(string functionName)
131         {
132             return (T)(object)Marshal.GetDelegateForFunctionPointer(GetProcAddress(functionName), typeof(T));
133         }
134     }
135 }

                                                                                                            xmzjg.lofter.com

猜你喜欢

转载自www.cnblogs.com/wz2988/p/12430376.html