/// <summary>
            ///     Get Next Instruction.
            /// </summary>
            /// <returns>
            ///     A boolean true if an instruction is returned. A boolean false otherwise.
            /// </returns>
            /// <exception cref="System.ObjectDisposedException">
            ///     Thrown if the enumerator is disposed.
            /// </exception>
            public bool MoveNext()
            {
                this.CheckDisposed();

                var pCode         = this._pinnedCode.AddrOfPinnedObject() + this._currentOffset;
                var pCount        = (UIntPtr)1;
                var pInstructions = IntPtr.Zero;
                var pSize         = (UIntPtr)this._codeSize - this._currentOffset;

                // Disassemble Binary Code.
                //
                // ...
                var pResultCode = CapstoneImport.Disassemble((UIntPtr)(ulong)(long)_disassembler.Handle.DangerousGetHandle(),
                                                             pCode, pSize, this._currentAddress, pCount,
                                                             ref pInstructions);

                var iResultCode        = (int)pResultCode;
                var nativeInstructions = MarshalExtension.PtrToStructure <NativeInstruction>(pInstructions, iResultCode);

                if (nativeInstructions == null || nativeInstructions.Length == 0)
                {
                    return(false);
                }

                var instruction = nativeInstructions[0];

                this._currentInstruction = this._disassembler.CreateInstruction(instruction);
                this._currentAddress    += (ulong)this._currentInstruction.Bytes.Length;
                this._currentOffset     += this._currentInstruction.Bytes.Length;

                return(true);
            }
