(self, insn)
return insn.size
decodes an instruction and place it into the given insn.

        Args:
          insn (idaapi.insn_t): the instruction to populate.

        Returns:
          int: size of insn on success, 0 on failure.
decodes an instruction and place it into the given insn.
decodes an instruction and place it into the given insn .
def notify_ana(self, insn):
        '''
        decodes an instruction and place it into the given insn.

        Args:
          insn (idaapi.insn_t): the instruction to populate.

        Returns:
          int: size of insn on success, 0 on failure.
        '''

        # as of today (v1), each opcode is a single byte
        opb = insn.get_next_byte()

        if opb not in wasm.opcodes.OPCODE_MAP:
            return 0

        # translate from opcode index to IDA-specific const.
        # as you can see elsewhere, IDA insn consts have to be contiguous,
        #  so we can't just re-use the opcode index.
        insn.itype = self.insns[opb]['id']

        # fetch entire instruction buffer to decode
        if wasm.opcodes.OPCODE_MAP.get(opb).imm_struct:
            # opcode has operands that we must decode

            # warning: py2.7-specific
            # can't usually just cast the bytearray to a string without explicit decode.
            # assumption: instruction will be less than 0x10 bytes.
            buf = str(bytearray(idc.GetManyBytes(insn.ea, 0x10)))
        else:
            # single byte instruction

            # warning: py2.7-specific
            buf = str(bytearray([opb]))

        bc = next(wasm.decode.decode_bytecode(buf))
        for _ in range(1, bc.len):
            # consume any additional bytes.
            # this is how IDA knows the size of the insn.
            insn.get_next_byte()

        insn.Op1.type = idaapi.o_void
        insn.Op2.type = idaapi.o_void

        # decode instruction operand.
        # as of today (V1), there's at most a single operand.
        # (though there may also be alignment directive, etc. that we place into Op2+)
        #
        # place the operand value into `.value`, unless its a local, and then use `.reg`.
        # use `.specval` to indicate special handling of register, possible cases:
        #   WASM_LOCAL
        #   WASM_GLOBAL
        #   WASM_FUNC_INDEX
        #   WASM_TYPE_INDEX
        #   WASM_BLOCK
        #   WASM_ALIGN
        #
        if bc.imm is not None:
            immtype = bc.imm.get_meta().structure

            SHOW_FLAGS = idaapi.OF_NO_BASE_DISP | idaapi.OF_NUMBER | idaapi.OF_SHOW

            # wasm is currently single-byte opcode only
            # therefore the first operand must be found at offset 0x1.
            insn.Op1.offb = 1
            insn.Op1.offo = 1

            # by default, display the operand, unless overridden below.
            insn.Op1.flags = SHOW_FLAGS

            if immtype == wasm.immtypes.BlockImm:
                # sig = BlockTypeField()
                insn.Op1.type = WASM_BLOCK
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.sig
                insn.Op1.specval = WASM_BLOCK

            elif immtype == wasm.immtypes.BranchImm:
                # relative_depth = VarUInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.relative_depth

            elif immtype == wasm.immtypes.BranchTableImm:
                # target_count = VarUInt32Field()
                # target_table = RepeatField(VarUInt32Field(), lambda x: x.target_count)
                # default_target = VarUInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.target_count

                insn.Op2.type = idaapi.o_imm
                insn.Op2.offb = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.offo = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.flags = SHOW_FLAGS
                insn.Op2.dtype = idaapi.dt_dword
                insn.Op2.value = bc.imm.target_table

                insn.Op3.type = idaapi.o_imm
                insn.Op3.offb = 1  # TODO(wb): fixup offset of Op3
                insn.Op3.offo = 1  # TODO(wb): fixup offset of Op3
                insn.Op3.flags = SHOW_FLAGS
                insn.Op3.dtype = idaapi.dt_dword
                insn.Op3.value = bc.imm.default_target

            elif immtype == wasm.immtypes.CallImm:
                # function_index = VarUInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.function_index
                insn.Op1.specval = WASM_FUNC_INDEX

            elif immtype == wasm.immtypes.CallIndirectImm:
                # type_index = VarUInt32Field()
                # reserved = VarUInt1Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.type_index
                insn.Op1.specval = WASM_TYPE_INDEX

                insn.Op2.type = idaapi.o_imm
                insn.Op2.offb = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.offo = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.flags = SHOW_FLAGS
                insn.Op2.dtype = idaapi.dt_dword
                insn.Op2.value = bc.imm.reserved

            elif immtype == wasm.immtypes.LocalVarXsImm:
                # local_index = VarUInt32Field()
                insn.Op1.type = idaapi.o_reg
                insn.Op1.reg = bc.imm.local_index
                insn.Op1.specval = WASM_LOCAL

            elif immtype == wasm.immtypes.GlobalVarXsImm:
                # global_index = VarUInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.global_index
                insn.Op1.specval = WASM_GLOBAL

            elif immtype == wasm.immtypes.MemoryImm:
                # flags = VarUInt32Field()
                # offset = VarUInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.offset

                insn.Op2.type = idaapi.o_imm
                insn.Op2.offb = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.offo = 1  # TODO(wb): fixup offset of Op2
                insn.Op2.flags = SHOW_FLAGS
                insn.Op2.dtype = idaapi.dt_dword
                insn.Op2.value = bc.imm.flags
                insn.Op2.specval = WASM_ALIGN

            elif immtype == wasm.immtypes.CurGrowMemImm:
                # reserved = VarUInt1Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.reserved

            elif immtype == wasm.immtypes.I32ConstImm:
                # value = VarInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_dword
                insn.Op1.value = bc.imm.value

            elif immtype == wasm.immtypes.I64ConstImm:
                # value = VarInt64Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_qword
                insn.Op1.value = bc.imm.value

            elif immtype == wasm.immtypes.F32ConstImm:
                # value = UInt32Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_float
                insn.Op1.value = bc.imm.value

            elif immtype == wasm.immtypes.F64ConstImm:
                # value = UInt64Field()
                insn.Op1.type = idaapi.o_imm
                insn.Op1.dtype = idaapi.dt_double
                insn.Op1.value = bc.imm.value

        return insn.size
