加载内存中的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