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 @@
-
+