/// <summary> /// Releases the engine. /// </summary> public void Dispose() { IntPtr currentEngine = Interlocked.Exchange(ref engine, IntPtr.Zero); if (currentEngine != IntPtr.Zero) { NativeInterop.Close(currentEngine); } }
/// <summary> /// Returns the string associated with a given error code. /// </summary> public static string ErrorToString(KeystoneError code) { IntPtr error = NativeInterop.ErrorToString(code); if (error != IntPtr.Zero) { return(Marshal.PtrToStringAnsi(error)); } return(string.Empty); }
/// <summary> /// Constructs the engine with a given architecture and a given mode. /// </summary> /// <param name="architecture">The target architecture.</param> /// <param name="mode">The mode, i.e. endianness, word size etc.</param> /// <remarks> /// Some architectures are not supported. /// Check with <see cref="IsArchitectureSupported(Architecture)"/> if the engine /// supports the target architecture. /// </remarks> public Engine(Architecture architecture, Mode mode) { internalImpl = ResolveSymbolInternal; var result = NativeInterop.Open(architecture, (int)mode, ref engine); if (result != KeystoneError.KS_ERR_OK) { throw new KeystoneException("Error while initializing keystone", result); } }
/// <summary> /// Sets an option in the engine. /// </summary> /// <param name="type">Type of the option.</param> /// <param name="value">Value it the option.</param> /// <returns>Whether the option was correctly set.</returns> /// <exception cref="KeystoneException">An error encountered when setting the option.</exception> public bool SetOption(OptionType type, uint value) { var result = NativeInterop.SetOption(engine, (int)type, (IntPtr)value); if (result != KeystoneError.KS_ERR_OK) { if (ThrowOnError) { throw new KeystoneException("Error while setting option", result); } return(false); } return(true); }
/// <summary> /// Encodes the given statement(s) into the given buffer. /// </summary> /// <param name="toEncode">String that contains the statements to encode.</param> /// <param name="address">Address of the first instruction to encode.</param> /// <param name="buffer">Buffer into which the data shall be written.</param> /// <param name="index">Index into the buffer after which the data shall be written.</param> /// <param name="statementCount">Number of statements found and encoded.</param> /// <returns>Size of the data writen by the operation., or <c>0</c> if it failed and <see cref="ThrowOnError" /> is <c>false</c>.</returns> /// <exception cref="ArgumentNullException">A null argument was given.</exception> /// <exception cref="ArgumentOutOfRangeException">The provided index is invalid.</exception> /// <exception cref="KeystoneException">An error encountered when encoding the instructions.</exception> public int Assemble(string toEncode, ulong address, byte[] buffer, int index, out int statementCount) { if (toEncode == null) { throw new ArgumentNullException(nameof(toEncode)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (index < 0 || index >= buffer.Length) { throw new ArgumentOutOfRangeException(nameof(buffer)); } int result = NativeInterop.Assemble(engine, toEncode, address, out IntPtr encoding, out uint size_, out uint statementCount_); int size = (int)size_; statementCount = (int)statementCount_; if (result != 0) { if (ThrowOnError) { throw new KeystoneException("Error while assembling instructions", GetLastKeystoneError()); } return(0); } Marshal.Copy(encoding, buffer, index, size); NativeInterop.Free(encoding); return(size); }
/// <summary> /// Encodes the given statement(s). /// </summary> /// <param name="toEncode">String that contains the statements to encode.</param> /// <param name="address">Address of the first instruction to encode.</param> /// <param name="size">Size of the buffer produced by the operation.</param> /// <param name="statementCount">Number of statements found and encoded.</param> /// <returns>Result of the operation, or <c>null</c> if it failed and <see cref="ThrowOnError" /> is <c>false</c>.</returns> /// <exception cref="ArgumentNullException">A null argument was given.</exception> /// <exception cref="KeystoneException">An error encountered when encoding the instructions.</exception> public byte[] Assemble(string toEncode, ulong address, out int size, out int statementCount) { if (toEncode == null) { throw new ArgumentNullException(nameof(toEncode)); } int result = NativeInterop.Assemble(engine, toEncode, address, out IntPtr encoding, out uint size_, out uint statementCount_); if (result != 0) { if (ThrowOnError) { throw new KeystoneException("Error while assembling instructions", GetLastKeystoneError()); } size = statementCount = 0; return(null); } size = (int)size_; statementCount = (int)statementCount_; byte[] buffer = new byte[size]; Marshal.Copy(encoding, buffer, 0, size); NativeInterop.Free(encoding); return(buffer); }
/// <summary> /// Gets the version of the engine. /// </summary> /// <param name="major">Major version number.</param> /// <param name="minor">Minor version number.</param> /// <returns>Unique identifier for this version.</returns> public static uint GetKeystoneVersion(ref uint major, ref uint minor) { return(NativeInterop.Version(ref major, ref minor)); }
/// <summary> /// Checks if the given architecture is supported. /// </summary> public static bool IsArchitectureSupported(Architecture architecture) { return(NativeInterop.IsArchitectureSupported(architecture)); }
/// <summary> /// Gets the last error for this instance. /// </summary> /// <returns>The last error code.</returns> /// <remarks> /// It might not retain its old error once accessed. /// </remarks> public KeystoneError GetLastKeystoneError() { return(NativeInterop.GetLastKeystoneError(engine)); }