Initial Commit

This commit is contained in:
Sajid
2024-09-07 18:00:09 +06:00
commit 0f9a53f75a
3352 changed files with 1563708 additions and 0 deletions

49
thirdparty/capstone/cstool/Makefile vendored Normal file
View File

@@ -0,0 +1,49 @@
# Makefile for Cstool of Capstone Disassembly Engine
include ../functions.mk
.PHONY: clean all
LIBNAME = capstone
CFLAGS += -I../include -I.
CFLAGS += -std=gnu99
LDFLAGS += -O3 -Wall -L.. -l$(LIBNAME)
TARGET = cstool
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:.c=.o)
LIBCAPSTONE = libcapstone.a
IS_CYGWIN := $(shell $(CC) -dumpmachine 2>/dev/null | grep -i cygwin | wc -l)
ifeq ($(IS_CYGWIN),1)
LIBCAPSTONE = capstone.lib
else
IS_MINGW := $(shell $(CC) --version 2>/dev/null | grep -i "\(mingw\|MSYS\)" | wc -l)
ifeq ($(IS_MINGW),1)
LIBCAPSTONE = capstone.lib
endif
endif
all: $(TARGET)
$(TARGET): ../$(LIBCAPSTONE) $(OBJECTS)
ifeq ($(V), 0)
$(call log,LINK,$@)
@${CC} $(OBJECTS) $(LDFLAGS) -o $@
else
${CC} $(OBJECTS) $(LDFLAGS) -o $@
endif
clean:
${RM} -rf *.o $(TARGET)
${RM} -f *.d
%.o: %.c
ifeq ($(V), 0)
$(call log,CC,$@)
@${CC} $(CFLAGS) -c $< -o $@
else
${CC} $(CFLAGS) -c $< -o $@
endif

47
thirdparty/capstone/cstool/README vendored Normal file
View File

@@ -0,0 +1,47 @@
This directory contains cstool of Capstone Engine.
Cstool is a command-line tool to disassemble assembly hex-string.
For example, to decode a hexcode string for Intel 32bit, run:
$ cstool x32 "90 91"
0 90 nop
1 91 xchg eax, ecx
Cstool disassembles the input and prints out the assembly instructions.
On each line, the first column is the instruction offset, the second
column is opcodes, and the rest is the instruction itself.
Cstool is flexible enough to accept all kind of hexcode format. The following
inputs have the same output with the example above.
$ cstool x32 "0x90 0x91"
$ cstool x32 "\x90\x91"
$ cstool x32 "90,91"
$ cstool x32 "90;91"
$ cstool x32 "90+91"
$ cstool x32 "90:91"
To print out instruction details, run Cstool with -d option, like below.
$ cstool -d x32 "01 d8"
0 01d8 add eax, ebx
Prefix:0x00 0x00 0x00 0x00
Opcode:0x01 0x00 0x00 0x00
rex: 0x0
addr_size: 4
modrm: 0xd8
disp: 0x0
sib: 0x0
op_count: 2
operands[0].type: REG = eax
operands[0].size: 4
operands[0].access: READ | WRITE
operands[1].type: REG = ebx
operands[1].size: 4
operands[1].access: READ
Registers read: eax ebx
Registers modified: eflags eax
EFLAGS: MOD_AF MOD_CF MOD_SF MOD_ZF MOD_PF MOD_OF
To see all the supported options, run ./cstool

764
thirdparty/capstone/cstool/cstool.c vendored Normal file
View File

