/// <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(); } }
/// <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(); } }
/// <summary> /// Get an Instruction's Details. /// </summary> /// <typeparam name="TInstructionDetail"> /// The type of the instruction's details. /// </typeparam> /// <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 TInstructionDetail?GetInstructionDetail <TInstructionDetail>(NativeInstructionHandle hInstruction) where TInstructionDetail : struct { 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); TInstructionDetail?instructionDetail = null; if (ppInstructionDetail != IntPtr.Zero) { // ... // // Fourth, we calculate the memory address of the instruction's architecture specific details, // which is always relative to the memory address of the instruction's details. var pArchInstructionDetail = ppInstructionDetail + NativeCapstone.MagicInstructionArchitectureDetailsFieldOffset; instructionDetail = (TInstructionDetail)Marshal.PtrToStructure(pArchInstructionDetail, typeof(TInstructionDetail)); } return(instructionDetail); } finally { hInstruction.DangerousRelease(); } }