Skip to content

How To; Use Diet Mode

Ahmed Garhy edited this page Jan 12, 2019 · 1 revision

Overview

Capstone supports a build option called Diet Mode to minimize its size when it is build. If a Capstone library is build with Diet Mode enabled, some Capstone APIs and structure fields are unsupported and in some cases return undefined results if they are used. More information can be found on the Capstone website.

Because Diet Mode is a Capstone build option, you cannot enable or disable it from Capstone.NET. Instead, Capstone.NET has support to determine whether the loaded Capstone library was compiled with Diet Mode enabled or disabled. If Diet Mode is enabled, Capstone.NET operations that would internally use Capstone APIs and structure fields that are unsupported in Diet Mode will throw an exception. This fail-fast technique is meant to indicate to you immediately that the an operation cannot be trusted to return accurate results because the loaded Capstone library does not support it.

Checking if Diet Mode is Enabled

You can determine whether Diet Mode is enabled or not using the static property CapstoneDisassembler.IsDietModeEnabled (View code). Some additional classes also define an instance property IsDietModeEnabled that can help you determine whether Diet Mode is enabled or not. The classes that define the instance property IsDietModeEnabled do so mainly for convenience (internally, those properties simply call CapstoneDisassembler.IsDietModeEnabled) if the class also defines operations that throw an exception when Diet Mode is enabled. Let's look at an example:

using Gee.External.Capstone;
using Gee.External.Capstone.Arm64;

const Arm64DisassembleMode disassembleMode = Arm64DisassembleMode.Arm;
using (CapstoneArm64Disassembler disassembler = CapstoneDisassembler.CreateArm64Disassembler(disassembleMode)) {
    disassembler.EnableInstructionDetails = true;
    disassembler.DisassembleSyntax = DisassembleSyntax.Intel;

    var binaryCode = new byte[] {
        0x09, 0x00, 0x38, 0xd5, 0xbf, 0x40, 0x00, 0xd5, 0x0c, 0x05, 0x13, 0xd5, 0x20, 0x50, 0x02, 0x0e,
        0x20, 0xe4, 0x3d, 0x0f, 0x00, 0x18, 0xa0, 0x5f, 0xa2, 0x00, 0xae, 0x9e, 0x9f, 0x37, 0x03, 0xd5,
        0xbf, 0x33, 0x03, 0xd5, 0xdf, 0x3f, 0x03, 0xd5, 0x21, 0x7c, 0x02, 0x9b, 0x21, 0x7c, 0x00, 0x53,
        0x00, 0x40, 0x21, 0x4b, 0xe1, 0x0b, 0x40, 0xb9, 0x20, 0x04, 0x81, 0xda, 0x20, 0x08, 0x02, 0x8b,
        0x10, 0x5b, 0xe8, 0x3c
    };

    Arm64Instruction[] instructions = disassembler.Disassemble(binaryCode);
    foreach (Arm64Instruction instruction in instructions) {
        // ...
        //
        // An instruction's address and unique identifier are always available.
        var address = instruction.Address;
        var id = instruction.Id;
        if (!CapstoneDisassembler.IsDietModeEnabled) {
            // ...
            //
            // An instruction's mnemonic and operand text are only available when Diet Mode is disabled.
            // An exception is thrown otherwise!
            var mnemonic = instruction.Mnemonic;
            var operand = instruction.Operand;
        }
    }
}

As mentioned earlier, Capstone.NET operations that require Diet Mode to be disabled will throw an exception, more specifically a System.NotSupportedException, if it is not. Some people might disagree with this design decision and will argue that throwing an exception is cumbersome and unnecessary. In truth, the design decision is there to help you avoid simple mistakes. First, Capstone APIs that require Diet Mode to be disabled will themselves return an error if Diet Mode is enabled. Second, for structure fields that are unsupported when Diet Mode is enabled, the Capstone documentation itself warns that they might be set to undefined values and should not be accessed.

Checking whether Diet Mode is enabled or not before performing relevant operations is usually good practice. However if you are developing an application or a library where you either build and distribute Capstone yourself or simply require Capstone to be build with a definite status for Diet Mode for your application or library to function correctly, then you can usually omit checking whether Diet Mode is enabled or not.

Irrelevant Operations When Diet Mode is Enabled

The following operations are unsupported, and thus will throw an exception, when Diet Mode is enabled:

  • Capstone[Arm|Arm64|X86]Disassembler.GetInstructionGroupName([Arm|Arm64|X86]InstructionGroupId)
  • Capstone[Arm|Arm64|X86]Disassembler.GetRegisterName([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]Instruction.Mnemonic
  • [Arm|Arm64|X86]Instruction.Operand
  • [Arm|Arm64|X86]InstructionDetail.AllReadRegisters
  • [Arm|Arm64|X86]InstructionDetail.AllWrittenRegisters
  • [Arm|Arm64|X86]InstructionDetail.ExplicitlyReadRegisters
  • [Arm|Arm64|X86]InstructionDetail.ExplicitlyWrittenRegisters
  • [Arm|Arm64|X86]InstructionDetail.Groups
  • [Arm|Arm64|X86]InstructionDetail.ImplicitlyReadRegisters
  • [Arm|Arm64|X86]InstructionDetail.ImplicitlyWrittenRegisters
  • [Arm|Arm64|X86]InstructionDetail.BelongsToGroup(string)
  • [Arm|Arm64|X86]InstructionDetail.BelongsToGroup([Arm|Arm64|X86]InstructionGroupId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterExplicitlyRead(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterExplicitlyRead([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterExplicitlyWritten(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterExplicitlyWritten([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterImplicitlyRead(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterImplicitlyRead([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterImplicitlyWritten(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterImplicitlyWritten([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterRead(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterRead([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterWritten(string)
  • [Arm|Arm64|X86]InstructionDetail.IsRegisterWritten([Arm|Arm64|X86]RegisterId)
  • [Arm|Arm64|X86]Register.Name
  • [Arm|Arm64|X86]InstructionGroup.Name