Repository: mandiant/capa
File: tests/test_binexport_accessors.py (Python)

Code before:
        (0x210190, ("x1", "x1", "#0x1")),
    ],
)
def test_get_operand_expressions(addr, op_expressions):
    insn = BE2_EXTRACTOR.idx.get_instruction_by_address(addr)
    ops = get_instruction_operands(BE2_EXTRACTOR.be2, insn)
    for i, op in enumerate(ops):
        exps = get_operand_expressions(BE2_EXTRACTOR.be2, op)
        assert len(exps) == 1
        assert exps[0].symbol == op_expressions[i]


@pytest.mark.parametrize(
    "addr,reg_expressions",
    [
        # 00210158 20 00 80 d2     mov        x0,#0x1
        (0x210158, ("x0", None)),
        # 0021015c a1 02 00 58     ldr        x1=>helloWorldStr,DAT_002101b0
        (0x21015C, ("x1", None)),
        # 00210184 02 68 61 38     ldrb       w2,[x0, x1, LSL ]
        (0x210184, ("w2", None)),
        # 00210190 21 04 00 91     add        x1,x1,#0x1
        (0x210190, ("x1", "x1", None)),
    ],
)
def _TODO_test_get_operand_register_expression(addr, reg_expressions):
    insn = BE2_EXTRACTOR.idx.get_instruction_by_address(addr)
    ops = get_instruction_operands(BE2_EXTRACTOR.be2, insn)
    for i, op in enumerate(ops):
        reg_exp = get_operand_register_expression(BE2_EXTRACTOR.be2, op)
        logger.debug("%s", get_operand_expressions(BE2_EXTRACTOR.be2, op))
        assert reg_exp == reg_expressions[i]


@pytest.mark.parametrize(
    "addr,expressions",
    [
        # 00210158 20 00 80 d2     mov        x0,#0x1
        (0x210158, (None, 0x1)),
        # 0021015c a1 02 00 58     ldr        x1=>helloWorldStr,DAT_002101b0
        (0x21015C, (None, None)),
        # 00210184 02 68 61 38     ldrb       w2,[x0, x1, LSL ]
        (0x210184, (None, None)),
        # 00210190 21 04 00 91     add        x1,x1,#0x1
        (0x210190, (None, None, 0x1)),
    ],
)
def _TODO_test_get_operand_immediate_expression(addr, expressions):
    insn = BE2_EXTRACTOR.idx.get_instruction_by_address(addr)
    ops = get_instruction_operands(BE2_EXTRACTOR.be2, insn)
    for i, op in enumerate(ops):

Review comment (bug):
@mike-hunhoff could you take a look at these to verify I understand correctly how the respective `get_` functions are supposed to work? these `_TODO_` tests here fail currently.

Code after:
        ),
        # 0021015c a1 02 00 58     ldr        x1=>helloWorldStr,DAT_002101b0
        (
            0x21015C,
            (
                BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="x1"),
                BinExport2.Expression(
                    type=BinExport2.Expression.IMMEDIATE_INT, symbol="DAT_002101b0", immediate=0x2101B0
                ),
            ),
        ),
        # 00210184 02 68 61 38     ldrb       w2,[x0, x1, LSL ]
        #                                                 ^^^ issue in Ghidra?
        #  IDA gives               LDRB       W2, [X0,X1]
        # still need to test/handle this and it's the only complex operand expression in this test binary :/
        (
            0x210184,
            (
                BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="w2"),
                (
                    BinExport2.Expression(type=BinExport2.Expression.DEREFERENCE, symbol="["),
                    BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="x0"),
                    BinExport2.Expression(type=BinExport2.Expression.OPERATOR, symbol=","),
                    BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="x1"),
                    BinExport2.Expression(type=BinExport2.Expression.OPERATOR, symbol=","),
                    BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="LSL"),
                    BinExport2.Expression(type=BinExport2.Expression.DEREFERENCE, symbol="]"),
                ),
            ),
        ),
        # 00210190 21 04 00 91     add        x1,x1,#0x1
        (
            0x210190,
            (
                BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="x1"),
                BinExport2.Expression(type=BinExport2.Expression.REGISTER, symbol="x1"),
                BinExport2.Expression(type=BinExport2.Expression.IMMEDIATE_INT, immediate=0x1),
            ),
        ),
    ],
)
def test_get_operand_expressions(addr, expressions):
    insn = BE2_EXTRACTOR.idx.get_instruction_by_address(addr)
    ops = get_instruction_operands(BE2_EXTRACTOR.be2, insn)
    for i, op in enumerate(ops):
        op_expression = expressions[i]
        exps = get_operand_expressions(BE2_EXTRACTOR.be2, op)
        if len(exps) > 1:
            for j, exp in enumerate(exps):
                assert exp.type == op_expression[j].type
                assert exp.symbol == op_expression[j].symbol