From 36cf1f0b1bc135a057391fbdd3efea927e9b8a11 Mon Sep 17 00:00:00 2001 From: ergoxiv Date: Tue, 2 Jun 2026 01:30:29 +0200 Subject: [PATCH] Downgrade to 1.0.14-mem-buffers-2.0.0 to synchronize with Reloaded.Hooks fork dependencies --- Source/Reloaded.Assembler/Assembler.cs | 388 +++++++++--------- .../Reloaded.Assembler.csproj | 4 +- 2 files changed, 206 insertions(+), 186 deletions(-) diff --git a/Source/Reloaded.Assembler/Assembler.cs b/Source/Reloaded.Assembler/Assembler.cs index c009c42..fef566f 100644 --- a/Source/Reloaded.Assembler/Assembler.cs +++ b/Source/Reloaded.Assembler/Assembler.cs @@ -5,224 +5,244 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Threading; using Reloaded.Assembler.Definitions; using Reloaded.Memory.Buffers; -using Reloaded.Memory.Buffers.Structs; -using Reloaded.Memory.Buffers.Structs.Params; +using Reloaded.Memory.Sources; using static Reloaded.Assembler.Kernel32.Kernel32; +using static Reloaded.Memory.Kernel32.Kernel32; -namespace Reloaded.Assembler; - -/// -/// Assembler class allows you to assemble X86 and X64 mnemonics using FASM. -/// -public unsafe class Assembler : IDisposable +namespace Reloaded.Assembler { - // Address and size of allocation of where the text/mnemonics to be assembled will be stored. - private object _lock = new(); - private PrivateAllocation _textAllocation; - private PrivateAllocation _resultAllocation; - - private readonly FasmDelegates.fasm_Assemble _assembleFunction; - private readonly FasmDelegates.fasm_GetVersion _getVersionFunction; - - /* Create the common static members. */ - /// - /// Creates a new instance of the FASM assembler. + /// Assembler class allows you to assemble X86 and X64 mnemonics using FASM. /// - /// - /// The minimum size of the buffer to be used for passing the - /// text to be assembled to FASM Assembler. - /// - /// - /// The minimum size of the buffer to be used for FASM to return the - /// text to be assembled. - /// - /// - /// The base directory to search for the FASM DLL. - /// If not provided, the current directory and the executing assembly's directory will be searched. - /// - public Assembler(int textSize = 0x10000, int resultSize = 0x8000, string fasmDir = null) + public unsafe class Assembler : IDisposable { - // Attempt allocation of memory X times. - AllocateText(textSize); - AllocateResult(resultSize); - - // Get path of FASM dll - string fasmDllPath = GetFasmDLLPath(fasmDir); - var fasmDllHandle = LoadLibraryW(fasmDllPath); - - // Throw exception if dll not loaded. - if (fasmDllHandle == IntPtr.Zero) - throw new FasmWrapperException("Failed to load FASM dll. The FASM dll pointer from LoadLibraryW is null."); - - // Obtain delegates to FASM functions. - IntPtr assembleAddress = GetProcAddress(fasmDllHandle, "fasm_Assemble"); - IntPtr getVersionAddress = GetProcAddress(fasmDllHandle, "fasm_GetVersion"); - _assembleFunction = Marshal.GetDelegateForFunctionPointer(assembleAddress); - _getVersionFunction = Marshal.GetDelegateForFunctionPointer(getVersionAddress); - } + // Address and size of allocation of where the text/mnemonics to be assembled will be stored. + private object _lock = new object(); + private nuint _textAddress; + private int _textSize; + private nuint _resultAddress; + private int _resultSize; - /// - /// Destroys this instance of the class. - /// - ~Assembler() => Dispose(); + private static readonly MemoryBufferHelper _bufferHelper; + private static readonly Memory.Sources.Memory _processMemory; - /// - /// Releases the allocated memory for the assembler. - /// - public void Dispose() - { - _textAllocation.Dispose(); - _resultAllocation.Dispose(); - GC.SuppressFinalize(this); - } + private readonly FasmDelegates.fasm_Assemble _assembleFunction; + private readonly FasmDelegates.fasm_GetVersion _getVersionFunction; - /// - /// Retrieves the version of the internally used FASM assembler DLL. - /// - /// - public Version GetVersion() - { - // Call the native function to get the version - int nativeVersion = _getVersionFunction(); - - // Create and return a managed version object - return new Version(nativeVersion & 0xff, (nativeVersion >> 16) & 0xff); - } + /* Create the common static members. */ + static Assembler() + { + _processMemory = new Memory.Sources.Memory(); + _bufferHelper = new MemoryBufferHelper(Process.GetCurrentProcess()); + } - /// - /// Assembles a file at a given path. - /// - /// The path of the file to be assembled. - /// The assembled file. - public byte[] AssembleFile(string filePath) - { - return Assemble(File.ReadAllLines(filePath)); - } + /// + /// Creates a new instance of the FASM assembler. + /// + /// + /// The minimum size of the buffer to be used for passing the + /// text to be assembled to FASM Assembler. + /// + /// + /// The minimum size of the buffer to be used for FASM to return the + /// text to be assembled. + /// + /// + /// The base directory to search for the FASM DLL. + /// If not provided, the current directory and the executing assembly's directory will be searched. + /// + public Assembler(int textSize = 0x10000, int resultSize = 0x8000, string fasmDir = null) + { + // Attempt allocation of memory X times. + AllocateText(textSize, 3); + AllocateResult(resultSize, 3); - /// - /// Assembles the given mnemonics. - /// - /// The mnemonics to assemble, with each line being represented as a string in the array. - /// The maximum number of passes to perform when assembling data. - public byte[] Assemble(IEnumerable mnemonics, ushort passLimit = 100) - { - string mnemonicsString = String.Join(Environment.NewLine, mnemonics); - return Assemble(mnemonicsString); - } + IntPtr fasmDllHandle; - /// - /// Assembles the given mnemonics. - /// - /// The mnemonics to assemble; delimited by new line \n for each new instruction. - /// The maximum number of passes to perform when assembling data. - /// Your text to be assembled is too large to fit in the preallocated region for program text. - /// An error thrown by the native FASM compiler. - public byte[] Assemble(string mnemonics, ushort passLimit = 100) - { - // Convert Text & Append - byte[] mnemonicBytes = Encoding.ASCII.GetBytes(mnemonics + "\0"); + // Get path of FASM dll + string fasmDllPath = GetFasmDLLPath(fasmDir); + fasmDllHandle = LoadLibraryW(fasmDllPath); - if (mnemonicBytes.Length > _textAllocation.Size) - throw new FasmWrapperException($"Your supplied array of mnemonics to be assembled is too large ({mnemonicBytes.Length} > {_textAllocation.Size} bytes)." + - "Consider simplifying your code or creating a new Assembler with greater textSize."); + // Throw exception if dll not loaded. + if (fasmDllHandle == null) + throw new FasmWrapperException("Failed to load FASM dll. The FASM dll pointer from LoadLibraryW is null."); - lock (_lock) - { - Memory.Memory.Instance.WriteRaw(_textAllocation.BaseAddress, mnemonicBytes); + // Obtain delegates to FASM functions. + IntPtr assembleAddress = GetProcAddress(fasmDllHandle, "fasm_Assemble"); + IntPtr getVersionAddress = GetProcAddress(fasmDllHandle, "fasm_GetVersion"); + _assembleFunction = Marshal.GetDelegateForFunctionPointer(assembleAddress); + _getVersionFunction = Marshal.GetDelegateForFunctionPointer(getVersionAddress); + } - // Assemble and check result. - var result = _assembleFunction((IntPtr)(void*)_textAllocation.BaseAddress, (IntPtr)(void*)_resultAllocation.BaseAddress, (IntPtr)_resultAllocation.Size, passLimit, IntPtr.Zero); + /// + /// Destroys this instance of the class. + /// + ~Assembler() + { + Dispose(); + } - // As stated in FASMDLL.TXT, at the beginning of the block, the FASM_STATE structure will reside. - // It is defined in FASM.ASH. We read it here. - Memory.Memory.Instance.Read(_resultAllocation.BaseAddress, out FasmState state); + /// + /// Releases the allocated memory for the assembler. + /// + public void Dispose() + { + _bufferHelper.Free(_textAddress); + _bufferHelper.Free(_resultAddress); + GC.SuppressFinalize(this); + } - if (result == FasmResult.Ok) - { - byte[] assembledBytes = new byte[state.OutputLength]; - Marshal.Copy((IntPtr)state.OutputData, assembledBytes, 0, assembledBytes.Length); - return assembledBytes; - } - - // TODO: Make this exception more detailed in time with FASMX64's development. - /* For now, I still do not know if FASMX64 will ever plan to change the pointer size, - so for now, I will opt to not get the line details and/or other more "complex" info. */ + /// + /// Retrieves the version of the internally used FASM assembler DLL. + /// + /// + public Version GetVersion() + { + // Call the native function to get the version + int nativeVersion = _getVersionFunction(); - string[] originalMnemonics = mnemonics.Split(new[] { Environment.NewLine }, StringSplitOptions.None); - var lineHeader = state.GetLineHeader(); + // Create and return a managed version object + return new Version(nativeVersion & 0xff, (nativeVersion >> 16) & 0xff); + } - throw new FasmException(state.ErrorCode, state.Condition, lineHeader.LineNumber, originalMnemonics); + /// + /// Assembles a file at a given path. + /// + /// The path of the file to be assembled. + /// The assembled file. + public byte[] AssembleFile(string filePath) + { + return Assemble(File.ReadAllLines(filePath)); } - } - /// - /// Retrieves the path of the FASM dll to load. - /// - private string GetFasmDLLPath(string fasmDir = null) - { - const string FASM86DLL = "FASM.dll"; - const string FASM64DLL = "FASMX64.dll"; + /// + /// Assembles the given mnemonics. + /// + /// The mnemonics to assemble, with each line being represented as a string in the array. + /// The maximum number of passes to perform when assembling data. + public byte[] Assemble(IEnumerable mnemonics, ushort passLimit = 100) + { + string mnemonicsString = String.Join(Environment.NewLine, mnemonics); + return Assemble(mnemonicsString); + } - // Prioritize the explictly provided directory - if (!string.IsNullOrEmpty(fasmDir)) + /// + /// Assembles the given mnemonics. + /// + /// The mnemonics to assemble; delimited by new line \n for each new instruction. + /// The maximum number of passes to perform when assembling data. + /// Your text to be assembled is too large to fit in the preallocated region for program text. + /// An error thrown by the native FASM compiler. + public byte[] Assemble(string mnemonics, ushort passLimit = 100) { - string fasmPath = Path.Combine(fasmDir, IntPtr.Size == 4 ? FASM86DLL : FASM64DLL); - if (File.Exists(fasmPath)) - return fasmPath; - else - throw new FasmWrapperException($"Appropriate FASM DLL for X86/64 has not been found in the provided directory: {fasmDir}"); + // Convert Text & Append + byte[] mnemonicBytes = Encoding.ASCII.GetBytes(mnemonics + "\0"); + + if (mnemonicBytes.Length > _textSize) + throw new FasmWrapperException($"Your supplied array of mnemonics to be assembled is too large ({mnemonicBytes.Length} > {_textSize} bytes)." + + "Consider simplifying your code or creating a new Assembler with greater textSize."); + + lock (_lock) + { + _processMemory.WriteRaw(_textAddress, mnemonicBytes); + + // Assemble and check result. + var result = _assembleFunction((IntPtr)(void*)_textAddress, (IntPtr)(void*)_resultAddress, (IntPtr)_resultSize, passLimit, IntPtr.Zero); + + // As stated in FASMDLL.TXT, at the beginning of the block, the FASM_STATE structure will reside. + // It is defined in FASM.ASH. We read it here. + + FasmState state; + _processMemory.Read(_resultAddress, out state); + + if (result == FasmResult.Ok) + { + byte[] assembledBytes = new byte[state.OutputLength]; + Marshal.Copy((IntPtr)state.OutputData, assembledBytes, 0, assembledBytes.Length); + return assembledBytes; + } + + // TODO: Make this exception more detailed in time with FASMX64's development. + /* For now, I still do not know if FASMX64 will ever plan to change the pointer size, + so for now, I will opt to not get the line details and/or other more "complex" info. */ + + string[] originalMnemonics = mnemonics.Split(new[] { Environment.NewLine }, StringSplitOptions.None); + var lineHeader = state.GetLineHeader(); + + throw new FasmException(state.ErrorCode, state.Condition, lineHeader.LineNumber, originalMnemonics); + } } - // Check current directory. - if (IntPtr.Size == 4 && File.Exists(FASM86DLL)) - return FASM86DLL; - else if (IntPtr.Size == 8 && File.Exists(FASM64DLL)) - return FASM64DLL; + /// + /// Retrieves the path of the FASM dll to load. + /// + private string GetFasmDLLPath(string fasmDir = null) + { + const string FASM86DLL = "FASM.dll"; + const string FASM64DLL = "FASMX64.dll"; - // Check DLL Directory - string assemblyDirectory = GetExecutingDLLDirectory(); - string asmDirectoryFasm86 = Path.Combine(assemblyDirectory, FASM86DLL); - string asmDirectoryFasm64 = Path.Combine(assemblyDirectory, FASM64DLL); + // Prioritize the explictly provided directory + if (!string.IsNullOrEmpty(fasmDir)) + { + string fasmPath = Path.Combine(fasmDir, IntPtr.Size == 4 ? FASM86DLL : FASM64DLL); + if (File.Exists(fasmPath)) + return fasmPath; + else + throw new FasmWrapperException($"Appropriate FASM DLL for X86/64 has not been found in the provided directory: {fasmDir}"); + } - if (IntPtr.Size == 4 && File.Exists(asmDirectoryFasm86)) - return asmDirectoryFasm86; - else if (IntPtr.Size == 8 && File.Exists(asmDirectoryFasm64)) - return asmDirectoryFasm64; + // Check current directory. + if (IntPtr.Size == 4 && File.Exists(FASM86DLL)) + return FASM86DLL; + else if (IntPtr.Size == 8 && File.Exists(FASM64DLL)) + return FASM64DLL; - throw new FasmWrapperException("Appropriate FASM DLL for X86/64 has not been found in either current or library directory."); - } + // Check DLL Directory + string assemblyDirectory = GetExecutingDLLDirectory(); + string asmDirectoryFasm86 = Path.Combine(assemblyDirectory, FASM86DLL); + string asmDirectoryFasm64 = Path.Combine(assemblyDirectory, FASM64DLL); - /// - /// Gets the directory of the currently executing assembly. - /// - private string GetExecutingDLLDirectory() => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + if (IntPtr.Size == 4 && File.Exists(asmDirectoryFasm86)) + return asmDirectoryFasm86; + else if (IntPtr.Size == 8 && File.Exists(asmDirectoryFasm64)) + return asmDirectoryFasm64; - /// - /// Attempts to allocate the memory to store the text to be supplied to FASM assembler. - /// - private void AllocateText(int textSize) - { - _textAllocation = Buffers.AllocatePrivateMemory(new BufferAllocatorSettings() + throw new FasmWrapperException("Appropriate FASM DLL for X86/64 has not been found in either current or library directory."); + } + + /// + /// Gets the directory of the currently executing assembly. + /// + private string GetExecutingDLLDirectory() => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + + /// + /// Attempts to allocate the memory to store the text to be supplied to FASM assembler. + /// + private void AllocateText(int textSize, int retryCount) { - Size = (uint)textSize, - MinAddress = 1, - MaxAddress = Int32.MaxValue - }); - } + var allocationProperties = _bufferHelper.Allocate(textSize, 1, Int32.MaxValue, retryCount); + _textAddress = allocationProperties.MemoryAddress; + _textSize = allocationProperties.Size; - /// - /// Attempts to allocate the memory to store the result received from FASM assembler. - /// - private void AllocateResult(int resultSize) - { - _resultAllocation = Buffers.AllocatePrivateMemory(new BufferAllocatorSettings() + if (_textAddress == 0) + throw new FasmWrapperException("Failed to allocate text memory for Assembler."); + } + + /// + /// Attempts to allocate the memory to store the result received from FASM assembler. + /// + private void AllocateResult(int resultSize, int retryCount) { - Size = (uint)resultSize, - MinAddress = 1, - MaxAddress = Int32.MaxValue - }); + var allocationProperties = _bufferHelper.Allocate(resultSize, 1, Int32.MaxValue, retryCount); + _resultAddress = allocationProperties.MemoryAddress; + _resultSize = allocationProperties.Size; + + if (_resultAddress == 0) + throw new FasmWrapperException("Failed to allocate result memory for Assembler."); + } + } } \ No newline at end of file diff --git a/Source/Reloaded.Assembler/Reloaded.Assembler.csproj b/Source/Reloaded.Assembler/Reloaded.Assembler.csproj index e6ca945..73dfc85 100644 --- a/Source/Reloaded.Assembler/Reloaded.Assembler.csproj +++ b/Source/Reloaded.Assembler/Reloaded.Assembler.csproj @@ -20,7 +20,7 @@ https://github.com/Aether-Tools/Reloaded.Assembler git https://github.com/Aether-Tools/Reloaded.Assembler - 1.0.16-anamv2 + 1.0.14-anamv1 LICENSE Icon.png @@ -44,6 +44,6 @@ - +