Exemplo n.º 2
0
        /// <summary>
        ///     Get an Instruction's Details.
        /// </summary>
        /// <param name="hInstruction">
        ///     An instruction handle.
        /// </param>
        /// <returns>
        ///     The instruction's details. A null reference indicates the instruction was disassembled without
        ///     details.
        /// </returns>
        internal static NativeInstructionDetail?GetInstructionDetail(NativeInstructionHandle hInstruction)
        {
            var pInstruction = hInstruction.DangerousAddRefAndGetHandle();

            try {
                // ...
                //
                // First, we calculate the memory address of the <c>NativeInstruction.Details</c> field, which is
                // always relative to the memory address of its defining <c>NativeInstruction</c> structure. This is
                // NOT the actual memory address of the instruction's details.
                var instructionDetailOffset = Marshal.OffsetOf(typeof(NativeInstruction), nameof(NativeInstruction.Details));
                var pInstructionDetail      = (IntPtr)((long)pInstruction + (long)instructionDetailOffset);

                // ...
                //
                // Second, we read the value of the <c>NativeInstruction.Details</c> field, which IS the actual memory
                // address of the instruction's details. If the value is not equal to <c>IntPtr.Zero</c>, that indicates
                // the instruction was disassembled with details.
                var ppInstructionDetail = Marshal.ReadIntPtr(pInstructionDetail);
                NativeInstructionDetail?instructionDetail = null;
                if (ppInstructionDetail != IntPtr.Zero)
                {
                    instructionDetail = MarshalExtension.PtrToStructure <NativeInstructionDetail>(ppInstructionDetail);
                }

                return(instructionDetail);
            }
            finally {
                hInstruction.DangerousRelease();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///     Set Disassembler Instruction Mnemonic Option.
        /// </summary>
        /// <param name="hDisassembler">
        ///     A disassembler handle.
        /// </param>
        /// <param name="optionValue">
        ///     A value to set the instruction mnemonic option to.
        /// </param>
        /// <exception cref="Gee.External.Capstone.CapstoneException">
        ///     Thrown if the instruction mnemonic option could not be set.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        ///     Thrown if the disassembler handle is invalid.
        /// </exception>
        /// <exception cref="System.ObjectDisposedException">
        ///     Thrown if the disassembler handle is disposed.
        /// </exception>
        internal static void SetInstructionMnemonicOption(NativeDisassemblerHandle hDisassembler, ref NativeInstructionMnemonicOptionValue optionValue)
        {
            var pOptionValue = IntPtr.Zero;

            try {
                pOptionValue = MarshalExtension.AllocHGlobal <NativeInstructionMnemonicOptionValue>();
                Marshal.StructureToPtr(optionValue, pOptionValue, false);

                // ...
                //
                // Throws an exception if the operation fails.
                const NativeDisassemblerOptionType optionType = NativeDisassemblerOptionType.SetMnemonic;
                var resultCode = NativeCapstoneImport.SetDisassemblerOption(hDisassembler, optionType, pOptionValue);
                if (resultCode != NativeCapstoneResultCode.Ok)
                {
                    if (resultCode == NativeCapstoneResultCode.InvalidHandle2)
                    {
                        var detailMessage = $"A disassembler handle ({nameof(hDisassembler)}) is invalid.";
                        throw new ArgumentException(detailMessage, nameof(hDisassembler));
                    }
                    else
                    {
                        var detailMessage = $"A disassembler option ({optionType}) could not be set.";
                        throw new CapstoneException(detailMessage);
                    }
                }
            }
            finally {
                if (pOptionValue != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pOptionValue);
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Allocate Memory For a Structure.
        /// </summary>
        /// <param name="size">
        ///     The collection's size.
        /// </param>
        /// <typeparam name="T">
        ///     The structure's type.
        /// </typeparam>
        /// <returns>
        ///     A pointer to the allocated memory.
        /// </returns>
        internal static IntPtr AllocHGlobal <T>(int size)
        {
            var nType = MarshalExtension.SizeOf <T>() * size;
            var pType = Marshal.AllocHGlobal(nType);

            return(pType);
        }
Exemplo n.º 5
0
        /// <summary>
        ///     Get an Instruction's Architecture Specific Details.
        /// </summary>
        /// <typeparam name="TInstructionDetails">
        ///     The type of the instruction's architecture specific details.
        /// </typeparam>
        /// <param name="instruction">
        ///     An instruction.
        /// </param>
        /// <returns>
        ///     The instruction's architecture specific details. A null reference indicates the instruction was
        ///     disassembled without its details.
        /// </returns>
        internal static TInstructionDetails?GetInstructionDetail <TInstructionDetails>(ref NativeInstruction instruction) where TInstructionDetails : struct
        {
            TInstructionDetails?instructionDetails = null;

            if (instruction.Details != IntPtr.Zero)
            {
                // ...
                //
                // Throws an exception if the operation fails.
                var pInstructionDetails = instruction.Details + NativeCapstone.MagicInstructionArchitectureDetailsFieldOffset;
                instructionDetails = MarshalExtension.PtrToStructure <TInstructionDetails>(pInstructionDetails);
            }

            return(instructionDetails);
        }
Exemplo n.º 6
0
        /// <summary>
        ///     Get an Instruction's Details.
        /// </summary>
        /// <param name="instruction">
        ///     An instruction.
        /// </param>
        /// <returns>
        ///     The instruction's details. A null reference indicates the instruction was disassembled without
        ///     details.
        /// </returns>
        internal static NativeInstructionDetail?GetInstructionDetail(ref NativeInstruction instruction)
        {
            NativeInstructionDetail?instructionDetails = null;

            if (instruction.Details != IntPtr.Zero)
            {
                // ...
                //
                // Throws an exception if the operation fails.
                var pInstructionDetails = instruction.Details;
                instructionDetails = MarshalExtension.PtrToStructure <NativeInstructionDetail>(pInstructionDetails);
            }

            return(instructionDetails);
        }
Exemplo n.º 7
0
        /// <summary>
        ///     Get an Instruction.
        /// </summary>
        /// <param name="hInstruction">
        ///     An instruction handle.
        /// </param>
        /// <returns>
        ///     An instruction.
        /// </returns>
        internal static NativeInstruction GetInstruction(NativeInstructionHandle hInstruction)
        {
            var pInstruction = hInstruction.DangerousAddRefAndGetHandle();

            try {
                // ...
                //
                // Throws an exception if the operation fails.
                var instruction = MarshalExtension.PtrToStructure <NativeInstruction>(pInstruction);
                return(instruction);
            }
            finally {
                hInstruction.DangerousRelease();
            }
        }
Exemplo n.º 8
0
        /// <summary>
        ///     Marshal a Pointer to a Collection of Structures.
        /// </summary>
        /// <typeparam name="T">
        ///     The collection's type.
        /// </typeparam>
        /// <param name="p">
        ///     A pointer to a collection. The pointer should be initialized to the collection's starting address.
        /// </param>
        /// <param name="size">
        ///     The collection's size.
        /// </param>
        /// <returns>
        ///     The destination collection.
        /// </returns>
        internal static T[] PtrToStructure <T>(IntPtr p, int size)
        {
            var array = new T[size];
            var index = p;

            for (var i = 0; i < size; i++)
            {
                var element = MarshalExtension.PtrToStructure <T>(index);
                array[i] = element;

                index += Marshal.SizeOf(typeof(T));
            }

            return(array);
        }
Exemplo n.º 9
0
        internal static void SetSkipDataOption(NativeDisassemblerHandle hDisassembler, ref NativeSkipDataOptionValue optionValue)
        {
            var pOptionValue = IntPtr.Zero;

            try {
                pOptionValue = MarshalExtension.AllocHGlobal <NativeSkipDataOptionValue>();
                Marshal.StructureToPtr(optionValue, pOptionValue, false);

                // ...
                //
                // Throws an exception if the operation fails.
                const NativeDisassemblerOptionType optionType = NativeDisassemblerOptionType.SetSkipDataConfig;
                var resultCode = NativeCapstoneImport.SetDisassemblerOption(hDisassembler, optionType, pOptionValue);
            }
            finally {
                if (pOptionValue != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pOptionValue);
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        ///     Disassemble Binary Code.
        /// </summary>
        /// <param name="handle">
        ///     A Capstone handle. Should not be a null reference.
        /// </param>
        /// <param name="code">
        ///     A collection of bytes representing the binary code to disassemble. Should not be a null reference.
        /// </param>
        /// <param name="count">
        ///     The number of instructions to disassemble. A 0 indicates all instructions should be disassembled.
        /// </param>
        /// <param name="startingAddress">
        ///     The address of the first instruction in the collection of bytes to disassemble.
        /// </param>
        /// <returns>
        ///     A native instruction handle.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        ///     Thrown if the binary code could not be disassembled.
        /// </exception>
        public static SafeNativeInstructionHandle Disassemble(SafeCapstoneHandle handle, byte[] code, int count, ulong startingAddress)
        {
            // Copy Code to Unmanaged Memory.
            //
            // ...
            var pCode = MarshalExtension.AllocHGlobal <byte>(code.Length);

            Marshal.Copy(code, 0, pCode, code.Length);

            var pCount        = (UIntPtr)count;
            var pHandle       = handle.DangerousGetHandle();
            var pInstructions = IntPtr.Zero;
            var pSize         = (UIntPtr)code.Length;
            // var uStartingAddress = (ulong) startingAddress;

            // Disassemble Binary Code.
            //
            // ...
            var pResultCode = CapstoneImport.Disassemble(unchecked ((UIntPtr)(ulong)(ulong)handle.DangerousGetHandle()), pCode, pSize,
                                                         startingAddress, pCount, ref pInstructions);

            if (pResultCode == UIntPtr.Zero)
            {
                throw new InvalidOperationException("Unable to disassemble binary code.");
            }

            var iResultCode  = (int)pResultCode;
            var instructions = MarshalExtension.PtrToStructure <NativeInstruction>(pInstructions, iResultCode);

            // Free Unmanaged Memory.
            //
            // Avoid a memory leak.
            Marshal.FreeHGlobal(pCode);

            var instructionHandle = new SafeNativeInstructionHandle(instructions, pInstructions, pResultCode);

            return(instructionHandle);
        }