capstone-engine / capstone

Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
http://www.capstone-engine.org
7.61k stars 1.56k forks source link

[ARM] Inconsistent instruction mnemonic #1030

Open tmfink opened 7 years ago

tmfink commented 7 years ago

When disassembling the bytes "\x00\x00\x00\x00" for Arm:

  1. insn.mnemonic ==> "andeq"
  2. But, cs_insn_name(handle, insn.id) ==> "and"
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */

#include <stdio.h>
#include <stdlib.h>

#include <platform.h>
#include <capstone.h>

static csh handle;

struct platform {
    cs_arch arch;
    cs_mode mode;
    unsigned char *code;
    size_t size;
    char *comment;
    int syntax;
};

static void print_string_hex(char *comment, unsigned char *str, size_t len)
{
    unsigned char *c;

    printf("%s", comment);
    for (c = str; c < str + len; c++) {
        printf("0x%02x ", *c & 0xff);
    }

    printf("\n");
}

static void test()
{
#define ARM_AND "\x00\x00\x00\x00"

    struct platform platforms[] = {
        {
            CS_ARCH_ARM,
            CS_MODE_ARM,
            (unsigned char *)ARM_AND,
            sizeof(ARM_AND) - 1,
            "ARM and/andeq"
        }
    };

    uint64_t address = 0x80001000;
    cs_insn *insn;
    int i;
    size_t count;

    for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
        cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
        if (err) {
            printf("Failed on cs_open() with error returned: %u\n", err);
            continue;
        }

        cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);

        if (platforms[i].syntax)
            cs_option(handle, CS_OPT_SYNTAX, platforms[i].syntax);

        count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
        if (count) {
            size_t j;
            printf("****************\n");
            printf("Platform: %s\n", platforms[i].comment);
            print_string_hex("Code:", platforms[i].code, platforms[i].size);
            printf("Disasm:\n");

            for (j = 0; j < count; j++) {
                printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
                printf("\t\tid = %u, cs_insn_name() = \"%s\"\n", insn[j].id, cs_insn_name(handle, insn[j].id));
            }
            printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);

            // free memory allocated by cs_disasm()
            cs_free(insn, count);
        } else {
            printf("****************\n");
            printf("Platform: %s\n", platforms[i].comment);
            print_string_hex("Code:", platforms[i].code, platforms[i].size);
            printf("ERROR: Failed to disasm given code!\n");
        }

        printf("\n");
        cs_close(&handle);
    }
}

int main()
{
    test();
    return 0;
}

Produces:

****************
Platform: ARM and/andeq
Code:0x00 0x00 0x00 0x00 
Disasm:
0x80001000:     andeq   r0, r0, r0
                id = 8, cs_insn_name() = "and"
0x80001004:
Rot127 commented 1 year ago

The name/mnemonic is and. eq is the predicate. Can be closed.