/// <summary>Return friendly name of a group id (that an instruction can /// belong to) Find the group id from header file of corresponding /// architecture (arm.h for ARM, x86.h for X86, ...)</summary> /// <param name="groupId"></param> /// <returns></returns> /// <remarks>Attempt to invoke this method with Capstone native library /// compiled in diet mode will throw an exception.</remarks> public string GetGroupName(uint groupId) { if (DietModeEnabled) { throw new InvalidOperationException("Diet mode enabled."); } return(CapstoneImport.GroupName(this, groupId)); }
/// <summary>This class initializer is intended to collect some immutable /// global information from the native library.</summary> static CapstoneDisassembler() { AllArchitectureSupported = CapstoneImport.IsSupported(CapstoneImport.SpecialMode.AllArchitecture); DietModeEnabled = CapstoneImport.IsSupported(CapstoneImport.SpecialMode.DietMode); X86ReduceEnabled = CapstoneImport.IsSupported(CapstoneImport.SpecialMode.X86Reduce); CapstoneImport.GetLibraryVersion(out _libraryMajorVersion, out _libraryMinorVersion); return; }
/// <summary>Invoke the native Capstone exported function that will open /// a disassembler for the given pair of architecture and mode.</summary> /// <param name="architecture">Target architecture</param> /// <param name="mode">Target mode</param> /// <returns>The native handle that is to be wrapped by our super class /// safe handle.</returns> /// <remarks>This method is for use by the constructor exclusively.</remarks> private static IntPtr CreateNativeAssembler(DisassembleArchitecture architecture, DisassembleMode mode) { IntPtr native; CapstoneImport.Open(architecture, mode, out native).ThrowOnCapstoneError(); return(native); }
/// <summary>Release Handle.</summary> /// <returns>A boolean true if the handle was released. A boolean false /// otherwise.</returns> protected override bool ReleaseHandle() { lock (ReleaseLock) { try { _beingFreed = this; CapstoneImport.Free(this, this._instructionCount); } finally { _beingFreed = null; } } this._instructions = Enumerable.Empty <NativeInstruction>(); return(true); }
/// <summary>This is a required override. The method invokes the Capstone /// provided native function that will release the handle.</summary> /// <returns>True on successfull handle release, false otherwise.</returns> /// <remarks>TODO : if the handle is not properly released by the native /// library, we should consider throwing an exception instead of returning /// a boolean. This is almost certainly an unex^pected condition that require /// some kind of fix.</remarks> protected override bool ReleaseHandle() { // We must use a local variable in order to be able to use the ref modifier // on Close call. SafeCapstoneContextHandle mySelf = this; if (IntPtr.Zero == mySelf.handle) { throw new InvalidOperationException(); } CapstoneImport.Close(ref mySelf).ThrowOnCapstoneError(); // We need to reset the handle by ourselves. this.handle = IntPtr.Zero; return(true); }
/// <summary>Disassemble Binary Code.</summary> /// <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 collection of dissembled instructions.</returns> /// <exception cref="System.InvalidOperationException">Thrown if the binary /// code could not be disassembled.</exception> public Instruction <Inst, Reg, Group, Detail>[] Disassemble( byte[] code, int count = 0, ulong startingAddress = 0x1000) { IntPtr nativeInstructions; IntPtr instructionsCount = CapstoneImport.Disassemble(this, code, (IntPtr)code.Length, startingAddress, (IntPtr)count, out nativeInstructions); if (IntPtr.Zero == instructionsCount) { CapstoneImport.GetLastError(this).ThrowOnCapstoneError(); } return(EnumerateNativeInstructions(nativeInstructions, (int)instructionsCount) .Select(this.CreateInstruction) .ToArray()); }
/// <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>Set Disassemble Syntax Option.</summary> /// <param name="value">A syntax option value.</param> /// <exception cref="System.InvalidOperationException"> /// Thrown if the disassemble syntax option could not be set. /// </exception> private void SetDisassembleSyntaxOption(DisassembleSyntaxOptionValue value) { CapstoneImport.SetOption(this, DisassembleOptionType.Syntax, (IntPtr)value) .ThrowOnCapstoneError(); }
/// <summary>Resolve a Registry Unique Identifier to an Registry Name. /// </summary> /// <returns>A string representing registry name of a null reference if /// the unique identifier is invalid.</returns> public string GetRegistryName(uint registryId) { return(CapstoneImport.GroupName(this, registryId)); }
/// <summary>Resolve an Instruction Unique Identifier to an Instruction Name. /// </summary> /// <returns>A string representing instruction name of a null reference if /// the unique identifier is invalid.</returns> public string GetInstructionName(uint instructionId) { return(CapstoneImport.GroupName(this, instructionId)); }