@@ -0,0 +1,764 @@
/* Tang Yuhang <tyh000011112222@gmail.com> 2016 */
/* pancake <pancake@nopcode.org> 2017 */
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "getopt.h"
#include <capstone/capstone.h>
#include "cstool.h"
void print_string_hex(const char *comment, unsigned char *str, size_t len);
static struct {
const char *name;
cs_arch arch;
cs_mode mode;
} all_archs[] = {
{ "arm", CS_ARCH_ARM, CS_MODE_ARM },
{ "armb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
{ "armbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_BIG_ENDIAN },
{ "arml", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
{ "armle", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_LITTLE_ENDIAN },
{ "armv8", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_V8 },
{ "thumbv8", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_V8 },
{ "armv8be", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_V8 | CS_MODE_BIG_ENDIAN },
{ "thumbv8be", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_V8 | CS_MODE_BIG_ENDIAN },
{ "cortexm", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_MCLASS },
{ "cortexv8m", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_MCLASS | CS_MODE_V8 },
{ "thumb", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB },
{ "thumbbe", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_BIG_ENDIAN },
{ "thumble", CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN },
{ "aarch64", CS_ARCH_AARCH64, CS_MODE_LITTLE_ENDIAN },
{ "aarch64be", CS_ARCH_AARCH64, CS_MODE_BIG_ENDIAN },
{ "mips", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_LITTLE_ENDIAN },
{ "mipsmicro", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_MICRO },
{ "mipsbemicro", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_MICRO | CS_MODE_BIG_ENDIAN },
{ "mipsbe32r6", CS_ARCH_MIPS, CS_MODE_MIPS32R6 | CS_MODE_BIG_ENDIAN},
{ "mipsbe32r6micro", CS_ARCH_MIPS, CS_MODE_MIPS32R6 | CS_MODE_BIG_ENDIAN | CS_MODE_MICRO },
{ "mips32r6", CS_ARCH_MIPS, CS_MODE_MIPS32R6 },
{ "mips32r6micro", CS_ARCH_MIPS, CS_MODE_MIPS32R6 | CS_MODE_MICRO },
{ "mipsbe", CS_ARCH_MIPS, CS_MODE_MIPS32 | CS_MODE_BIG_ENDIAN },
{ "mips64", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_LITTLE_ENDIAN },
{ "mips64be", CS_ARCH_MIPS, CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN },
{ "x16", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16
{ "x16att", CS_ARCH_X86, CS_MODE_16 }, // CS_MODE_16 , CS_OPT_SYNTAX_ATT
{ "x32", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32
{ "x32att", CS_ARCH_X86, CS_MODE_32 }, // CS_MODE_32, CS_OPT_SYNTAX_ATT
{ "x64", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64
{ "x64att", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64, CS_OPT_SYNTAX_ATT
{ "ppc32", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_LITTLE_ENDIAN },
{ "ppc32be", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_BIG_ENDIAN },
{ "ppc32qpx", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_QPX | CS_MODE_LITTLE_ENDIAN },
{ "ppc32beqpx", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_QPX | CS_MODE_BIG_ENDIAN },
{ "ppc32ps", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_PS | CS_MODE_LITTLE_ENDIAN },
{ "ppc32beps", CS_ARCH_PPC, CS_MODE_32 | CS_MODE_PS | CS_MODE_BIG_ENDIAN },
{ "ppc64", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_LITTLE_ENDIAN },
{ "ppc64be", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN },
{ "ppc64qpx", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_QPX | CS_MODE_LITTLE_ENDIAN },
{ "ppc64beqpx", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_QPX | CS_MODE_BIG_ENDIAN },
{ "sparc", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN },
{ "sparcv9", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 },
{ "systemz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
{ "sysz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
{ "s390x", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
{ "xcore", CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN },
{ "m68k", CS_ARCH_M68K, CS_MODE_BIG_ENDIAN },
{ "m68k40", CS_ARCH_M68K, CS_MODE_M68K_040 },
{ "tms320c64x", CS_ARCH_TMS320C64X, CS_MODE_BIG_ENDIAN },
{ "m6800", CS_ARCH_M680X, CS_MODE_M680X_6800 },
{ "m6801", CS_ARCH_M680X, CS_MODE_M680X_6801 },
{ "m6805", CS_ARCH_M680X, CS_MODE_M680X_6805 },
{ "m6808", CS_ARCH_M680X, CS_MODE_M680X_6808 },
{ "m6809", CS_ARCH_M680X, CS_MODE_M680X_6809 },
{ "m6811", CS_ARCH_M680X, CS_MODE_M680X_6811 },
{ "cpu12", CS_ARCH_M680X, CS_MODE_M680X_CPU12 },
{ "hd6301", CS_ARCH_M680X, CS_MODE_M680X_6301 },
{ "hd6309", CS_ARCH_M680X, CS_MODE_M680X_6309 },
{ "hcs08", CS_ARCH_M680X, CS_MODE_M680X_HCS08 },
{ "evm", CS_ARCH_EVM, 0 },
{ "wasm", CS_ARCH_WASM, 0 },
{ "bpf", CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_CLASSIC },
{ "bpfbe", CS_ARCH_BPF, CS_MODE_BIG_ENDIAN | CS_MODE_BPF_CLASSIC },
{ "ebpf", CS_ARCH_BPF, CS_MODE_LITTLE_ENDIAN | CS_MODE_BPF_EXTENDED },
{ "ebpfbe", CS_ARCH_BPF, CS_MODE_BIG_ENDIAN | CS_MODE_BPF_EXTENDED },
{ "riscv32", CS_ARCH_RISCV, CS_MODE_RISCV32 | CS_MODE_RISCVC },
{ "riscv64", CS_ARCH_RISCV, CS_MODE_RISCV64 | CS_MODE_RISCVC },
{ "6502", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_6502 },
{ "65c02", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65C02 },
{ "w65c02", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_W65C02 },
{ "65816", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65816_LONG_MX },
{ "sh", CS_ARCH_SH, CS_MODE_BIG_ENDIAN },
{ "sh2", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_BIG_ENDIAN},
{ "sh2e", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN},
{ "sh-dsp", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_SHDSP | CS_MODE_BIG_ENDIAN},
{ "sh2a", CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_BIG_ENDIAN},
{ "sh2a-fpu", CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN},
{ "sh3", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 },
{ "sh3be", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 },
{ "sh3e", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 | CS_MODE_SHFPU},
{ "sh3ebe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 | CS_MODE_SHFPU},
{ "sh3-dsp", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 | CS_MODE_SHDSP },
{ "sh3-dspbe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 | CS_MODE_SHDSP },
{ "sh4", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4 | CS_MODE_SHFPU },
{ "sh4be", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4 | CS_MODE_SHFPU },
{ "sh4a", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4A | CS_MODE_SHFPU },
{ "sh4abe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4A | CS_MODE_SHFPU },
{ "sh4al-dsp", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4A | CS_MODE_SHDSP | CS_MODE_SHFPU },
{ "sh4al-dspbe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4A | CS_MODE_SHDSP | CS_MODE_SHFPU },
{ "tc110", CS_ARCH_TRICORE, CS_MODE_TRICORE_110 },
{ "tc120", CS_ARCH_TRICORE, CS_MODE_TRICORE_120 },
{ "tc130", CS_ARCH_TRICORE, CS_MODE_TRICORE_130 },
{ "tc131", CS_ARCH_TRICORE, CS_MODE_TRICORE_131 },
{ "tc160", CS_ARCH_TRICORE, CS_MODE_TRICORE_160 },
{ "tc161", CS_ARCH_TRICORE, CS_MODE_TRICORE_161 },
{ "tc162", CS_ARCH_TRICORE, CS_MODE_TRICORE_162 },
{ "alpha", CS_ARCH_ALPHA, CS_MODE_LITTLE_ENDIAN },
{ "alphabe", CS_ARCH_ALPHA, CS_MODE_BIG_ENDIAN },
{ "hppa11", CS_ARCH_HPPA, CS_MODE_HPPA_11 | CS_MODE_LITTLE_ENDIAN },
{ "hppa11be", CS_ARCH_HPPA, CS_MODE_HPPA_11 | CS_MODE_BIG_ENDIAN },
{ "hppa20", CS_ARCH_HPPA, CS_MODE_HPPA_20 | CS_MODE_LITTLE_ENDIAN },
{ "hppa20be", CS_ARCH_HPPA, CS_MODE_HPPA_20 | CS_MODE_BIG_ENDIAN },
{ "hppa20w", CS_ARCH_HPPA, CS_MODE_HPPA_20W | CS_MODE_LITTLE_ENDIAN },
{ "hppa20wbe", CS_ARCH_HPPA, CS_MODE_HPPA_20W | CS_MODE_BIG_ENDIAN },
{ "loongarch32", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH32 },
{ "loongarch64", CS_ARCH_LOONGARCH, CS_MODE_LOONGARCH64 },
{ NULL }
};
static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins);
void print_string_hex(const 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");
}
// convert hexchar to hexnum
static uint8_t char_to_hexnum(char c)
{
if (c >= '0' && c <= '9') {
return (uint8_t)(c - '0');
}
if (c >= 'a' && c <= 'f') {
return (uint8_t)(10 + c - 'a');
}
// c >= 'A' && c <= 'F'
return (uint8_t)(10 + c - 'A');
}
// convert user input (char[]) to uint8_t[], each element of which is
// valid hexadecimal, and return actual length of uint8_t[] in @size.
static uint8_t *preprocess(char *code, size_t *size)
{
size_t i = 0, j = 0;
uint8_t high, low;
uint8_t *result;
if (strlen(code) == 0)
return NULL;
result = (uint8_t *)malloc(strlen(code));
if (result != NULL) {
while (code[i] != '\0') {
if (isxdigit(code[i]) && isxdigit(code[i+1])) {
high = 16 * char_to_hexnum(code[i]);
low = char_to_hexnum(code[i+1]);
result[j] = high + low;
i++;
j++;
}
i++;
}
*size = j;
}
return result;
}
static void usage(char *prog)
{
printf("Cstool for Capstone Disassembler Engine v%u.%u.%u\n\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
printf("Syntax: %s [-d|-a|-r|-s|-u|-v] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
printf("\nThe following <arch+mode> options are supported:\n");
if (cs_support(CS_ARCH_X86)) {
printf(" x16 16-bit mode (X86)\n");
printf(" x32 32-bit mode (X86)\n");
printf(" x64 64-bit mode (X86)\n");
printf(" x16att 16-bit mode (X86), syntax AT&T\n");
printf(" x32att 32-bit mode (X86), syntax AT&T\n");
printf(" x64att 64-bit mode (X86), syntax AT&T\n");
}
if (cs_support(CS_ARCH_ARM)) {
printf(" arm arm\n");
printf(" armbe arm + big endian\n");
printf(" thumb thumb mode\n");
printf(" thumbbe thumb + big endian\n");
printf(" cortexm thumb + cortex-m extensions\n");
printf(" cortexv8m thumb + cortex-m extensions + v8\n");
printf(" armv8 arm v8\n");
printf(" thumbv8 thumb v8\n");
printf(" armv8be arm v8 + big endian\n");
printf(" thumbv8be thumb v8 + big endian\n");
}
if (cs_support(CS_ARCH_AARCH64)) {
printf(" aarch64 aarch64 mode\n");
printf(" aarch64be aarch64 + big endian\n");
}
if (cs_support(CS_ARCH_ALPHA)) {
printf(" alpha alpha + little endian\n");
printf(" alphabe alpha + big endian\n");
}
if (cs_support(CS_ARCH_HPPA)) {
printf(" hppa11 hppa V1.1 + little endian\n");
printf(" hppa11be hppa V1.1 + big endian\n");
printf(" hppa20 hppa V2.0 + little endian\n");
printf(" hppa20be hppa V2.0 + big endian\n");
printf(" hppa20w hppa V2.0 wide + little endian\n");
printf(" hppa20wbe hppa V2.0 wide + big endian\n");
}
if (cs_support(CS_ARCH_MIPS)) {
printf(" mips mips32 + little endian\n");
printf(" mipsbe mips32 + big endian\n");
printf(" mips64 mips64 + little endian\n");
printf(" mips64be mips64 + big endian\n");
}
if (cs_support(CS_ARCH_PPC)) {
printf(" ppc32 ppc32 + little endian\n");
printf(" ppc32be ppc32 + big endian\n");
printf(" ppc32qpx ppc32 + qpx + little endian\n");
printf(" ppc32beqpx ppc32 + qpx + big endian\n");
printf(" ppc32ps ppc32 + ps + little endian\n");
printf(" ppc32beps ppc32 + ps + big endian\n");
printf(" ppc64 ppc64 + little endian\n");
printf(" ppc64be ppc64 + big endian\n");
printf(" ppc64qpx ppc64 + qpx + little endian\n");
printf(" ppc64beqpx ppc64 + qpx + big endian\n");
}
if (cs_support(CS_ARCH_SPARC)) {
printf(" sparc sparc\n");
}
if (cs_support(CS_ARCH_SYSZ)) {
printf(" systemz systemz (s390x)\n");
}
if (cs_support(CS_ARCH_XCORE)) {
printf(" xcore xcore\n");
}
if (cs_support(CS_ARCH_M68K)) {
printf(" m68k m68k + big endian\n");
printf(" m68k40 m68k_040\n");
}
if (cs_support(CS_ARCH_TMS320C64X)) {
printf(" tms320c64x TMS320C64x\n");
}
if (cs_support(CS_ARCH_M680X)) {
printf(" m6800 M6800/2\n");
printf(" m6801 M6801/3\n");
printf(" m6805 M6805\n");
printf(" m6808 M68HC08\n");
printf(" m6809 M6809\n");
printf(" m6811 M68HC11\n");
printf(" cpu12 M68HC12/HCS12\n");
printf(" hd6301 HD6301/3\n");
printf(" hd6309 HD6309\n");
printf(" hcs08 HCS08\n");
}
if (cs_support(CS_ARCH_EVM)) {
printf(" evm Ethereum Virtual Machine\n");
}
if (cs_support(CS_ARCH_MOS65XX)) {
printf(" 6502 MOS 6502\n");
printf(" 65c02 WDC 65c02\n");
printf(" w65c02 WDC w65c02\n");
printf(" 65816 WDC 65816 (long m/x)\n");
}
if (cs_support(CS_ARCH_WASM)) {
printf(" wasm: Web Assembly\n");
}
if (cs_support(CS_ARCH_BPF)) {
printf(" bpf Classic BPF\n");
printf(" bpfbe Classic BPF + big endian\n");
printf(" ebpf Extended BPF\n");
printf(" ebpfbe Extended BPF + big endian\n");
}
if (cs_support(CS_ARCH_RISCV)) {
printf(" riscv32 riscv32\n");
printf(" riscv64 riscv64\n");
}
if (cs_support(CS_ARCH_SH)) {
printf(" sh superh SH1\n");
printf(" sh2 superh SH2\n");
printf(" sh2e superh SH2E\n");
printf(" sh2dsp superh SH2-DSP\n");
printf(" sh2a superh SH2A\n");
printf(" sh2afpu superh SH2A-FPU\n");
printf(" sh3 superh SH3\n");
printf(" sh3be superh SH3 big endian\n");
printf(" sh3e superh SH3E\n");
printf(" sh3ebe superh SH3E big endian\n");
printf(" sh3-dsp superh SH3-DSP\n");
printf(" sh3-dspbe superh SH3-DSP big endian\n");
printf(" sh4 superh SH4\n");
printf(" sh4be superh SH4 big endian\n");
printf(" sh4a superh SH4A\n");
printf(" sh4abe superh SH4A big endian\n");
printf(" sh4al-dsp superh SH4AL-DSP\n");
printf(" sh4al-dspbe superh SH4AL-DSP big endian\n");
}
if (cs_support(CS_ARCH_TRICORE)) {
printf(" tc110 tricore V1.1\n");
printf(" tc120 tricore V1.2\n");
printf(" tc130 tricore V1.3\n");
printf(" tc131 tricore V1.3.1\n");
printf(" tc160 tricore V1.6\n");
printf(" tc161 tricore V1.6.1\n");
printf(" tc162 tricore V1.6.2\n");
}
if (cs_support(CS_ARCH_LOONGARCH)) {
printf(" loongarch32 LoongArch32\n");
printf(" loongarch64 LoongArch64\n");
}
printf("\nExtra options:\n");
printf(" -d show detailed information of the instructions\n");
printf(" -r show detailed information of the real instructions (even for alias)\n");
printf(" -a Print Capstone register alias (if any). Otherwise LLVM register names are emitted.\n");
printf(" -s decode in SKIPDATA mode\n");
printf(" -u show immediates as unsigned\n");
printf(" -f Dev fuzzing: Disassembles <assembly-hexstring> to 0xffffffff.\n\n");
printf(" -v show version & Capstone core build info\n\n");
}
static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins)
{
printf("\tID: %u (%s)\n", ins->id, cs_insn_name(handle, ins->id));
if (ins->is_alias) {
printf("\tIs alias: %" PRIu64 " (%s) ", ins->alias_id, cs_insn_name(handle, ins->alias_id));
printf("with %s operand set\n", ins->usesAliasDetails ? "ALIAS" : "REAL");
}
switch(arch) {
case CS_ARCH_X86:
print_insn_detail_x86(handle, md, ins);
break;
case CS_ARCH_ARM:
print_insn_detail_arm(handle, ins);
break;
case CS_ARCH_AARCH64:
print_insn_detail_aarch64(handle, ins);
break;
case CS_ARCH_MIPS:
print_insn_detail_mips(handle, ins);
break;
case CS_ARCH_PPC:
print_insn_detail_ppc(handle, ins);
break;
case CS_ARCH_SPARC:
print_insn_detail_sparc(handle, ins);
break;
case CS_ARCH_SYSZ:
print_insn_detail_sysz(handle, ins);
break;
case CS_ARCH_XCORE:
print_insn_detail_xcore(handle, ins);
break;
case CS_ARCH_M68K:
print_insn_detail_m68k(handle, ins);
break;
case CS_ARCH_TMS320C64X:
print_insn_detail_tms320c64x(handle, ins);
break;
case CS_ARCH_M680X:
print_insn_detail_m680x(handle, ins);
break;
case CS_ARCH_EVM:
print_insn_detail_evm(handle, ins);
break;
case CS_ARCH_WASM:
print_insn_detail_wasm(handle, ins);
break;
case CS_ARCH_MOS65XX:
print_insn_detail_mos65xx(handle, ins);
break;
case CS_ARCH_BPF:
print_insn_detail_bpf(handle, ins);
break;
case CS_ARCH_RISCV:
print_insn_detail_riscv(handle, ins);
break;
case CS_ARCH_SH:
print_insn_detail_sh(handle, ins);
break;
case CS_ARCH_TRICORE:
print_insn_detail_tricore(handle, ins);
break;
case CS_ARCH_ALPHA:
print_insn_detail_alpha(handle, ins);
break;
case CS_ARCH_HPPA:
print_insn_detail_hppa(handle, ins);
break;
case CS_ARCH_LOONGARCH:
print_insn_detail_loongarch(handle, ins);
break;
default: break;
}
if (ins->detail && ins->detail->groups_count) {
int j;
printf("\tGroups: ");
for(j = 0; j < ins->detail->groups_count; j++) {
printf("%s ", cs_group_name(handle, ins->detail->groups[j]));
}
printf("\n");
}
printf("\n");
}
static uint32_t read_le(uint8_t *buf, size_t size) {
uint32_t res = 0;
for (size_t i = 0, j = size - 1; i < size; ++i, --j) {
res |= buf[i] << j * 8;
}
return res;
}
static void to_buf(uint32_t num, uint8_t *buf) {
for (size_t i = 0, j = 3; i < 4; ++i, --j) {
buf[i] = (num >> j) & 0xff;
}
}
static void run_dev_fuzz(csh handle, uint8_t *bytes, uint32_t size) {
uint8_t buf[4] = {0};
uint32_t bytes_as_num = read_le(bytes, size);
uint32_t address = 0xffffffff;
printf("Run dev fuzz\n");
printf("Start: 0x%" PRIx32 "\n", bytes_as_num);
printf("End: 0xffffffff\n"
"Address: 0x%" PRIx32 "\n", address);
cs_insn *insn;
while (true) {
printf("\rProgress: 0x%08x\t\t", bytes_as_num);
fflush(stdout);
cs_disasm(handle, buf, 4, address, 0, &insn);
if (insn && insn->detail)
free(insn->detail);
free(insn);
bytes_as_num++;
to_buf(bytes_as_num, buf);
if (bytes_as_num == 0xffffffff) {
printf("\rProgress: 0x%08x\t\t", bytes_as_num);
fflush(stdout);
cs_disasm(handle, (uint8_t*)&buf, 4, address, 0, &insn);
if (insn && insn->detail)
free(insn->detail);
free(insn);
printf("\n");
return;
}
}
}
int main(int argc, char **argv)
{
int i, c;
csh handle;
char *mode;
uint8_t *assembly;
size_t count, size;
uint64_t address = 0LL;
cs_insn *insn;
cs_err err;
cs_mode md;
cs_arch arch = CS_ARCH_ALL;
bool detail_flag = false;
bool unsigned_flag = false;
bool skipdata = false;
bool custom_reg_alias = false;
bool set_real_detail = false;
bool dev_fuzz = false;
int args_left;
while ((c = getopt (argc, argv, "rasudhvf")) != -1) {
switch (c) {
case 'a':
custom_reg_alias = true;
break;
case 'r':
set_real_detail = true;
break;
case 's':
skipdata = true;
break;
case 'u':
unsigned_flag = true;
break;
case 'd':
detail_flag = true;
break;
case 'v':
printf("cstool for Capstone Disassembler, v%u.%u.%u\n", CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA);
printf("Capstone build: ");
if (cs_support(CS_ARCH_X86)) {
printf("x86=1 ");
}
if (cs_support(CS_ARCH_ARM)) {
printf("arm=1 ");
}
if (cs_support(CS_ARCH_AARCH64)) {
printf("aarch64=1 ");
}
if (cs_support(CS_ARCH_MIPS)) {
printf("mips=1 ");
}
if (cs_support(CS_ARCH_PPC)) {
printf("ppc=1 ");
}
if (cs_support(CS_ARCH_SPARC)) {
printf("sparc=1 ");
}
if (cs_support(CS_ARCH_SYSZ)) {
printf("sysz=1 ");
}
if (cs_support(CS_ARCH_XCORE)) {
printf("xcore=1 ");
}
if (cs_support(CS_ARCH_M68K)) {
printf("m68k=1 ");
}
if (cs_support(CS_ARCH_TMS320C64X)) {
printf("tms320c64x=1 ");
}
if (cs_support(CS_ARCH_M680X)) {
printf("m680x=1 ");
}
if (cs_support(CS_ARCH_EVM)) {
printf("evm=1 ");
}
if (cs_support(CS_ARCH_WASM)) {
printf("wasm=1 ");
}
if (cs_support(CS_ARCH_MOS65XX)) {
printf("mos65xx=1 ");
}
if (cs_support(CS_ARCH_BPF)) {
printf("bpf=1 ");
}
if (cs_support(CS_ARCH_RISCV)) {
printf("riscv=1 ");
}
if (cs_support(CS_ARCH_SH)) {
printf("sh=1 ");
}
if (cs_support(CS_SUPPORT_DIET)) {
printf("diet=1 ");
}
if (cs_support(CS_SUPPORT_X86_REDUCE)) {
printf("x86_reduce=1 ");
}
if (cs_support(CS_ARCH_TRICORE)) {
printf("tricore=1 ");
}
if (cs_support(CS_ARCH_ALPHA)) {
printf("alpha=1 ");
}
if (cs_support(CS_ARCH_HPPA)) {
printf("hppa=1 ");
}
if (cs_support(CS_ARCH_LOONGARCH)) {
printf("loongarch=1 ");
}
printf("\n");
return 0;
case 'f':
dev_fuzz = true;
break;
case 'h':
usage(argv[0]);
return 0;
default:
usage(argv[0]);
return -1;
}
}
args_left = argc - optind;
if (args_left < 2 || args_left > 3) {
usage(argv[0]);
return -1;
}
mode = argv[optind];
assembly = preprocess(argv[optind + 1], &size);
if (!assembly) {
usage(argv[0]);
return -1;
}
if (args_left == 3) {
char *temp, *src = argv[optind + 2];
address = strtoull(src, &temp, 16);
if (temp == src || *temp != '\0' || errno == ERANGE) {
printf("ERROR: invalid address argument, quit!\n");
return -2;
}
}
for (i = 0; all_archs[i].name; i++) {
if (!strcmp(all_archs[i].name, mode)) {
arch = all_archs[i].arch;
err = cs_open(all_archs[i].arch, all_archs[i].mode, &handle);
if (!err) {
md = all_archs[i].mode;
if (strstr (mode, "att")) {
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
}
// turn on SKIPDATA mode
if (skipdata)
cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
}
break;
}
}
if (arch == CS_ARCH_ALL) {
printf("ERROR: Invalid <arch+mode>: \"%s\", quit!\n", mode);
usage(argv[0]);
return -1;
}
if (err) {
printf("ERROR: Failed on cs_open(), quit!\n");
usage(argv[0]);
return -1;
}
if (detail_flag) {
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
}
if (unsigned_flag) {
cs_option(handle, CS_OPT_UNSIGNED, CS_OPT_ON);
}
if (custom_reg_alias) {
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_CS_REG_ALIAS);
}
if (set_real_detail) {
cs_option(handle, CS_OPT_DETAIL, CS_OPT_DETAIL_REAL);
}
if (dev_fuzz) {
run_dev_fuzz(handle, assembly, size);
cs_close(&handle);
return 0;
}
count = cs_disasm(handle, assembly, size, address, 0, &insn);
if (count > 0) {
for (i = 0; i < count; i++) {
int j;
printf("%2"PRIx64" ", insn[i].address);
for (j = 0; j < insn[i].size; j++) {
if (j > 0)
putchar(' ');
printf("%02x", insn[i].bytes[j]);
}
// Align instruction when it varies in size.
// ex: x86, s390x or compressed riscv
if (arch == CS_ARCH_RISCV) {
for (; j < 4; j++) {
printf(" ");
}
} else if (arch == CS_ARCH_X86) {
for (; j < 16; j++) {
printf(" ");
}
} else if (arch == CS_ARCH_SYSZ) {
for (; j < 6; j++) {
printf(" ");
}
}
printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
if (detail_flag) {
print_details(handle, arch, md, &insn[i]);
}
}
cs_free(insn, count);
free(assembly);
} else {
printf("ERROR: invalid assembly code\n");
cs_close(&handle);
free(assembly);
return(-4);
}
cs_close(&handle);
return 0;
}

26
thirdparty/capstone/cstool/cstool.h vendored Normal file
View File

@@ -0,0 +1,26 @@
#ifndef CAPSTONE_CSTOOL_CSTOOL_H_
#define CAPSTONE_CSTOOL_CSTOOL_H_
void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins);
void print_insn_detail_arm(csh handle, cs_insn *ins);
void print_insn_detail_aarch64(csh handle, cs_insn *ins);
void print_insn_detail_mips(csh handle, cs_insn *ins);
void print_insn_detail_ppc(csh handle, cs_insn *ins);
void print_insn_detail_sparc(csh handle, cs_insn *ins);
void print_insn_detail_sysz(csh handle, cs_insn *ins);
void print_insn_detail_xcore(csh handle, cs_insn *ins);
void print_insn_detail_m68k(csh handle, cs_insn *ins);
void print_insn_detail_tms320c64x(csh handle, cs_insn *ins);
void print_insn_detail_m680x(csh handle, cs_insn *ins);
void print_insn_detail_evm(csh handle, cs_insn *ins);
void print_insn_detail_riscv(csh handle, cs_insn *ins);
void print_insn_detail_wasm(csh handle, cs_insn *ins);
void print_insn_detail_mos65xx(csh handle, cs_insn *ins);
void print_insn_detail_bpf(csh handle, cs_insn *ins);
void print_insn_detail_sh(csh handle, cs_insn *ins);
void print_insn_detail_tricore(csh handle, cs_insn *ins);
void print_insn_detail_alpha(csh handle, cs_insn *ins);
void print_insn_detail_hppa(csh handle, cs_insn *ins);
void print_insn_detail_loongarch(csh handle, cs_insn *ins);
#endif //CAPSTONE_CSTOOL_CSTOOL_H_

View File

@@ -0,0 +1,244 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
#include "capstone/aarch64.h"
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_aarch64(csh handle, cs_insn *ins)
{
cs_aarch64 *aarch64;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
uint8_t access;
// detail can be NULL if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
aarch64 = &(ins->detail->aarch64);
if (aarch64->op_count)
printf("\top_count: %u\n", aarch64->op_count);
for (i = 0; i < aarch64->op_count; i++) {
cs_aarch64_op *op = &(aarch64->operands[i]);
switch(op->type) {
default:
break;
case AARCH64_OP_REG:
printf("\t\toperands[%u].type: REG = %s%s\n", i, cs_reg_name(handle, op->reg), op->is_vreg ? " (vreg)" : "");
if (op->is_list_member) {
printf("\t\toperands[%u].is_list_member: true\n", i);
}
break;
case AARCH64_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case AARCH64_OP_FP:
#if defined(_KERNEL_MODE)
// Issue #681: Windows kernel does not support formatting float point
printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
#else
printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
#endif
break;
case AARCH64_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != AARCH64_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != AARCH64_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
if (ins->detail->aarch64.post_index)
printf("\t\t\tpost-indexed: true\n");
break;
case AARCH64_OP_SME:
printf("\t\toperands[%u].type: SME_MATRIX\n", i);
printf("\t\toperands[%u].sme.type: %d\n", i, op->sme.type);
if (op->sme.tile != AARCH64_REG_INVALID)
printf("\t\toperands[%u].sme.tile: %s\n", i, cs_reg_name(handle, op->sme.tile));
if (op->sme.slice_reg != AARCH64_REG_INVALID)
printf("\t\toperands[%u].sme.slice_reg: %s\n", i, cs_reg_name(handle, op->sme.slice_reg));
if (op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID || op->sme.slice_offset.imm_range.first != AARCH64_SLICE_IMM_RANGE_INVALID) {
printf("\t\toperands[%u].sme.slice_offset: ", i);
if (op->sme.has_range_offset)
printf("%hhd:%hhd\n", op->sme.slice_offset.imm_range.first, op->sme.slice_offset.imm_range.offset);
else
printf("%d\n", op->sme.slice_offset.imm);
}
if (op->sme.slice_reg != AARCH64_REG_INVALID || op->sme.slice_offset.imm != AARCH64_SLICE_IMM_INVALID)
printf("\t\toperands[%u].sme.is_vertical: %s\n", i, (op->sme.is_vertical ? "true" : "false"));
break;
case AARCH64_OP_PRED:
printf("\t\toperands[%u].type: PREDICATE\n", i);
if (op->pred.reg != AARCH64_REG_INVALID)
printf("\t\toperands[%u].pred.reg: %s\n", i, cs_reg_name(handle, op->pred.reg));
if (op->pred.vec_select != AARCH64_REG_INVALID)
printf("\t\toperands[%u].pred.vec_select: %s\n", i, cs_reg_name(handle, op->pred.vec_select));
if (op->pred.imm_index != -1)
printf("\t\toperands[%u].pred.imm_index: %d\n", i, op->pred.imm_index);
break;
case AARCH64_OP_CIMM:
printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm);
break;
case AARCH64_OP_SYSREG:
printf("\t\toperands[%u].type: SYS REG:\n", i);
switch (op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_REG_MRS:
printf("\t\toperands[%u].subtype: REG_MRS = 0x%x\n", i, op->sysop.reg.sysreg);
break;
case AARCH64_OP_REG_MSR:
printf("\t\toperands[%u].subtype: REG_MSR = 0x%x\n", i, op->sysop.reg.sysreg);
break;
case AARCH64_OP_TLBI:
printf("\t\toperands[%u].subtype TLBI = 0x%x\n", i, op->sysop.reg.tlbi);
break;
case AARCH64_OP_IC:
printf("\t\toperands[%u].subtype IC = 0x%x\n", i, op->sysop.reg.ic);
break;
}
break;
case AARCH64_OP_SYSALIAS:
printf("\t\toperands[%u].type: SYS ALIAS:\n", i);
switch (op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_SVCR:
if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRSM)
printf("\t\t\toperands[%u].svcr: BIT = SM\n", i);
else if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRZA)
printf("\t\t\toperands[%u].svcr: BIT = ZA\n", i);
else if(op->sysop.alias.svcr == AARCH64_SVCR_SVCRSMZA)
printf("\t\t\toperands[%u].svcr: BIT = SM & ZA\n", i);
break;
case AARCH64_OP_AT:
printf("\t\toperands[%u].subtype AT = 0x%x\n", i, op->sysop.alias.at);
break;
case AARCH64_OP_DB:
printf("\t\toperands[%u].subtype DB = 0x%x\n", i, op->sysop.alias.db);
break;
case AARCH64_OP_DC:
printf("\t\toperands[%u].subtype DC = 0x%x\n", i, op->sysop.alias.dc);
break;
case AARCH64_OP_ISB:
printf("\t\toperands[%u].subtype ISB = 0x%x\n", i, op->sysop.alias.isb);
break;
case AARCH64_OP_TSB:
printf("\t\toperands[%u].subtype TSB = 0x%x\n", i, op->sysop.alias.tsb);
break;
case AARCH64_OP_PRFM:
printf("\t\toperands[%u].subtype PRFM = 0x%x\n", i, op->sysop.alias.prfm);
break;
case AARCH64_OP_SVEPRFM:
printf("\t\toperands[%u].subtype SVEPRFM = 0x%x\n", i, op->sysop.alias.sveprfm);
break;
case AARCH64_OP_RPRFM:
printf("\t\toperands[%u].subtype RPRFM = 0x%x\n", i, op->sysop.alias.rprfm);
break;
case AARCH64_OP_PSTATEIMM0_15:
printf("\t\toperands[%u].subtype PSTATEIMM0_15 = 0x%x\n", i, op->sysop.alias.pstateimm0_15);
break;
case AARCH64_OP_PSTATEIMM0_1:
printf("\t\toperands[%u].subtype PSTATEIMM0_1 = 0x%x\n", i, op->sysop.alias.pstateimm0_1);
break;
case AARCH64_OP_PSB:
printf("\t\toperands[%u].subtype PSB = 0x%x\n", i, op->sysop.alias.psb);
break;
case AARCH64_OP_BTI:
printf("\t\toperands[%u].subtype BTI = 0x%x\n", i, op->sysop.alias.bti);
break;
case AARCH64_OP_SVEPREDPAT:
printf("\t\toperands[%u].subtype SVEPREDPAT = 0x%x\n", i, op->sysop.alias.svepredpat);
break;
case AARCH64_OP_SVEVECLENSPECIFIER:
printf("\t\toperands[%u].subtype SVEVECLENSPECIFIER = 0x%x\n", i, op->sysop.alias.sveveclenspecifier);
break;
}
break;
case AARCH64_OP_SYSIMM:
printf("\t\toperands[%u].type: SYS IMM:\n", i);
switch(op->sysop.sub_type) {
default:
printf("Sub type %d not handled.\n", op->sysop.sub_type);
break;
case AARCH64_OP_EXACTFPIMM:
printf("\t\toperands[%u].subtype EXACTFPIMM = %d\n", i, op->sysop.imm.exactfpimm);
break;
case AARCH64_OP_DBNXS:
printf("\t\toperands[%u].subtype DBNXS = %d\n", i, op->sysop.imm.dbnxs);
break;
}
break;
}
access = op->access;
switch(access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
if (op->shift.type != AARCH64_SFT_INVALID &&
op->shift.value)
printf("\t\t\tShift: type = %u, value = %u\n",
op->shift.type, op->shift.value);
if (op->ext != AARCH64_EXT_INVALID)
printf("\t\t\tExt: %u\n", op->ext);
if (op->vas != AARCH64LAYOUT_INVALID)
printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
if (op->vector_index != -1)
printf("\t\t\tVector Index: %u\n", op->vector_index);
}
if (aarch64->update_flags)
printf("\tUpdate-flags: True\n");
if (ins->detail->writeback)
printf("\tWrite-back: True\n");
if (aarch64->cc != AArch64CC_Invalid)
printf("\tCode-condition: %u\n", aarch64->cc);
// Print out all registers accessed by this instruction (either implicit or explicit)
if (!cs_regs_access(handle, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
}

View File

@@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_alpha(csh handle, cs_insn *ins)
{
cs_alpha *alpha;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
alpha = &(ins->detail->alpha);
if (alpha->op_count)
printf("\top_count: %u\n", alpha->op_count);
for (i = 0; i < alpha->op_count; i++) {
cs_alpha_op *op = &(alpha->operands[i]);
switch ((int)op->type) {
default:
break;
case ALPHA_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i,
cs_reg_name(handle, op->reg));
break;
case ALPHA_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i,
op->imm);
break;
}
// Print out all registers accessed by this instruction (either implicit or
// explicit)
if (!cs_regs_access(handle, ins, regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for (i = 0; i < regs_read_count; i++) {
printf(" %s",
cs_reg_name(handle,
regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for (i = 0; i < regs_write_count; i++) {
printf(" %s",
cs_reg_name(handle,
regs_write[i]));
}
printf("\n");
}
}
}
}

200
thirdparty/capstone/cstool/cstool_arm.c vendored Normal file
View File

@@ -0,0 +1,200 @@
#include "capstone/arm.h"
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_arm(csh handle, cs_insn *ins)
{
cs_arm *arm;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
arm = &(ins->detail->arm);
if (arm->op_count)
printf("\top_count: %u\n", arm->op_count);
for (i = 0; i < arm->op_count; i++) {
cs_arm_op *op = &(arm->operands[i]);
switch((int)op->type) {
default:
break;
case ARM_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case ARM_OP_IMM:
if (op->imm < 0)
printf("\t\toperands[%u].type: IMM = -0x%" PRIx64 "\n", i, -(op->imm));
else
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case ARM_OP_PRED:
printf("\t\toperands[%u].type: PRED = %d\n", i, op->pred);
break;
case ARM_OP_FP:
#if defined(_KERNEL_MODE)
// Issue #681: Windows kernel does not support formatting float point
printf("\t\toperands[%u].type: FP = <float_point_unsupported>\n", i);
#else
printf("\t\toperands[%u].type: FP = %f\n", i, op->fp);
#endif
break;
case ARM_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != ARM_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != ARM_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.scale != 1)
printf("\t\t\toperands[%u].mem.scale: %d\n", i, op->mem.scale);
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
if (op->mem.align != 0)
printf("\t\t\toperands[%u].mem.align: 0x%x\n", i, op->mem.align);
if (op->mem.lshift != 0)
printf("\t\t\toperands[%u].mem.lshift: 0x%x\n", i, op->mem.lshift);
break;
case ARM_OP_PIMM:
printf("\t\toperands[%u].type: P-IMM = %" PRIu64 "\n", i, op->imm);
break;
case ARM_OP_CIMM:
printf("\t\toperands[%u].type: C-IMM = %" PRIu64 "\n", i, op->imm);
break;
case ARM_OP_SETEND:
printf("\t\toperands[%u].type: SETEND = %s\n", i, op->setend == ARM_SETEND_BE? "be" : "le");
break;
case ARM_OP_SYSM:
printf("\t\toperands[%u].type: SYSM = 0x%" PRIx16 "\n", i, op->sysop.sysm);
printf("\t\toperands[%u].type: MASK = %" PRIu8 "\n", i, op->sysop.msr_mask);
break;
case ARM_OP_SYSREG:
printf("\t\toperands[%u].type: SYSREG = %s\n", i, cs_reg_name(handle, (uint32_t) op->sysop.reg.mclasssysreg));
printf("\t\toperands[%u].type: MASK = %" PRIu8 "\n", i, op->sysop.msr_mask);
break;
case ARM_OP_BANKEDREG:
// FIXME: Printing the name is currenliy not supported if the encodings overlap
// with system registers.
printf("\t\toperands[%u].type: BANKEDREG = %" PRIu32 "\n", i, (uint32_t) op->sysop.reg.bankedreg);
if (op->sysop.msr_mask != UINT8_MAX)
printf("\t\toperands[%u].type: MASK = %" PRIu8 "\n", i, op->sysop.msr_mask);
case ARM_OP_SPSR:
case ARM_OP_CPSR: {
const char type = op->type == ARM_OP_SPSR ? 'S' : 'C';
printf("\t\toperands[%u].type: %cPSR = ", i, type);
uint16_t field = op->sysop.psr_bits;
if ((field & ARM_FIELD_SPSR_F) || (field & ARM_FIELD_CPSR_F))
printf("f");
if ((field & ARM_FIELD_SPSR_S) || (field & ARM_FIELD_CPSR_S))
printf("s");
if ((field & ARM_FIELD_SPSR_X) || (field & ARM_FIELD_CPSR_X))
printf("x");
if ((field & ARM_FIELD_SPSR_C) || (field & ARM_FIELD_CPSR_C))
printf("c");
printf("\n");
printf("\t\toperands[%u].type: MASK = %" PRIu8 "\n", i, op->sysop.msr_mask);
break;
}
}
if (op->neon_lane != -1) {
printf("\t\toperands[%u].neon_lane = %u\n", i, op->neon_lane);
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
if (op->shift.type < ARM_SFT_ASR_REG)
// shift with constant value
printf("\t\t\tShift: %u = %u\n", op->shift.type, op->shift.value);
else
// shift with register
printf("\t\t\tShift: %u = %s\n", op->shift.type,
cs_reg_name(handle, op->shift.value));
}
if (op->vector_index != -1) {
printf("\t\toperands[%u].vector_index = %u\n", i, op->vector_index);
}
if (op->subtracted)
printf("\t\tSubtracted: True\n");
}
if (arm->cc != ARMCC_AL && arm->cc != ARMCC_UNDEF)
printf("\tCode condition: %u\n", arm->cc);
if (arm->vcc != ARMVCC_None)
printf("\tVector code condition: %u\n", arm->vcc);
if (arm->update_flags)
printf("\tUpdate-flags: True\n");
if (ins->detail->writeback) {
printf("\tWrite-back: True\n");
printf("\tPost index: %s\n", arm->post_index ? "True" : "False");
}
if (arm->cps_mode)
printf("\tCPSI-mode: %u\n", arm->cps_mode);
if (arm->cps_flag)
printf("\tCPSI-flag: %u\n", arm->cps_flag);
if (arm->vector_data)
printf("\tVector-data: %u\n", arm->vector_data);
if (arm->vector_size != 0)
printf("\tVector-size: %u\n", arm->vector_size);
if (arm->usermode)
printf("\tUser-mode: True\n");
if (arm->mem_barrier)
printf("\tMemory-barrier: %u\n", arm->mem_barrier);
if (arm->pred_mask)
printf("\tPredicate Mask: 0x%x\n", arm->pred_mask);
// Print out all registers accessed by this instruction (either implicit or explicit)
if (!cs_regs_access(handle, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
}

79
thirdparty/capstone/cstool/cstool_bpf.c vendored Normal file
View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <capstone/capstone.h>
#include <capstone/platform.h>
#include "cstool.h"
static const char * ext_name[] = {
[BPF_EXT_LEN] = "#len",
};
void print_insn_detail_bpf(csh handle, cs_insn *ins)
{
unsigned i;
cs_bpf *bpf;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
bpf = &(ins->detail->bpf);
printf("\tOperand count: %u\n", bpf->op_count);
for (i = 0; i < bpf->op_count; i++) {
cs_bpf_op *op = &(bpf->operands[i]);
printf("\t\toperands[%u].type: ", i);
switch (op->type) {
case BPF_OP_INVALID:
printf("INVALID\n");
break;
case BPF_OP_REG:
printf("REG = %s\n", cs_reg_name(handle, op->reg));
break;
case BPF_OP_IMM:
printf("IMM = 0x%" PRIx64 "\n", op->imm);
break;
case BPF_OP_OFF:
printf("OFF = +0x%x\n", op->off);
break;
case BPF_OP_MEM:
printf("MEM\n");
if (op->mem.base != BPF_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
case BPF_OP_MMEM:
printf("MMEM = M[0x%x]\n", op->mmem);
break;
case BPF_OP_MSH:
printf("MSH = 4*([0x%x]&0xf)\n", op->msh);
break;
case BPF_OP_EXT:
printf("EXT = %s\n", ext_name[op->ext]);
break;
}
}
/* print all registers that are involved in this instruction */
if (!cs_regs_access(handle, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++)
printf(" %s", cs_reg_name(handle, regs_read[i]));
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++)
printf(" %s", cs_reg_name(handle, regs_write[i]));
printf("\n");
}
}
}

25
thirdparty/capstone/cstool/cstool_evm.c vendored Normal file
View File

@@ -0,0 +1,25 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_evm(csh handle, cs_insn *ins)
{
cs_evm *evm;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
evm = &(ins->detail->evm);
if (evm->pop)
printf("\tPop: %u\n", evm->pop);
if (evm->push)
printf("\tPush: %u\n", evm->push);
if (evm->fee)
printf("\tGas fee: %u\n", evm->fee);
}

View File

@@ -0,0 +1,89 @@
#include <stdio.h>
#include <capstone/capstone.h>
#include <capstone/platform.h>
#include "cstool.h"
#include "limits.h"
void print_insn_detail_hppa(csh handle, cs_insn *ins)
{
cs_hppa *hppa;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
if (ins->detail == NULL)
return;
hppa = &ins->detail->hppa;
printf("\top_count: %u\n", hppa->op_count);
for (unsigned i = 0; i < hppa->op_count; i++) {
cs_hppa_op *op = &(hppa->operands[i]);
uint64_t target_addr;
switch (op->type) {
default:
break;
case HPPA_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i,
cs_reg_name(handle, op->reg));
break;
case HPPA_OP_IMM:
if (op->imm < 0)
printf("\t\toperands[%u].type: IMM = -0x%" PRIx64
"\n",
i, -(op->imm));
else
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64
"\n",
i, op->imm);
break;
case HPPA_OP_IDX_REG:
printf("\t\toperands[%u].type: IDX_REG = %s\n", i,
cs_reg_name(handle, op->reg));
break;
case HPPA_OP_DISP:
if (op->imm < 0)
printf("\t\toperands[%u].type: DISP = -0x%" PRIx64
"\n",
i, -(op->imm));
else
printf("\t\toperands[%u].type: DISP = 0x%" PRIx64
"\n",
i, op->imm);
break;
case HPPA_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.space != HPPA_REG_INVALID) {
printf("\t\t\toperands[%u].mem.space: REG = %s\n",
i, cs_reg_name(handle, op->mem.space));
}
printf("\t\t\toperands[%u].mem.base: REG = %s\n", i,
cs_reg_name(handle, op->mem.base));
break;
case HPPA_OP_TARGET:
printf("\t\toperands[%u].type: ", i);
target_addr = ins->address + op->imm;
printf("TARGET = 0x%" PRIx64 "\n", target_addr);
break;
}
}
if (!cs_regs_access(handle, ins, regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for (unsigned i = 0; i < regs_read_count; i++)
printf(" %s",
cs_reg_name(handle, regs_read[i]));
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for (unsigned i = 0; i < regs_write_count; i++)
printf(" %s",
cs_reg_name(handle, regs_write[i]));
printf("\n");
}
}
}

View File

@@ -0,0 +1,91 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
/* Jiajie Chen <c@jia.je>, 2013-2024 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_loongarch(csh handle, cs_insn *ins)
{
cs_loongarch *loongarch;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
uint8_t access;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
loongarch = &(ins->detail->loongarch);
if (loongarch->op_count)
printf("\top_count: %u\n", loongarch->op_count);
for (i = 0; i < loongarch->op_count; i++) {
cs_loongarch_op *op = &(loongarch->operands[i]);
switch ((int)op->type) {
default:
break;
case LOONGARCH_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i,
cs_reg_name(handle, op->reg));
break;
case LOONGARCH_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%lx\n", i,
(long)op->imm);
break;
case LOONGARCH_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != LOONGARCH_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != LOONGARCH_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%lx\n",
i, (long)op->mem.disp);
break;
}
access = op->access;
switch (access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
if (ins->detail->writeback)
printf("\tWrite-back: True\n");
/* print all registers that are involved in this instruction */
if (!cs_regs_access(handle, ins, regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for (i = 0; i < regs_read_count; i++)
printf(" %s",
cs_reg_name(handle, regs_read[i]));
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for (i = 0; i < regs_write_count; i++)
printf(" %s",
cs_reg_name(handle, regs_write[i]));
printf("\n");
}
}
}

View File

@@ -0,0 +1,154 @@
/* Capstone Disassembly Engine */
/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
static const char *s_access[] = {
"UNCHANGED", "READ", "WRITE", "READ | WRITE",
};
static void print_read_write_regs(csh handle, cs_detail *detail)
{
int i;
if (detail->regs_read_count > 0) {
printf("\treading from regs: ");
for (i = 0; i < detail->regs_read_count; ++i) {
if (i > 0)
printf(", ");
printf("%s", cs_reg_name(handle, detail->regs_read[i]));
}
printf("\n");
}
if (detail->regs_write_count > 0) {
printf("\twriting to regs: ");
for (i = 0; i < detail->regs_write_count; ++i) {
if (i > 0)
printf(", ");
printf("%s", cs_reg_name(handle,
detail->regs_write[i]));
}
printf("\n");
}
}
void print_insn_detail_m680x(csh handle, cs_insn *insn)
{
cs_detail *detail = insn->detail;
cs_m680x *m680x = NULL;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is
// turned ON
if (detail == NULL)
return;
m680x = &detail->m680x;
if (m680x->op_count)
printf("\top_count: %u\n", m680x->op_count);
for (i = 0; i < m680x->op_count; i++) {
cs_m680x_op *op = &(m680x->operands[i]);
const char *comment;
switch ((int)op->type) {
default:
break;
case M680X_OP_REGISTER:
comment = "";
if ((i == 0 && m680x->flags & M680X_FIRST_OP_IN_MNEM) ||
(i == 1 && m680x->flags &
M680X_SECOND_OP_IN_MNEM))
comment = " (in mnemonic)";
printf("\t\toperands[%u].type: REGISTER = %s%s\n", i,
cs_reg_name(handle, op->reg), comment);
break;
case M680X_OP_CONSTANT:
printf("\t\toperands[%u].type: CONSTANT = %u\n", i,
op->const_val);
break;
case M680X_OP_IMMEDIATE:
printf("\t\toperands[%u].type: IMMEDIATE = #%d\n", i,
op->imm);
break;
case M680X_OP_DIRECT:
printf("\t\toperands[%u].type: DIRECT = 0x%02x\n", i,
op->direct_addr);
break;
case M680X_OP_EXTENDED:
printf("\t\toperands[%u].type: EXTENDED %s = 0x%04x\n",
i, op->ext.indirect ? "INDIRECT" : "",
op->ext.address);
break;
case M680X_OP_RELATIVE:
printf("\t\toperands[%u].type: RELATIVE = 0x%04x\n", i,
op->rel.address);
break;
case M680X_OP_INDEXED:
printf("\t\toperands[%u].type: INDEXED%s\n", i,
(op->idx.flags & M680X_IDX_INDIRECT) ?
" INDIRECT" : "");
if (op->idx.base_reg != M680X_REG_INVALID)
printf("\t\t\tbase register: %s\n",
cs_reg_name(handle, op->idx.base_reg));
if (op->idx.offset_reg != M680X_REG_INVALID)
printf("\t\t\toffset register: %s\n",
cs_reg_name(handle, op->idx.offset_reg));
if ((op->idx.offset_bits != 0) &&
(op->idx.offset_reg == M680X_REG_INVALID) &&
!op->idx.inc_dec) {
printf("\t\t\toffset: %d\n", op->idx.offset);
if (op->idx.base_reg == M680X_REG_PC)
printf("\t\t\toffset address: 0x%x\n",
op->idx.offset_addr);
printf("\t\t\toffset bits: %u\n",
op->idx.offset_bits);
}
if (op->idx.inc_dec) {
const char *post_pre = op->idx.flags &
M680X_IDX_POST_INC_DEC ? "post" : "pre";
const char *inc_dec = (op->idx.inc_dec > 0) ?
"increment" : "decrement";
printf("\t\t\t%s %s: %d\n", post_pre, inc_dec,
abs(op->idx.inc_dec));
}
break;
}
if (op->size != 0)
printf("\t\t\tsize: %u\n", op->size);
if (op->access != CS_AC_INVALID)
printf("\t\t\taccess: %s\n", s_access[op->access]);
}
print_read_write_regs(handle, detail);
}

120
thirdparty/capstone/cstool/cstool_m68k.c vendored Normal file
View File

@@ -0,0 +1,120 @@
//
// cstool_m68k.c
//
//
// Created by YUHANG TANG on 26/10/16.
//
//
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
static const char* s_addressing_modes[] = {
"<invalid mode>",
"Register Direct - Data",
"Register Direct - Address",
"Register Indirect - Address",
"Register Indirect - Address with Postincrement",
"Register Indirect - Address with Predecrement",
"Register Indirect - Address with Displacement",
"Address Register Indirect With Index - 8-bit displacement",
"Address Register Indirect With Index - Base displacement",
"Memory indirect - Postindex",
"Memory indirect - Preindex",
"Program Counter Indirect - with Displacement",
"Program Counter Indirect with Index - with 8-Bit Displacement",
"Program Counter Indirect with Index - with Base Displacement",
"Program Counter Memory Indirect - Postindexed",
"Program Counter Memory Indirect - Preindexed",
"Absolute Data Addressing - Short",
"Absolute Data Addressing - Long",
"Immediate value",
};
static void print_read_write_regs(cs_detail* detail, csh handle)
{
int i;
for (i = 0; i < detail->regs_read_count; ++i) {
uint16_t reg_id = detail->regs_read[i];
const char* reg_name = cs_reg_name(handle, reg_id);
printf("\treading from reg: %s\n", reg_name);
}
for (i = 0; i < detail->regs_write_count; ++i) {
uint16_t reg_id = detail->regs_write[i];
const char* reg_name = cs_reg_name(handle, reg_id);
printf("\twriting to reg: %s\n", reg_name);
}
}
void print_insn_detail_m68k(csh handle, cs_insn *ins)
{
cs_m68k* m68k;
cs_detail* detail;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
detail = ins->detail;
m68k = &detail->m68k;
if (m68k->op_count)
printf("\top_count: %u\n", m68k->op_count);
print_read_write_regs(detail, handle);
printf("\tgroups_count: %u\n", detail->groups_count);
for (i = 0; i < m68k->op_count; i++) {
cs_m68k_op* op = &(m68k->operands[i]);
switch((int)op->type) {
default:
break;
case M68K_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case M68K_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, (int)op->imm);
break;
case M68K_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base_reg != M68K_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base_reg));
if (op->mem.index_reg != M68K_REG_INVALID) {
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index_reg));
printf("\t\t\toperands[%u].mem.index: size = %c\n",
i, op->mem.index_size ? 'l' : 'w');
}
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
if (op->mem.scale != 0)
printf("\t\t\toperands[%u].mem.scale: %d\n", i, op->mem.scale);
printf("\t\taddress mode: %s\n", s_addressing_modes[op->address_mode]);
break;
case M68K_OP_FP_SINGLE:
printf("\t\toperands[%u].type: FP_SINGLE\n", i);
printf("\t\t\toperands[%u].simm: %f\n", i, op->simm);
break;
case M68K_OP_FP_DOUBLE:
printf("\t\toperands[%u].type: FP_DOUBLE\n", i);
printf("\t\t\toperands[%u].dimm: %lf\n", i, op->dimm);
break;
}
}
}

View File

@@ -0,0 +1,46 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_mips(csh handle, cs_insn *ins)
{
int i;
cs_mips *mips;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
mips = &(ins->detail->mips);
if (mips->op_count)
printf("\top_count: %u\n", mips->op_count);
for (i = 0; i < mips->op_count; i++) {
cs_mips_op *op = &(mips->operands[i]);
switch((int)op->type) {
default:
break;
case MIPS_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case MIPS_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case MIPS_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != MIPS_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
break;
}
}
}

View File

@@ -0,0 +1,98 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
static const char *get_am_name(mos65xx_address_mode mode)
{
switch(mode) {
default:
case MOS65XX_AM_NONE:
return "No address mode";
case MOS65XX_AM_IMP:
return "implied";
case MOS65XX_AM_ACC:
return "accumulator";
case MOS65XX_AM_IMM:
return "immediate value";
case MOS65XX_AM_REL:
return "relative";
case MOS65XX_AM_INT:
return "interrupt signature";
case MOS65XX_AM_BLOCK:
return "block move";
case MOS65XX_AM_ZP:
return "zero page";
case MOS65XX_AM_ZP_X:
return "zero page indexed with x";
case MOS65XX_AM_ZP_Y:
return "zero page indexed with y";
case MOS65XX_AM_ZP_REL:
return "relative bit branch";
case MOS65XX_AM_ZP_IND:
return "zero page indirect";
case MOS65XX_AM_ZP_X_IND:
return "zero page indexed with x indirect";
case MOS65XX_AM_ZP_IND_Y:
return "zero page indirect indexed with y";
case MOS65XX_AM_ZP_IND_LONG:
return "zero page indirect long";
case MOS65XX_AM_ZP_IND_LONG_Y:
return "zero page indirect long indexed with y";
case MOS65XX_AM_ABS:
return "absolute";
case MOS65XX_AM_ABS_X:
return "absolute indexed with x";
case MOS65XX_AM_ABS_Y:
return "absolute indexed with y";
case MOS65XX_AM_ABS_IND:
return "absolute indirect";
case MOS65XX_AM_ABS_X_IND:
return "absolute indexed with x indirect";
case MOS65XX_AM_ABS_IND_LONG:
return "absolute indirect long";
case MOS65XX_AM_ABS_LONG:
return "absolute long";
case MOS65XX_AM_ABS_LONG_X:
return "absolute long indexed with x";
case MOS65XX_AM_SR:
return "stack relative";
case MOS65XX_AM_SR_IND_Y:
return "stack relative indirect indexed with y";
}
}
void print_insn_detail_mos65xx(csh handle, cs_insn *ins)
{
int i;
cs_mos65xx *mos65xx;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
mos65xx = &(ins->detail->mos65xx);
printf("\taddress mode: %s\n", get_am_name(mos65xx->am));
printf("\tmodifies flags: %s\n", mos65xx->modifies_flags ? "true": "false");
if (mos65xx->op_count)
printf("\top_count: %u\n", mos65xx->op_count);
for (i = 0; i < mos65xx->op_count; i++) {
cs_mos65xx_op *op = &(mos65xx->operands[i]);
switch((int)op->type) {
default:
break;
case MOS65XX_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case MOS65XX_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
break;
case MOS65XX_OP_MEM:
printf("\t\toperands[%u].type: MEM = 0x%x\n", i, op->mem);
break;
}
}
}

View File

@@ -0,0 +1,182 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
#include <stdio.h>
#include <capstone/capstone.h>
#include "capstone/ppc.h"
#include "cstool.h"
static const char* get_pred_name(ppc_pred pred)
{
switch(pred) {
default:
return ("invalid");
case PPC_PRED_LT:
case PPC_PRED_LT_MINUS:
case PPC_PRED_LT_PLUS:
case PPC_PRED_LT_RESERVED:
return ("lt");
case PPC_PRED_LE:
case PPC_PRED_LE_MINUS:
case PPC_PRED_LE_PLUS:
case PPC_PRED_LE_RESERVED:
return ("le");
case PPC_PRED_EQ:
case PPC_PRED_EQ_MINUS:
case PPC_PRED_EQ_PLUS:
case PPC_PRED_EQ_RESERVED:
return ("eq");
case PPC_PRED_GE:
case PPC_PRED_GE_MINUS:
case PPC_PRED_GE_PLUS:
case PPC_PRED_GE_RESERVED:
return ("ge");
case PPC_PRED_GT:
case PPC_PRED_GT_MINUS:
case PPC_PRED_GT_PLUS:
case PPC_PRED_GT_RESERVED:
return ("gt");
case PPC_PRED_NE:
case PPC_PRED_NE_MINUS:
case PPC_PRED_NE_PLUS:
case PPC_PRED_NE_RESERVED:
return ("ne");
case PPC_PRED_UN: // PPC_PRED_SO
case PPC_PRED_UN_MINUS:
case PPC_PRED_UN_PLUS:
case PPC_PRED_UN_RESERVED:
return ("so/un");
case PPC_PRED_NU: // PPC_PRED_NS
case PPC_PRED_NU_MINUS:
case PPC_PRED_NU_PLUS:
case PPC_PRED_NU_RESERVED:
return ("ns/nu");
case PPC_PRED_NZ:
case PPC_PRED_NZ_MINUS:
case PPC_PRED_NZ_PLUS:
case PPC_PRED_NZ_RESERVED:
return ("nz");
case PPC_PRED_Z:
case PPC_PRED_Z_MINUS:
case PPC_PRED_Z_PLUS:
case PPC_PRED_Z_RESERVED:
return ("z");
case PPC_PRED_BIT_SET:
return "bit-set";
case PPC_PRED_BIT_UNSET:
return "bit-unset";
}
}
static const char *get_pred_hint(ppc_br_hint at) {
switch (at) {
default:
return "invalid";
case PPC_BR_NOT_GIVEN:
return "not-given";
case PPC_BR_TAKEN:
return "likely-taken";
case PPC_BR_NOT_TAKEN:
return "likely-not-taken";
case PPC_BR_RESERVED:
return "reserved";
}
}
void print_insn_detail_ppc(csh handle, cs_insn *ins)
{
cs_ppc *ppc;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
ppc = &(ins->detail->ppc);
if (ppc->op_count)
printf("\top_count: %u\n", ppc->op_count);
for (i = 0; i < ppc->op_count; i++) {
cs_ppc_op *op = &(ppc->operands[i]);
switch((int)op->type) {
default:
break;
case PPC_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case PPC_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%"PRIx64"\n", i, op->imm);
break;
case PPC_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != PPC_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.offset != PPC_REG_INVALID)
printf("\t\t\toperands[%u].mem.offset: REG = %s\n", i,
cs_reg_name(handle, op->mem.offset));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
if (ppc->bc.pred_cr != PPC_PRED_INVALID ||
ppc->bc.pred_ctr != PPC_PRED_INVALID) {
printf("\tBranch:\n");
printf("\t\tbi: %u\n", ppc->bc.bi);
printf("\t\tbo: %u\n", ppc->bc.bo);
if (ppc->bc.bh != PPC_BH_INVALID)
printf("\t\tbh: %u\n", ppc->bc.bh);
if (ppc->bc.pred_cr != PPC_PRED_INVALID) {
printf("\t\tcrX: %s\n", cs_reg_name(handle, ppc->bc.crX));
printf("\t\tpred CR-bit: %s\n", get_pred_name(ppc->bc.pred_cr));
}
if (ppc->bc.pred_ctr != PPC_PRED_INVALID)
printf("\t\tpred CTR: %s\n", get_pred_name(ppc->bc.pred_ctr));
if (ppc->bc.hint != PPC_BR_NOT_GIVEN)
printf("\t\thint: %s\n", get_pred_hint(ppc->bc.hint));
}
if (ppc->bc.hint != PPC_BR_NOT_GIVEN)
printf("\tBranch hint: %u\n", ppc->bc.hint);
if (ppc->update_cr0)
printf("\tUpdate-CR0: True\n");
uint16_t *regs_read = ins->detail->regs_read;
uint16_t *regs_write = ins->detail->regs_write;
uint8_t regs_read_count = ins->detail->regs_read_count;
uint8_t regs_write_count = ins->detail->regs_write_count;
// Print out all registers accessed by this instruction (either implicit or explicit)
if (regs_read_count) {
printf("\tImplicit registers read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tImplicit registers modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}

View File

@@ -0,0 +1,59 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_riscv(csh handle, cs_insn *ins)
{
cs_riscv *riscv;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
riscv = &(ins->detail->riscv);
if (riscv->op_count)
printf("\top_count: %u\n", riscv->op_count);
for (i = 0; i < riscv->op_count; i++) {
cs_riscv_op *op = &(riscv->operands[i]);
switch((int)op->type) {
default:
break;
case RISCV_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case RISCV_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%lx\n", i, (long)op->imm);
break;
case RISCV_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != RISCV_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%lx\n", i, (long)op->mem.disp);
break;
}
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
printf("\n");
}

87
thirdparty/capstone/cstool/cstool_sh.c vendored Normal file
View File

@@ -0,0 +1,87 @@
//
// cstool_sh.c
//
// Yoshinori Sato 2022/09/07
//
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
static const char* s_addressing_modes[] = {
"<invalid mode>",
"Register Direct", /// Rn
"Register Indirect", /// @Rn
"Register Indirect with Postincrement", /// @Rn+
"Register Indirect with Predecrement", /// @-Rn
"Register Indirect with Displacement", /// @(disp,Rn)
"Indexed register indirect", /// @(R0, Rn)
"GBR indirect with displacement", /// @(disp,GBR)
"Indexed GBR indirect", /// @(R0, GBR)
"PC-relative with Displacement", /// @(disp, PC)
"Immediate value",
};
static void print_read_write_regs(cs_detail* detail, csh handle)
{
int i;
for (i = 0; i < detail->regs_read_count; ++i) {
uint16_t reg_id = detail->regs_read[i];
const char* reg_name = cs_reg_name(handle, reg_id);
printf("\treading from reg: %s\n", reg_name);
}
for (i = 0; i < detail->regs_write_count; ++i) {
uint16_t reg_id = detail->regs_write[i];
const char* reg_name = cs_reg_name(handle, reg_id);
printf("\twriting to reg: %s\n", reg_name);
}
}
void print_insn_detail_sh(csh handle, cs_insn *ins)
{
cs_detail* detail;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
detail = ins->detail;
print_read_write_regs(detail, handle);
printf("\tgroups_count: %u\n", detail->groups_count);
for (i = 0; i < detail->sh.op_count; i++) {
cs_sh_op* op = &(detail->sh.operands[i]);
switch((int)op->type) {
default:
break;
case SH_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case SH_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, (int)op->imm);
break;
case SH_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.reg != SH_REG_INVALID)
printf("\t\t\toperands[%u].mem.reg: REG = %s\n",
i, cs_reg_name(handle, op->mem.reg));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n",
i, op->mem.disp);
printf("\t\taddress mode: %s\n", s_addressing_modes[op->mem.address]);
break;
}
}
}

View File

@@ -0,0 +1,53 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_sparc(csh handle, cs_insn *ins)
{
cs_sparc *sparc;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
sparc = &(ins->detail->sparc);
if (sparc->op_count)
printf("\top_count: %u\n", sparc->op_count);
for (i = 0; i < sparc->op_count; i++) {
cs_sparc_op *op = &(sparc->operands[i]);
switch((int)op->type) {
default:
break;
case SPARC_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case SPARC_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case SPARC_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
}
}
if (sparc->cc != 0)
printf("\tCode condition: %u\n", sparc->cc);
if (sparc->hint != 0)
printf("\tHint code: %u\n", sparc->hint);
}

View File

@@ -0,0 +1,55 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_sysz(csh handle, cs_insn *ins)
{
cs_sysz *sysz;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
sysz = &(ins->detail->sysz);
if (sysz->op_count)
printf("\top_count: %u\n", sysz->op_count);
for (i = 0; i < sysz->op_count; i++) {
cs_sysz_op *op = &(sysz->operands[i]);
switch((int)op->type) {
default:
break;
case SYSZ_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case SYSZ_OP_ACREG:
printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg);
break;
case SYSZ_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case SYSZ_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != SYSZ_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != SYSZ_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.length != 0)
printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
break;
}
}
if (sysz->cc != 0)
printf("\tCode condition: %u\n", sysz->cc);
}

View File

@@ -0,0 +1,105 @@
/* Capstone Disassembler Engine */
/* By Fotis Loukos <me@fotisl.com>, 2017 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_tms320c64x(csh handle, cs_insn *ins)
{
cs_tms320c64x *tms320c64x;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
tms320c64x = &(ins->detail->tms320c64x);
if (tms320c64x->op_count)
printf("\top_count: %u\n", tms320c64x->op_count);
for (i = 0; i < tms320c64x->op_count; i++) {
cs_tms320c64x_op *op = &(tms320c64x->operands[i]);
switch((int)op->type) {
default:
break;
case TMS320C64X_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case TMS320C64X_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
break;
case TMS320C64X_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != TMS320C64X_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
printf("\t\t\toperands[%u].mem.disptype: ", i);
if(op->mem.disptype == TMS320C64X_MEM_DISP_INVALID) {
printf("Invalid\n");
printf("\t\t\toperands[%u].mem.disp: %u\n", i, op->mem.disp);
}
if(op->mem.disptype == TMS320C64X_MEM_DISP_CONSTANT) {
printf("Constant\n");
printf("\t\t\toperands[%u].mem.disp: %u\n", i, op->mem.disp);
}
if(op->mem.disptype == TMS320C64X_MEM_DISP_REGISTER) {
printf("Register\n");
printf("\t\t\toperands[%u].mem.disp: %s\n", i, cs_reg_name(handle, op->mem.disp));
}
printf("\t\t\toperands[%u].mem.unit: %u\n", i, op->mem.unit);
printf("\t\t\toperands[%u].mem.direction: ", i);
if(op->mem.direction == TMS320C64X_MEM_DIR_INVALID)
printf("Invalid\n");
if(op->mem.direction == TMS320C64X_MEM_DIR_FW)
printf("Forward\n");
if(op->mem.direction == TMS320C64X_MEM_DIR_BW)
printf("Backward\n");
printf("\t\t\toperands[%u].mem.modify: ", i);
if(op->mem.modify == TMS320C64X_MEM_MOD_INVALID)
printf("Invalid\n");
if(op->mem.modify == TMS320C64X_MEM_MOD_NO)
printf("No\n");
if(op->mem.modify == TMS320C64X_MEM_MOD_PRE)
printf("Pre\n");
if(op->mem.modify == TMS320C64X_MEM_MOD_POST)
printf("Post\n");
printf("\t\t\toperands[%u].mem.scaled: %u\n", i, op->mem.scaled);
break;
case TMS320C64X_OP_REGPAIR:
printf("\t\toperands[%u].type: REGPAIR = %s:%s\n", i, cs_reg_name(handle, op->reg + 1), cs_reg_name(handle, op->reg));
break;
}
}
printf("\tFunctional unit: ");
switch(tms320c64x->funit.unit) {
case TMS320C64X_FUNIT_D:
printf("D%u\n", tms320c64x->funit.side);
break;
case TMS320C64X_FUNIT_L:
printf("L%u\n", tms320c64x->funit.side);
break;
case TMS320C64X_FUNIT_M:
printf("M%u\n", tms320c64x->funit.side);
break;
case TMS320C64X_FUNIT_S:
printf("S%u\n", tms320c64x->funit.side);
break;
case TMS320C64X_FUNIT_NO:
printf("No Functional Unit\n");
break;
default:
printf("Unknown (Unit %u, Side %u)\n", tms320c64x->funit.unit, tms320c64x->funit.side);
break;
}
if(tms320c64x->funit.crosspath == 1)
printf("\tCrosspath: 1\n");
if(tms320c64x->condition.reg != TMS320C64X_REG_INVALID)
printf("\tCondition: [%c%s]\n", (tms320c64x->condition.zero == 1) ? '!' : ' ', cs_reg_name(handle, tms320c64x->condition.reg));
printf("\tParallel: %s\n", (tms320c64x->parallel == 1) ? "true" : "false");
printf("\n");
}

View File

@@ -0,0 +1,83 @@
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_tricore(csh handle, cs_insn *ins)
{
cs_tricore *tricore;
int i;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
tricore = &(ins->detail->tricore);
if (tricore->op_count)
printf("\top_count: %u\n", tricore->op_count);
for (i = 0; i < tricore->op_count; i++) {
cs_tricore_op *op = &(tricore->operands[i]);
switch ((int)op->type) {
default:
break;
case TRICORE_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i,
cs_reg_name(handle, op->reg));
break;
case TRICORE_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n",
i, op->imm);
break;
case TRICORE_OP_MEM:
printf("\t\toperands[%u].type: MEM\n"
"\t\t\t.mem.base: REG = %s\n"
"\t\t\t.mem.disp: 0x%" PRIx64 "\n",
i, cs_reg_name(handle, op->mem.base),
op->mem.disp);
break;
}
switch (op->access) {
default:
break;
case CS_AC_READ:
printf("\t\t\t.access: READ\n");
break;
case CS_AC_WRITE:
printf("\t\t\t.access: WRITE\n");
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\t\t.access: READ | WRITE\n");
break;
}
}
// Print out all registers accessed by this instruction (either implicit or
// explicit)
if (!cs_regs_access(handle, ins, regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for (i = 0; i < regs_read_count; i++) {
printf(" %s",
cs_reg_name(handle, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for (i = 0; i < regs_write_count; i++) {
printf(" %s",
cs_reg_name(handle, regs_write[i]));
}
printf("\n");
}
}
if (tricore->update_flags)
printf("\tUpdate-flags: True\n");
}

View File

@@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_wasm(csh handle, cs_insn *ins)
{
cs_wasm *wasm;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
wasm = &(ins->detail->wasm);
if (wasm->op_count > 0) {
unsigned int i;
printf("\tOperand count: %d\n", wasm->op_count);
for (i = 0; i < wasm->op_count; i++) {
switch (wasm->operands[i].type) {
default:
break;
case WASM_OP_INT7:
printf("\t\tOperand[%u] type: int7\n", i);
printf("\t\tOperand[%u] value: %d\n", i, wasm->operands[i].int7);
break;
case WASM_OP_UINT32:
printf("\t\tOperand[%u] type: uint32\n", i);
printf("\t\tOperand[%u] value: 0x%x\n", i, wasm->operands[i].uint32);
break;
case WASM_OP_UINT64:
printf("\t\tOperand[%u] type: uint64\n", i);
printf("\t\tOperand[%u] value: 0x%" PRIx64 "\n", i, wasm->operands[i].uint64);
break;
case WASM_OP_VARUINT32:
printf("\t\tOperand[%u] type: varuint32\n", i);
printf("\t\tOperand[%u] value: 0x%x\n", i, wasm->operands[i].varuint32);
break;
case WASM_OP_VARUINT64:
printf("\t\tOperand[%u] type: varuint64\n", i);
printf("\t\tOperand[%u] value: 0x%" PRIx64 "\n", i, wasm->operands[i].varuint64);
break;
}
printf("\t\tOperand[%u] size: %u\n", i, wasm->operands[i].size);
}
}
}

346
thirdparty/capstone/cstool/cstool_x86.c vendored Normal file
View File

@@ -0,0 +1,346 @@
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
#include <stdio.h>
#include <stdlib.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_string_hex(const char *comment, unsigned char *str, size_t len);
static const char *get_eflag_name(uint64_t flag)
{
switch(flag) {
default:
return NULL;
case X86_EFLAGS_UNDEFINED_OF:
return "UNDEF_OF";
case X86_EFLAGS_UNDEFINED_SF:
return "UNDEF_SF";
case X86_EFLAGS_UNDEFINED_ZF:
return "UNDEF_ZF";
case X86_EFLAGS_MODIFY_AF:
return "MOD_AF";
case X86_EFLAGS_UNDEFINED_PF:
return "UNDEF_PF";
case X86_EFLAGS_MODIFY_CF:
return "MOD_CF";
case X86_EFLAGS_MODIFY_SF:
return "MOD_SF";
case X86_EFLAGS_MODIFY_ZF:
return "MOD_ZF";
case X86_EFLAGS_UNDEFINED_AF:
return "UNDEF_AF";
case X86_EFLAGS_MODIFY_PF:
return "MOD_PF";
case X86_EFLAGS_UNDEFINED_CF:
return "UNDEF_CF";
case X86_EFLAGS_MODIFY_OF:
return "MOD_OF";
case X86_EFLAGS_RESET_OF:
return "RESET_OF";
case X86_EFLAGS_RESET_CF:
return "RESET_CF";
case X86_EFLAGS_RESET_DF:
return "RESET_DF";
case X86_EFLAGS_RESET_IF:
return "RESET_IF";
case X86_EFLAGS_RESET_ZF:
return "RESET_ZF";
case X86_EFLAGS_TEST_OF:
return "TEST_OF";
case X86_EFLAGS_TEST_SF:
return "TEST_SF";
case X86_EFLAGS_TEST_ZF:
return "TEST_ZF";
case X86_EFLAGS_TEST_PF:
return "TEST_PF";
case X86_EFLAGS_TEST_CF:
return "TEST_CF";
case X86_EFLAGS_RESET_SF:
return "RESET_SF";
case X86_EFLAGS_RESET_AF:
return "RESET_AF";
case X86_EFLAGS_RESET_TF:
return "RESET_TF";
case X86_EFLAGS_RESET_NT:
return "RESET_NT";
case X86_EFLAGS_PRIOR_OF:
return "PRIOR_OF";
case X86_EFLAGS_PRIOR_SF:
return "PRIOR_SF";
case X86_EFLAGS_PRIOR_ZF:
return "PRIOR_ZF";
case X86_EFLAGS_PRIOR_AF:
return "PRIOR_AF";
case X86_EFLAGS_PRIOR_PF:
return "PRIOR_PF";
case X86_EFLAGS_PRIOR_CF:
return "PRIOR_CF";
case X86_EFLAGS_PRIOR_TF:
return "PRIOR_TF";
case X86_EFLAGS_PRIOR_IF:
return "PRIOR_IF";
case X86_EFLAGS_PRIOR_DF:
return "PRIOR_DF";
case X86_EFLAGS_TEST_NT:
return "TEST_NT";
case X86_EFLAGS_TEST_DF:
return "TEST_DF";
case X86_EFLAGS_RESET_PF:
return "RESET_PF";
case X86_EFLAGS_PRIOR_NT:
return "PRIOR_NT";
case X86_EFLAGS_MODIFY_TF:
return "MOD_TF";
case X86_EFLAGS_MODIFY_IF:
return "MOD_IF";
case X86_EFLAGS_MODIFY_DF:
return "MOD_DF";
case X86_EFLAGS_MODIFY_NT:
return "MOD_NT";
case X86_EFLAGS_MODIFY_RF:
return "MOD_RF";
case X86_EFLAGS_SET_CF:
return "SET_CF";
case X86_EFLAGS_SET_DF:
return "SET_DF";
case X86_EFLAGS_SET_IF:
return "SET_IF";
case X86_EFLAGS_SET_OF:
return "SET_OF";
case X86_EFLAGS_SET_SF:
return "SET_SF";
case X86_EFLAGS_SET_ZF:
return "SET_ZF";
case X86_EFLAGS_SET_AF:
return "SET_AF";
case X86_EFLAGS_SET_PF:
return "SET_PF";
case X86_EFLAGS_TEST_AF:
return "TEST_AF";
case X86_EFLAGS_TEST_TF:
return "TEST_TF";
case X86_EFLAGS_TEST_RF:
return "TEST_RF";
case X86_EFLAGS_RESET_0F:
return "RESET_0F";
case X86_EFLAGS_RESET_AC:
return "RESET_AC";
}
}
static const char *get_fpu_flag_name(uint64_t flag)
{
switch (flag) {
default:
return NULL;
case X86_FPU_FLAGS_MODIFY_C0:
return "MOD_C0";
case X86_FPU_FLAGS_MODIFY_C1:
return "MOD_C1";
case X86_FPU_FLAGS_MODIFY_C2:
return "MOD_C2";
case X86_FPU_FLAGS_MODIFY_C3:
return "MOD_C3";
case X86_FPU_FLAGS_RESET_C0:
return "RESET_C0";
case X86_FPU_FLAGS_RESET_C1:
return "RESET_C1";
case X86_FPU_FLAGS_RESET_C2:
return "RESET_C2";
case X86_FPU_FLAGS_RESET_C3:
return "RESET_C3";
case X86_FPU_FLAGS_SET_C0:
return "SET_C0";
case X86_FPU_FLAGS_SET_C1:
return "SET_C1";
case X86_FPU_FLAGS_SET_C2:
return "SET_C2";
case X86_FPU_FLAGS_SET_C3:
return "SET_C3";
case X86_FPU_FLAGS_UNDEFINED_C0:
return "UNDEF_C0";
case X86_FPU_FLAGS_UNDEFINED_C1:
return "UNDEF_C1";
case X86_FPU_FLAGS_UNDEFINED_C2:
return "UNDEF_C2";
case X86_FPU_FLAGS_UNDEFINED_C3:
return "UNDEF_C3";
case X86_FPU_FLAGS_TEST_C0:
return "TEST_C0";
case X86_FPU_FLAGS_TEST_C1:
return "TEST_C1";
case X86_FPU_FLAGS_TEST_C2:
return "TEST_C2";
case X86_FPU_FLAGS_TEST_C3:
return "TEST_C3";
}
}
void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins)
{
int count, i;
cs_x86 *x86;
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
x86 = &(ins->detail->x86);
print_string_hex("\tPrefix:", x86->prefix, 4);
print_string_hex("\tOpcode:", x86->opcode, 4);
printf("\trex: 0x%x\n", x86->rex);
printf("\taddr_size: %u\n", x86->addr_size);
printf("\tmodrm: 0x%x\n", x86->modrm);
printf("\tdisp: 0x%" PRIx64 "\n", x86->disp);
// SIB is not available in 16-bit mode
if ((mode & CS_MODE_16) == 0) {
printf("\tsib: 0x%x\n", x86->sib);
if (x86->sib_base != X86_REG_INVALID)
printf("\t\tsib_base: %s\n", cs_reg_name(ud, x86->sib_base));
if (x86->sib_index != X86_REG_INVALID)
printf("\t\tsib_index: %s\n", cs_reg_name(ud, x86->sib_index));
if (x86->sib_scale != 0)
printf("\t\tsib_scale: %d\n", x86->sib_scale);
}
// XOP code condition
if (x86->xop_cc != X86_XOP_CC_INVALID) {
printf("\txop_cc: %u\n", x86->xop_cc);
}
// SSE code condition
if (x86->sse_cc != X86_SSE_CC_INVALID) {
printf("\tsse_cc: %u\n", x86->sse_cc);
}
// AVX code condition
if (x86->avx_cc != X86_AVX_CC_INVALID) {
printf("\tavx_cc: %u\n", x86->avx_cc);
}
// AVX Suppress All Exception
if (x86->avx_sae) {
printf("\tavx_sae: %u\n", x86->avx_sae);
}
// AVX Rounding Mode
if (x86->avx_rm != X86_AVX_RM_INVALID) {
printf("\tavx_rm: %u\n", x86->avx_rm);
}
// Print out all immediate operands
count = cs_op_count(ud, ins, X86_OP_IMM);
if (count > 0) {
printf("\timm_count: %u\n", count);
for (i = 1; i < count + 1; i++) {
int index = cs_op_index(ud, ins, X86_OP_IMM, i);
printf("\t\timms[%u]: 0x%" PRIx64 "\n", i, x86->operands[index].imm);
}
}
if (x86->op_count)
printf("\top_count: %u\n", x86->op_count);
// Print out all operands
for (i = 0; i < x86->op_count; i++) {
cs_x86_op *op = &(x86->operands[i]);
switch((int)op->type) {
case X86_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(ud, op->reg));
break;
case X86_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
break;
case X86_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.segment != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.segment: REG = %s\n", i, cs_reg_name(ud, op->mem.segment));
if (op->mem.base != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(ud, op->mem.base));
if (op->mem.index != X86_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n", i, cs_reg_name(ud, op->mem.index));
if (op->mem.scale != 1)
printf("\t\t\toperands[%u].mem.scale: %u\n", i, op->mem.scale);
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
break;
default:
break;
}
// AVX broadcast type
if (op->avx_bcast != X86_AVX_BCAST_INVALID)
printf("\t\toperands[%u].avx_bcast: %u\n", i, op->avx_bcast);
// AVX zero opmask {z}
if (op->avx_zero_opmask != false)
printf("\t\toperands[%u].avx_zero_opmask: TRUE\n", i);
printf("\t\toperands[%u].size: %u\n", i, op->size);
switch(op->access) {
default:
break;
case CS_AC_READ:
printf("\t\toperands[%u].access: READ\n", i);
break;
case CS_AC_WRITE:
printf("\t\toperands[%u].access: WRITE\n", i);
break;
case CS_AC_READ | CS_AC_WRITE:
printf("\t\toperands[%u].access: READ | WRITE\n", i);
break;
}
}
// Print out all registers accessed by this instruction (either implicit or explicit)
if (!cs_regs_access(ud, ins,
regs_read, &regs_read_count,
regs_write, &regs_write_count)) {
if (regs_read_count) {
printf("\tRegisters read:");
for(i = 0; i < regs_read_count; i++) {
printf(" %s", cs_reg_name(ud, regs_read[i]));
}
printf("\n");
}
if (regs_write_count) {
printf("\tRegisters modified:");
for(i = 0; i < regs_write_count; i++) {
printf(" %s", cs_reg_name(ud, regs_write[i]));
}
printf("\n");
}
}
if (x86->eflags || x86->fpu_flags) {
for(i = 0; i < ins->detail->groups_count; i++) {
if (ins->detail->groups[i] == X86_GRP_FPU) {
printf("\tFPU_FLAGS:");
for(i = 0; i <= 63; i++)
if (x86->fpu_flags & ((uint64_t)1 << i)) {
printf(" %s", get_fpu_flag_name((uint64_t)1 << i));
}
printf("\n");
break;
}
}
if (i == ins->detail->groups_count) {
printf("\tEFLAGS:");
for(i = 0; i <= 63; i++)
if (x86->eflags & ((uint64_t)1 << i)) {
printf(" %s", get_eflag_name((uint64_t)1 << i));
}
printf("\n");
}
}
}

View File

@@ -0,0 +1,51 @@
/* Capstone Disassembler Engine */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
#include <stdio.h>
#include <capstone/capstone.h>
#include "cstool.h"
void print_insn_detail_xcore(csh handle, cs_insn *ins)
{
cs_xcore *xcore;
int i;
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
if (ins->detail == NULL)
return;
xcore = &(ins->detail->xcore);
if (xcore->op_count)
printf("\top_count: %u\n", xcore->op_count);
for (i = 0; i < xcore->op_count; i++) {
cs_xcore_op *op = &(xcore->operands[i]);
switch((int)op->type) {
default:
break;
case XCORE_OP_REG:
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
break;
case XCORE_OP_IMM:
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
break;
case XCORE_OP_MEM:
printf("\t\toperands[%u].type: MEM\n", i);
if (op->mem.base != XCORE_REG_INVALID)
printf("\t\t\toperands[%u].mem.base: REG = %s\n",
i, cs_reg_name(handle, op->mem.base));
if (op->mem.index != XCORE_REG_INVALID)
printf("\t\t\toperands[%u].mem.index: REG = %s\n",
i, cs_reg_name(handle, op->mem.index));
if (op->mem.disp != 0)
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
if (op->mem.direct != 1)
printf("\t\t\toperands[%u].mem.direct: -1\n", i);
break;
}
}
printf("\n");
}

76
thirdparty/capstone/cstool/getopt.c vendored Normal file
View File

@@ -0,0 +1,76 @@
#include <string.h>
#include <stdio.h>
#include "getopt.h"
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
const char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int getopt (int nargc, char * const nargv[], const char *ostr)
{
static const char *place = EMSG; /* option letter processing */
const char *oli; /* option letter list index */
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr (ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)printf ("illegal option -- %c\n", optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
} else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)printf ("option requires an argument -- %c\n", optopt);
return (BADCH);
} else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return optopt; /* dump back option letter */
}

14
thirdparty/capstone/cstool/getopt.h vendored Normal file
View File

@@ -0,0 +1,14 @@
#ifndef CSTOOL_GETOPT_H
#define CSTOOL_GETOPT_H
// global
extern int opterr, /* if error message should be printed */
optind, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
extern const char *optarg; /* argument associated with option */
int getopt (int nargc, char *const nargv[], const char *ostr);
#endif