/// <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); } } }