/// <summary>Provides an enumerator that will enumerate <see cref="NativeInstruction"/> /// instances marshaled back from a call to cs_disasm.</summary> /// <param name="pNativeArray">A pointer to the native collection. The pointer /// should be initialized to the collection's starting address.</param> /// <param name="codeSize">The collection's codeSize.</param> /// <returns>An enumerable object.</returns> /// <remarks>CAUTION : Make sure not to release native memory until you are /// done with the enumerator.</remarks> private IEnumerable <NativeInstruction> EnumerateNativeInstructions(IntPtr pNativeArray, int size) { for (int index = 0; index < size; index++) { yield return(NativeInstruction.Create(this, ref pNativeArray)); } yield break; }
/// <summary>Iteratively disassemble source code.</summary> /// <param name="callback">A delegate that will be invoked on each disassembled /// instruction.</param> public void Disassemble(byte[] code, IterativeDisassemblyDelegate callback) { bool shouldContinue = true; ulong address = DefaultStartAddress; int totalSize = 0; IntPtr nativeCode = IntPtr.Zero; try { IntPtr nativeInstruction = IntPtr.Zero; using (SafeNativeInstructionHandle hInstruction = CapstoneImport.AllocateInstruction(this)) { nativeInstruction = hInstruction.DangerousGetHandle(); // Transfer the managed byte array into a native buffer. nativeCode = Marshal.AllocCoTaskMem(code.Length); Marshal.Copy(code, 0, nativeCode, code.Length); IntPtr remainingSize = (IntPtr)code.Length; do { if (hInstruction.IsClosed) { throw new ApplicationException(); } ulong instructionStartAddress = address; shouldContinue |= CapstoneImport.DisassembleIteratively(this, ref nativeCode, ref remainingSize, ref address, hInstruction); if (shouldContinue) { int instructionSize = (int)(address - instructionStartAddress); totalSize += instructionSize; shouldContinue |= callback(NativeInstruction.Create(this, ref nativeInstruction), instructionSize, address); } } while (shouldContinue && (0 < (long)remainingSize)); // TODO : Consider releasing nativeInstruction handle. if (hInstruction.IsClosed) { throw new ApplicationException(); } hInstruction.Dispose(); } } finally { if (IntPtr.Zero != nativeCode) { Marshal.FreeCoTaskMem(nativeCode); } } }
/// <summary>Create a managed representation of a native instruction from /// the given native buffer.</summary> /// <param name="from">Native data to be decoded. On return the native data /// address is incremented to point at next instruction assuming instructions /// are stored in an array, such as the one returned by cs_disasm..</param> /// <returns>An instance of this class.</returns> internal static NativeInstruction Create <Inst, Reg, Group, Detail>( CapstoneDisassembler <Inst, Reg, Group, Detail> onBehalfOf, ref IntPtr from) { int offset = 0; // WARNING : Do not change properties initialization order. They match // the native structure field order. Order of parameters in some Helpers // functions is also very sensitive. NativeInstruction result = new NativeInstruction() { InstructionId = Helpers.GetNativeUInt32(from, ref offset), Address = Helpers.GetNativeUInt64(from, ref offset), ManagedBytes = Helpers.GetNativeInlineBufferArray(from, 16, Helpers.GetNativeUInt16(from, ref offset), ref offset), ManagedMnemonic = Helpers.GetAnsiString(from, 32, ref offset), ManagedOperand = Helpers.GetAnsiString(from, 160, ref offset), }; IntPtr nativeDetails = Helpers.GetNativeIntPtr(from, ref offset); from += offset; // TODO : Handle details. return(result); }
/// <summary>Create a Dissembled Instruction.</summary> /// <param name="nativeInstruction">A native instruction.</param> /// <returns>A dissembled instruction.</returns> protected abstract Instruction <Inst, Reg, Group, Detail> CreateInstruction(NativeInstruction nativeInstruction);
/// <summary>Convert a Native Instruction to an X86 Dissembled Instruction.</summary> /// <param name="this">A native instruction.</param> /// <returns>A dissembled instruction.</returns> public static Instruction <X86Instruction, X86Register, X86InstructionGroup, X86InstructionDetail> AsX86Instruction(this NativeInstruction @this) { var @object = @this.AsInstruction <X86Instruction, X86Register, X86InstructionGroup, X86InstructionDetail>(); @object.Id = (X86Instruction)@this.InstructionId; return(@object); }
/// <summary>Convert a Native Instruction to a ARM64 Dissembled Instruction.</summary> /// <param name="this">A native instruction.</param> /// <returns>A dissembled instruction.</returns> public static Instruction <Arm64Instruction, Arm64Register, Arm64InstructionGroup, Arm64InstructionDetail> AsArm64Instruction(this NativeInstruction @this) { var @object = @this.AsInstruction <Arm64Instruction, Arm64Register, Arm64InstructionGroup, Arm64InstructionDetail>(); @object.Id = (Arm64Instruction)@this.InstructionId; return(@object); }
/// <summary>Convert a Native Instruction to a Dissembled Instruction.</summary> /// <param name="this">A native instruction.</param> /// <returns>A dissembled instruction.</returns> public static Instruction <ArchInst, ArchReg, ArchGroup, ArchDetail> AsInstruction <ArchInst, ArchReg, ArchGroup, ArchDetail>(this NativeInstruction @this) where ArchInst : struct, System.IConvertible { return(new Instruction <ArchInst, ArchReg, ArchGroup, ArchDetail>() { Address = (long)@this.Address, Bytes = @this.ManagedBytes, Mnemonic = @this.ManagedMnemonic, Operand = @this.ManagedOperand, Id = (ArchInst)(System.Enum.ToObject(typeof(ArchInst), @this.InstructionId)) }); }