def notify_ana ( self , insn ) : # as of today (v1), each opcode is a single byte opb = insn . get_next_byte ( ) if opb not in wasm . opcodes . OPCODE_MAP : return 0 # translate from opcode index to IDA-specific const. # as you can see elsewhere, IDA insn consts have to be contiguous, #  so we can't just re-use the opcode index. insn . itype = self . insns [ opb ] [ 'id' ] # fetch entire instruction buffer to decode if wasm . opcodes . OPCODE_MAP . get ( opb ) . imm_struct : # opcode has operands that we must decode # warning: py2.7-specific # can't usually just cast the bytearray to a string without explicit decode. # assumption: instruction will be less than 0x10 bytes. buf = str ( bytearray ( idc . GetManyBytes ( insn . ea , 0x10 ) ) ) else : # single byte instruction # warning: py2.7-specific buf = str ( bytearray ( [ opb ] ) ) bc = next ( wasm . decode . decode_bytecode ( buf ) ) for _ in range ( 1 , bc . len ) : # consume any additional bytes. # this is how IDA knows the size of the insn. insn . get_next_byte ( ) insn . Op1 . type = idaapi . o_void insn . Op2 . type = idaapi . o_void # decode instruction operand. # as of today (V1), there's at most a single operand. # (though there may also be alignment directive, etc. that we place into Op2+) # # place the operand value into `.value`, unless its a local, and then use `.reg`. # use `.specval` to indicate special handling of register, possible cases: #   WASM_LOCAL #   WASM_GLOBAL #   WASM_FUNC_INDEX #   WASM_TYPE_INDEX #   WASM_BLOCK #   WASM_ALIGN # if bc . imm is not None : immtype = bc . imm . get_meta ( ) . structure SHOW_FLAGS = idaapi . OF_NO_BASE_DISP | idaapi . OF_NUMBER | idaapi . OF_SHOW # wasm is currently single-byte opcode only # therefore the first operand must be found at offset 0x1. insn . Op1 . offb = 1 insn . Op1 . offo = 1 # by default, display the operand, unless overridden below. insn . Op1 . flags = SHOW_FLAGS if immtype == wasm . immtypes . BlockImm : # sig = BlockTypeField() insn . Op1 . type = WASM_BLOCK insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . sig insn . Op1 . specval = WASM_BLOCK elif immtype == wasm . immtypes . BranchImm : # relative_depth = VarUInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . relative_depth elif immtype == wasm . immtypes . BranchTableImm : # target_count = VarUInt32Field() # target_table = RepeatField(VarUInt32Field(), lambda x: x.target_count) # default_target = VarUInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . target_count insn . Op2 . type = idaapi . o_imm insn . Op2 . offb = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . offo = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . flags = SHOW_FLAGS insn . Op2 . dtype = idaapi . dt_dword insn . Op2 . value = bc . imm . target_table insn . Op3 . type = idaapi . o_imm insn . Op3 . offb = 1 # TODO(wb): fixup offset of Op3 insn . Op3 . offo = 1 # TODO(wb): fixup offset of Op3 insn . Op3 . flags = SHOW_FLAGS insn . Op3 . dtype = idaapi . dt_dword insn . Op3 . value = bc . imm . default_target elif immtype == wasm . immtypes . CallImm : # function_index = VarUInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . function_index insn . Op1 . specval = WASM_FUNC_INDEX elif immtype == wasm . immtypes . CallIndirectImm : # type_index = VarUInt32Field() # reserved = VarUInt1Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . type_index insn . Op1 . specval = WASM_TYPE_INDEX insn . Op2 . type = idaapi . o_imm insn . Op2 . offb = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . offo = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . flags = SHOW_FLAGS insn . Op2 . dtype = idaapi . dt_dword insn . Op2 . value = bc . imm . reserved elif immtype == wasm . immtypes . LocalVarXsImm : # local_index = VarUInt32Field() insn . Op1 . type = idaapi . o_reg insn . Op1 . reg = bc . imm . local_index insn . Op1 . specval = WASM_LOCAL elif immtype == wasm . immtypes . GlobalVarXsImm : # global_index = VarUInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . global_index insn . Op1 . specval = WASM_GLOBAL elif immtype == wasm . immtypes . MemoryImm : # flags = VarUInt32Field() # offset = VarUInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . offset insn . Op2 . type = idaapi . o_imm insn . Op2 . offb = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . offo = 1 # TODO(wb): fixup offset of Op2 insn . Op2 . flags = SHOW_FLAGS insn . Op2 . dtype = idaapi . dt_dword insn . Op2 . value = bc . imm . flags insn . Op2 . specval = WASM_ALIGN elif immtype == wasm . immtypes . CurGrowMemImm : # reserved = VarUInt1Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . reserved elif immtype == wasm . immtypes . I32ConstImm : # value = VarInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_dword insn . Op1 . value = bc . imm . value elif immtype == wasm . immtypes . I64ConstImm : # value = VarInt64Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_qword insn . Op1 . value = bc . imm . value elif immtype == wasm . immtypes . F32ConstImm : # value = UInt32Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_float insn . Op1 . value = bc . imm . value elif immtype == wasm . immtypes . F64ConstImm : # value = UInt64Field() insn . Op1 . type = idaapi . o_imm insn . Op1 . dtype = idaapi . dt_double insn . Op1 . value = bc . imm . value return insn . size