/// <summary>
 ///     Create a Deferred Instruction Enumerable.
 /// </summary>
 /// <param name="disassembler">
 ///     The disassembler to use. 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="offset">
 ///     An offset to start disassembling from. A 0 indicates disassembly should start at the first byte.
 ///     Should be less than the length of the collection of bytes to disassemble.
 /// </param>
 /// <param name="startingAddress">
 ///     The address of the first instruction in the collection of bytes to disassemble.
 /// </param>
 public DeferredInstructionEnumerable(CapstoneDisassembler <TArchitectureInstruction, TArchitectureRegister, TArchitectureGroup, TArchitectureDetail> disassembler, byte[] code, int offset, long startingAddress)
 {
     this._disassembler    = disassembler;
     this._code            = code;
     this._offset          = offset;
     this._startingAddress = startingAddress;
 }
            /// <summary>
            ///     Created a Deferred Instruction Enumerator.
            /// </summary>
            /// <param name="disassembler">
            ///     The disassembler to use. 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="offset">
            ///     An offset to start disassembling from. A 0 indicates disassembly should start at the first byte.
            ///     Should be less than the length of the collection of bytes to disassemble.
            /// </param>
            /// <param name="startingAddress">
            ///     The address of the first instruction in the collection of bytes to disassemble.
            /// </param>
            public DeferredInstructionEnumerator(CapstoneDisassembler <TArchitectureInstruction, TArchitectureRegister, TArchitectureGroup, TArchitectureDetail> disassembler, byte[] code, int offset, long startingAddress)
            {
                this._disassembler   = disassembler;
                this._pinnedCode     = GCHandle.Alloc(code, GCHandleType.Pinned);
                this._currentOffset  = offset;
                this._currentAddress = (ulong)startingAddress;

                this._codeSize = code.Length;
                this._disposed = false;
            }
        /// <summary>
        ///     Build an Instruction.
        /// </summary>
        /// <param name="disassembler">
        ///     A disassembler.
        /// </param>
        /// <param name="hInstruction">
        ///     An instruction handle.
        /// </param>
        internal virtual void Build(CapstoneDisassembler disassembler, NativeInstructionHandle hInstruction)
        {
            // ...
            //
            // Throws an exception if the operation fails.
            var nativeInstruction = NativeCapstone.GetInstruction(hInstruction);

            this.Address = nativeInstruction.Address;
            this.DisassembleArchitecture = disassembler.DisassembleArchitecture;
            this.DisassembleMode         = this.CreateDisassembleMode(disassembler.NativeDisassembleMode);
            this.Id            = this.CreateId(nativeInstruction.Id);
            this.IsSkippedData = disassembler.EnableSkipDataMode && !(nativeInstruction.Id > 0);
            this.Mnemonic      = !CapstoneDisassembler.IsDietModeEnabled ? nativeInstruction.Mnemonic : null;
            this.Operand       = !CapstoneDisassembler.IsDietModeEnabled ? nativeInstruction.Operand : null;
            // ...
            //
            // ...
            SetBytes(this, ref nativeInstruction);
            SetDetails(this, disassembler, hInstruction, ref nativeInstruction);

            // <summary>
            //      Set Instruction's Machine Bytes.
            // </summary>
            void SetBytes(InstructionBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TId, TRegister, TRegisterId> @this, ref NativeInstruction cNativeInstruction)
            {
                @this.Bytes = new byte[0];
                if (cNativeInstruction.Id >= 0)
                {
                    @this.Bytes = new byte[cNativeInstruction.Size];
                    for (var cI = 0; cI < @this.Bytes.Length; cI++)
                    {
                        @this.Bytes[cI] = cNativeInstruction.Bytes[cI];
                    }
                }
            }

            // <summary>
            //      Set Instruction's Details.
            // </summary>
            void SetDetails(InstructionBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TId, TRegister, TRegisterId> @this, CapstoneDisassembler cDisassembler, NativeInstructionHandle cHInstruction, ref NativeInstruction cNativeInstruction)
            {
                var cHasDetails = cNativeInstruction.Details != IntPtr.Zero;
                var cIsInstructionDetailsEnabled = cDisassembler.EnableInstructionDetails;

                @this.Details = null;
                if (cHasDetails && cIsInstructionDetailsEnabled && cNativeInstruction.Id > 0)
                {
                    @this.Details = @this.CreateDetails(cDisassembler, cHInstruction);
                }
            }
        }
 /// <summary>
 ///     Create Instruction's Details.
 /// </summary>
 /// <param name="disassembler">
 ///     A disassembler.
 /// </param>
 /// <param name="hInstruction">
 ///     An instruction handle.
 /// </param>
 /// <returns>
 ///     The instruction's details.
 /// </returns>
 private protected abstract TDetail CreateDetails(CapstoneDisassembler disassembler, NativeInstructionHandle hInstruction);
