Skip to content

capstone

Capstone integration

capstone_decode_instruction(inst)

Decode an instruction with capstone

Decode an instruction and retry for ARM to check if the Thumb mode was activated The decoding logic is done by the inner method _decode.

Parameters:

Name Type Description Default
inst Instruction

Instruction to translate

required

Returns:

Type Description
Optional[CsInsn]

A capstone instruction if it has been decoded

Source code in quokka/backends/capstone.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def capstone_decode_instruction(
    inst: quokka.Instruction,
) -> Optional[capstone.CsInsn]:
    """Decode an instruction with capstone

    Decode an instruction and retry for ARM to check if the Thumb mode was activated
    The decoding logic is done by the inner method `_decode`.

    Arguments:
        inst: Instruction to translate

    Returns:
        A capstone instruction if it has been decoded
    """

    context: capstone.Cs = update_capstone_context(inst.program, inst.thumb)
    capstone_inst = _decode(context, inst.bytes, inst.address, count=1)

    if capstone_inst is None and context.arch == capstone.CS_ARCH_ARM:
        if context.mode == capstone.CS_MODE_THUMB:
            new_context = get_capstone_context(quokka.analysis.ArchARM)
        else:
            new_context = get_capstone_context(quokka.analysis.ArchARMThumb)

        capstone_inst = _decode(new_context, inst.bytes, inst.address, count=1)

    return capstone_inst

get_capstone_context(arch, endian=Endianness.LITTLE_ENDIAN)

Compute the capstone context for the program

The Capstone context is used to decode instructions afterwards. Since we are interested in most of the details, we already set the details to True.

Parameters:

Name Type Description Default
arch Type[QuokkaArch]

Quokka program architecture

required

Returns:

Type Description
Cs

A capstone Cs instance

Source code in quokka/backends/capstone.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
def get_capstone_context(
        arch: Type[quokka.analysis.QuokkaArch],
        endian: Type[Endianness] = Endianness.LITTLE_ENDIAN) -> capstone.Cs:
    """Compute the capstone context for the program

    The Capstone context is used to decode instructions afterwards. Since we are
    interested in most of the details, we already set the details to True.

    Arguments:
        arch: Quokka program architecture

    Returns:
        A capstone Cs instance
    """
    endian_mapping = {
        Endianness.BIG_ENDIAN: capstone.CS_MODE_BIG_ENDIAN,
        Endianness.LITTLE_ENDIAN: capstone.CS_MODE_LITTLE_ENDIAN,
    }
    capstone_endian = endian_mapping[endian]

    mapping = {
        quokka.analysis.ArchARM: (capstone.CS_ARCH_ARM, capstone.CS_MODE_ARM),
        quokka.analysis.ArchARM64: (capstone.CS_ARCH_ARM64, capstone.CS_MODE_ARM),
        quokka.analysis.ArchX86: (capstone.CS_ARCH_X86, capstone.CS_MODE_32),
        quokka.analysis.ArchX64: (capstone.CS_ARCH_X86, capstone.CS_MODE_64),
        quokka.analysis.ArchARMThumb: (
            capstone.CS_ARCH_ARM,
            capstone.CS_MODE_THUMB,
        ),
        quokka.analysis.ArchMIPS: (
            capstone.CS_ARCH_MIPS,
            capstone.CS_MODE_32 + capstone_endian),
        quokka.analysis.ArchMIPS64: (
            capstone.CS_ARCH_MIPS,
            capstone.CS_MODE_64 + capstone_endian),
        quokka.analysis.ArchPPC: (
            capstone.CS_ARCH_PPC,
            capstone.CS_MODE_32 + capstone_endian),
        quokka.analysis.ArchPPC64: (
            capstone.CS_ARCH_PPC,
            capstone.CS_MODE_64 + capstone_endian),
    }

    try:
        capstone_arch, capstone_mode = mapping.get(arch)
    except TypeError as exc:
        raise quokka.CapstoneError("Unable to find the Architecture") from exc

    context = capstone.Cs(capstone_arch, capstone_mode)
    context.detail = True

    return context

update_capstone_context(program, is_thumb)

Returns an appropriate context for Capstone instructions

For ARM architecture, if the instruction is Thumb, we must use a different context.

Parameters:

Name Type Description Default
program Program

Program to consider

required
is_thumb bool

Is the instruction a thumb one?

required

Returns:

Type Description
Cs

The correct capstone context

Source code in quokka/backends/capstone.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def update_capstone_context(program: quokka.Program, is_thumb: bool) -> capstone.Cs:
    """Returns an appropriate context for Capstone instructions

    For ARM architecture, if the instruction is Thumb, we must use a different context.

    Arguments:
        program: Program to consider
        is_thumb: Is the instruction a thumb one?

    Returns:
        The correct capstone context
    """
    if (
        program.arch
        in (
            quokka.analysis.ArchARM,
            quokka.analysis.ArchARM64,
            quokka.analysis.ArchARMThumb,
        )
        and is_thumb
    ):
        return get_capstone_context(quokka.analysis.ArchARMThumb)

    return program.capstone