Exemple #5
0
        /// <summary>
        ///     Build an Instruction Detail.
        /// </summary>
        /// <param name="disassembler">
        ///     A disassembler.
        /// </param>
        /// <param name="hInstruction">
        ///     An instruction handle.
        /// </param>
        internal virtual void Build(CapstoneDisassembler disassembler, NativeInstructionHandle hInstruction)
        {
            // ...
            //
            // Throws an exception if the operation fails.
            var nativeInstructionDetail = NativeCapstone.GetInstructionDetail(hInstruction).GetValueOrDefault();

            this.DisassembleArchitecture = disassembler.DisassembleArchitecture;
            this.DisassembleMode         = this.CreateDisassembleMode(disassembler.NativeDisassembleMode);
            // ...
            //
            // ...
            SetAccessedRegisters(this, disassembler, hInstruction);
            SetGroups(this, disassembler, ref nativeInstructionDetail);
            SetImplicitlyReadRegisters(this, disassembler, ref nativeInstructionDetail);
            SetImplicitlyWrittenRegisters(this, disassembler, ref nativeInstructionDetail);

            // <summary>
            //      Set Accessed Registers.
            // </summary>
            void SetAccessedRegisters(InstructionDetailBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TInstructionId, TRegister, TRegisterId> @this, CapstoneDisassembler cDisassembler, NativeInstructionHandle cHInstruction)
            {
                @this.AllReadRegisters    = new TRegister[0];
                @this.AllWrittenRegisters = new TRegister[0];
                if (!CapstoneDisassembler.IsDietModeEnabled)
                {
                    var isArchSupported = cDisassembler.DisassembleArchitecture != DisassembleArchitecture.M68K;
                    isArchSupported = isArchSupported && cDisassembler.DisassembleArchitecture != DisassembleArchitecture.Mips;
                    isArchSupported = isArchSupported && cDisassembler.DisassembleArchitecture != DisassembleArchitecture.PowerPc;
                    isArchSupported = isArchSupported && cDisassembler.DisassembleArchitecture != DisassembleArchitecture.XCore;
                    if (isArchSupported)
                    {
                        // ...
                        //
                        // Throws an exception if the operation fails.
                        var cAccessedRegisters = NativeCapstone.GetAccessedRegisters(cDisassembler.Handle, cHInstruction);

                        @this.AllReadRegisters = new TRegister[cAccessedRegisters.Item1.Length];
                        for (var cI = 0; cI < @this.AllReadRegisters.Length; cI++)
                        {
                            var cExplicitlyReadRegister = cAccessedRegisters.Item1[cI];
                            @this.AllReadRegisters[cI] = @this.CreateRegister(cDisassembler, cExplicitlyReadRegister);
                        }

                        @this.AllWrittenRegisters = new TRegister[cAccessedRegisters.Item2.Length];
                        for (var cI = 0; cI < @this.AllWrittenRegisters.Length; cI++)
                        {
                            var cExplicitlyWrittenRegister = cAccessedRegisters.Item2[cI];
                            @this.AllWrittenRegisters[cI] = @this.CreateRegister(cDisassembler, cExplicitlyWrittenRegister);
                        }
                    }
                }
            }

            // <summary>
            //      Set Instruction's Groups.
            // </summary>
            void SetGroups(InstructionDetailBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TInstructionId, TRegister, TRegisterId> @this, CapstoneDisassembler cDisassembler, ref NativeInstructionDetail cNativeInstructionDetail)
            {
                @this.Groups = new TGroup[cNativeInstructionDetail.GroupCount];
                if (!CapstoneDisassembler.IsDietModeEnabled)
                {
                    for (var cI = 0; cI < @this.Groups.Length; cI++)
                    {
                        var cGroup = cNativeInstructionDetail.Groups[cI];
                        @this.Groups[cI] = @this.CreateInstructionGroup(cDisassembler, cGroup);
                    }
                }
            }

            // <summary>
            //      Set Implicitly Read Registers.
            // </summary>
            void SetImplicitlyReadRegisters(InstructionDetailBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TInstructionId, TRegister, TRegisterId> @this, CapstoneDisassembler cDisassembler, ref NativeInstructionDetail cNativeInstructionDetail)
            {
                @this.ImplicitlyReadRegisters = new TRegister[cNativeInstructionDetail.ImplicitlyReadRegisterCount];
                if (!CapstoneDisassembler.IsDietModeEnabled)
                {
                    for (var cI = 0; cI < @this.ImplicitlyReadRegisters.Length; cI++)
                    {
                        var cImplicitlyReadRegister = cNativeInstructionDetail.ImplicitlyReadRegisters[cI];
                        @this.ImplicitlyReadRegisters[cI] = @this.CreateRegister(cDisassembler, cImplicitlyReadRegister);
                    }
                }
            }

            // <summary>
            //      Set Implicitly Written Registers.
            // </summary>
            void SetImplicitlyWrittenRegisters(InstructionDetailBuilder <TDetail, TDisassembleMode, TGroup, TGroupId, TInstruction, TInstructionId, TRegister, TRegisterId> @this, CapstoneDisassembler cDisassembler, ref NativeInstructionDetail cNativeInstructionDetail)
            {
                @this.ImplicitlyWrittenRegisters = new TRegister[cNativeInstructionDetail.ImplicitlyWrittenRegisterCount];
                if (!CapstoneDisassembler.IsDietModeEnabled)
                {
                    for (var cI = 0; cI < @this.ImplicitlyWrittenRegisters.Length; cI++)
                    {
                        var cImplicitlyWrittenRegister = cNativeInstructionDetail.ImplicitlyWrittenRegisters[cI];
                        @this.ImplicitlyWrittenRegisters[cI] = @this.CreateRegister(cDisassembler, cImplicitlyWrittenRegister);
                    }
                }
            }
        }
Exemple #6
0
 /// <summary>
 ///     Create a Register.
 /// </summary>
 /// <param name="disassembler">
 ///     A disassembler.
 /// </param>
 /// <param name="registerId">
 ///     A register's unique identifier.
 /// </param>
 /// <returns>
 ///     A register.
 /// </returns>
 private protected abstract TRegister CreateRegister(CapstoneDisassembler disassembler, short registerId);
Exemple #7
0
 /// <summary>
 ///     Create an Instruction Group.
 /// </summary>
 /// <param name="disassembler">
 ///     A disassembler.
 /// </param>
 /// <param name="instructionGroupId">
 ///     An instruction group's unique identifier.
 /// </param>
 /// <returns>
 ///     An instruction group.
 /// </returns>
 private protected abstract TGroup CreateInstructionGroup(CapstoneDisassembler disassembler, byte instructionGroupId);