Merge branch 'master' of https://github.com/echotyh/capstone into echotyh-master
This commit is contained in:
commit
0687b2396b
|
@ -2,19 +2,25 @@
|
||||||
|
|
||||||
include ../functions.mk
|
include ../functions.mk
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean all
|
||||||
|
|
||||||
LIBNAME = capstone
|
LIBNAME = capstone
|
||||||
|
|
||||||
CFLAGS = -I../include
|
CFLAGS = -I../include
|
||||||
LDFLAGS = -O3 -Wall -L.. -l$(LIBNAME)
|
LDFLAGS = -O3 -Wall -L.. -l$(LIBNAME)
|
||||||
|
|
||||||
cstool: cstool.o
|
TARGET = cstool
|
||||||
|
SOURCES := $(wildcard *.c)
|
||||||
|
OBJECTS := $(SOURCES:.c=.o)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
ifeq ($(V),0)
|
ifeq ($(V),0)
|
||||||
$(call log,LINK,$@)
|
$(call log,LINK,$@)
|
||||||
@${CC} $< $(LDFLAGS) -o $@
|
@${CC} $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
else
|
else
|
||||||
${CC} $< $(LDFLAGS) -o $@
|
${CC} $(OBJECTS) $(LDFLAGS) -o $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
143
cstool/cstool.c
143
cstool/cstool.c
|
@ -1,4 +1,4 @@
|
||||||
/* Tang Yuhang <1648200150@qq.com> 2016 */
|
/* Tang Yuhang <tyh000011112222@gmail.com> 2016 */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -7,7 +7,16 @@
|
||||||
|
|
||||||
#include <capstone.h>
|
#include <capstone.h>
|
||||||
|
|
||||||
#define VERSION "1.0"
|
#define VERSION "2.0"
|
||||||
|
|
||||||
|
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_arm64(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);
|
||||||
|
|
||||||
// convert hexchar to hexnum
|
// convert hexchar to hexnum
|
||||||
static uint8_t char_to_hexnum(char c)
|
static uint8_t char_to_hexnum(char c)
|
||||||
|
@ -53,7 +62,7 @@ static uint8_t *preprocess(char *code, size_t *size)
|
||||||
static void usage(char *prog)
|
static void usage(char *prog)
|
||||||
{
|
{
|
||||||
printf("Cstool v%s for Capstone Disassembler Engine (www.capstone-engine.org)\n\n", VERSION);
|
printf("Cstool v%s for Capstone Disassembler Engine (www.capstone-engine.org)\n\n", VERSION);
|
||||||
printf("Syntax: %s <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
|
printf("Syntax: %s [-d:print all debug information] <arch+mode> <assembly-hexstring> [start-address-in-hex-format]\n", prog);
|
||||||
printf("\nThe following <arch+mode> options are supported:\n");
|
printf("\nThe following <arch+mode> options are supported:\n");
|
||||||
|
|
||||||
if (cs_support(CS_ARCH_X86)) {
|
if (cs_support(CS_ARCH_X86)) {
|
||||||
|
@ -114,91 +123,131 @@ int main(int argc, char **argv)
|
||||||
uint64_t address = 0;
|
uint64_t address = 0;
|
||||||
cs_insn *insn;
|
cs_insn *insn;
|
||||||
cs_err err;
|
cs_err err;
|
||||||
bool x86_arch = false;
|
cs_mode md;
|
||||||
|
char *arch;
|
||||||
|
bool debug_flag = false;
|
||||||
|
|
||||||
if (argc != 3 && argc != 4) {
|
if (argc != 3 && argc != 4 && argc != 5) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = argv[1];
|
if (!strcmp(argv[1], "-d")) {
|
||||||
assembly = preprocess(argv[2], &size);
|
if (argc == 3) {
|
||||||
if (assembly == NULL) {
|
usage(argv[0]);
|
||||||
printf("ERROR: invalid assembler-string argument, quit!\n");
|
return -1;
|
||||||
return -3;
|
|
||||||
}
|
}
|
||||||
|
debug_flag = true;
|
||||||
|
mode = argv[2];
|
||||||
|
assembly = preprocess(argv[3], &size);
|
||||||
|
if (argc == 5) {
|
||||||
|
char *temp;
|
||||||
|
address = strtoull(argv[4], &temp, 16);
|
||||||
|
if (temp == argv[4] || *temp != '\0' || errno == ERANGE) {
|
||||||
|
printf("ERROR: invalid address argument, quit!\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (argc == 5) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc == 4) {
|
mode = argv[1];
|
||||||
// cstool <arch> <assembly> <address>
|
assembly = preprocess(argv[2], &size);
|
||||||
char *temp;
|
if (assembly == NULL) {
|
||||||
address = strtoull(argv[3], &temp, 16);
|
printf("ERROR: invalid assembler-string argument, quit!\n");
|
||||||
if (temp == argv[3] || *temp != '\0' || errno == ERANGE) {
|
return -3;
|
||||||
printf("ERROR: invalid address argument, quit!\n");
|
}
|
||||||
return -2;
|
|
||||||
|
if (argc == 4) {
|
||||||
|
// cstool <arch> <assembly> <address>
|
||||||
|
char *temp;
|
||||||
|
address = strtoull(argv[3], &temp, 16);
|
||||||
|
if (temp == argv[3] || *temp != '\0' || errno == ERANGE) {
|
||||||
|
printf("ERROR: invalid address argument, quit!\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "arm")) {
|
if (!strcmp(mode, "arm")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "armb")) {
|
if (!strcmp(mode, "armb")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "arml")) {
|
if (!strcmp(mode, "arml")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "thumb")) {
|
if (!strcmp(mode, "thumb")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "thumbbe")) {
|
if (!strcmp(mode, "thumbbe")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB + CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "thumble")) {
|
if (!strcmp(mode, "thumble")) {
|
||||||
|
arch = "arm";
|
||||||
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM, CS_MODE_ARM + CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "arm64")) {
|
if (!strcmp(mode, "arm64")) {
|
||||||
|
arch = "arm64";
|
||||||
err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "mips")) {
|
if (!strcmp(mode, "mips")) {
|
||||||
|
arch = "mips";
|
||||||
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "mipsbe")) {
|
if (!strcmp(mode, "mipsbe")) {
|
||||||
|
arch = "mips";
|
||||||
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "mips64")) {
|
if (!strcmp(mode, "mips64")) {
|
||||||
|
arch = "mips";
|
||||||
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "mips64be")) {
|
if (!strcmp(mode, "mips64be")) {
|
||||||
|
arch = "mips";
|
||||||
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "x16")) {
|
if (!strcmp(mode, "x16")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_16;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "x32")) {
|
if (!strcmp(mode, "x32")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_32;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "x64")) {
|
if (!strcmp(mode, "x64")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_64;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "x16att")) {
|
if (!strcmp(mode, "x16att")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_16;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
||||||
|
@ -206,7 +255,8 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"x32att")) {
|
if (!strcmp(mode,"x32att")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_32;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_32, &handle);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
||||||
|
@ -214,7 +264,8 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"x64att")) {
|
if (!strcmp(mode,"x64att")) {
|
||||||
x86_arch = true;
|
md = CS_MODE_64;
|
||||||
|
arch = "x86";
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_64, &handle);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
|
||||||
|
@ -222,22 +273,27 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"ppc64")) {
|
if (!strcmp(mode,"ppc64")) {
|
||||||
|
arch = "ppc";
|
||||||
err = cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_LITTLE_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_PPC, CS_MODE_64+CS_MODE_LITTLE_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"ppc64be")) {
|
if (!strcmp(mode,"ppc64be")) {
|
||||||
|
arch = "ppc";
|
||||||
err = cs_open(CS_ARCH_PPC,CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_PPC,CS_MODE_64+CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"sparc")) {
|
if (!strcmp(mode,"sparc")) {
|
||||||
|
arch = "sparc";
|
||||||
err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
|
if (!strcmp(mode, "systemz") || !strcmp(mode, "sysz") || !strcmp(mode, "s390x")) {
|
||||||
|
arch = "sysz";
|
||||||
err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(mode,"xcore")) {
|
if (!strcmp(mode,"xcore")) {
|
||||||
|
arch = "xcore";
|
||||||
err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle);
|
err = cs_open(CS_ARCH_XCORE, CS_MODE_BIG_ENDIAN, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +303,10 @@ int main(int argc, char **argv)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug_flag) {
|
||||||
|
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
|
||||||
|
}
|
||||||
|
|
||||||
count = cs_disasm(handle, assembly, size, address, 0, &insn);
|
count = cs_disasm(handle, assembly, size, address, 0, &insn);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -259,12 +319,45 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
// X86 instruction size is variable.
|
// X86 instruction size is variable.
|
||||||
// align assembly instruction after the opcode
|
// align assembly instruction after the opcode
|
||||||
if (x86_arch) {
|
if (!strcmp(arch, "x86")) {
|
||||||
for (; j < 16; j++) {
|
for (; j < 16; j++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
|
printf(" %s\t%s\n", insn[i].mnemonic, insn[i].op_str);
|
||||||
|
if (debug_flag) {
|
||||||
|
if (!strcmp(arch, "x86")) {
|
||||||
|
print_insn_detail_x86(handle, md, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "arm")) {
|
||||||
|
print_insn_detail_arm(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch,"arm64")) {
|
||||||
|
print_insn_detail_arm64(handle,&insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "mips")) {
|
||||||
|
print_insn_detail_mips(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "ppc")) {
|
||||||
|
print_insn_detail_ppc(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "sparc")) {
|
||||||
|
print_insn_detail_sparc(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "sysz")) {
|
||||||
|
print_insn_detail_sysz(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(arch, "xcore")) {
|
||||||
|
print_insn_detail_xcore(handle, &insn[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cs_free(insn, count);
|
cs_free(insn, count);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_insn_detail_arm(csh handle, cs_insn *ins)
|
||||||
|
{
|
||||||
|
cs_arm *arm;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
printf("\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm);
|
||||||
|
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 != 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.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%x\n", i, op->mem.disp);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ARM_OP_PIMM:
|
||||||
|
printf("\t\toperands[%u].type: P-IMM = %u\n", i, op->imm);
|
||||||
|
break;
|
||||||
|
case ARM_OP_CIMM:
|
||||||
|
printf("\t\toperands[%u].type: C-IMM = %u\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_SYSREG:
|
||||||
|
printf("\t\toperands[%u].type: SYSREG = %u\n", i, op->reg);
|
||||||
|
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 != ARM_CC_AL && arm->cc != ARM_CC_INVALID)
|
||||||
|
printf("\tCode condition: %u\n", arm->cc);
|
||||||
|
|
||||||
|
if (arm->update_flags)
|
||||||
|
printf("\tUpdate-flags: True\n");
|
||||||
|
|
||||||
|
if (arm->writeback)
|
||||||
|
printf("\tWrite-back: True\n");
|
||||||
|
|
||||||
|
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)
|
||||||
|
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);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_insn_detail_arm64(csh handle, cs_insn *ins)
|
||||||
|
{
|
||||||
|
cs_arm64 *arm64;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// detail can be NULL if SKIPDATA option is turned ON
|
||||||
|
if (ins->detail == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
arm64 = &(ins->detail->arm64);
|
||||||
|
if (arm64->op_count)
|
||||||
|
printf("\top_count: %u\n", arm64->op_count);
|
||||||
|
|
||||||
|
for (i = 0; i < arm64->op_count; i++) {
|
||||||
|
cs_arm64_op *op = &(arm64->operands[i]);
|
||||||
|
switch(op->type) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ARM64_OP_REG:
|
||||||
|
printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
|
||||||
|
break;
|
||||||
|
case ARM64_OP_IMM:
|
||||||
|
printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
|
||||||
|
break;
|
||||||
|
case ARM64_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 ARM64_OP_MEM:
|
||||||
|
printf("\t\toperands[%u].type: MEM\n", i);
|
||||||
|
if (op->mem.base != ARM64_REG_INVALID)
|
||||||
|
printf("\t\t\toperands[%u].mem.base: REG = %s\n", i, cs_reg_name(handle, op->mem.base));
|
||||||
|
if (op->mem.index != ARM64_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;
|
||||||
|
case ARM64_OP_CIMM:
|
||||||
|
printf("\t\toperands[%u].type: C-IMM = %u\n", i, (int)op->imm);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_REG_MRS:
|
||||||
|
printf("\t\toperands[%u].type: REG_MRS = 0x%x\n", i, op->reg);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_REG_MSR:
|
||||||
|
printf("\t\toperands[%u].type: REG_MSR = 0x%x\n", i, op->reg);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_PSTATE:
|
||||||
|
printf("\t\toperands[%u].type: PSTATE = 0x%x\n", i, op->pstate);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_SYS:
|
||||||
|
printf("\t\toperands[%u].type: SYS = 0x%x\n", i, op->sys);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_PREFETCH:
|
||||||
|
printf("\t\toperands[%u].type: PREFETCH = 0x%x\n", i, op->prefetch);
|
||||||
|
break;
|
||||||
|
case ARM64_OP_BARRIER:
|
||||||
|
printf("\t\toperands[%u].type: BARRIER = 0x%x\n", i, op->barrier);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op->shift.type != ARM64_SFT_INVALID &&
|
||||||
|
op->shift.value)
|
||||||
|
printf("\t\t\tShift: type = %u, value = %u\n",
|
||||||
|
op->shift.type, op->shift.value);
|
||||||
|
|
||||||
|
if (op->ext != ARM64_EXT_INVALID)
|
||||||
|
printf("\t\t\tExt: %u\n", op->ext);
|
||||||
|
|
||||||
|
if (op->vas != ARM64_VAS_INVALID)
|
||||||
|
printf("\t\t\tVector Arrangement Specifier: 0x%x\n", op->vas);
|
||||||
|
|
||||||
|
if (op->vess != ARM64_VESS_INVALID)
|
||||||
|
printf("\t\t\tVector Element Size Specifier: %u\n", op->vess);
|
||||||
|
|
||||||
|
if (op->vector_index != -1)
|
||||||
|
printf("\t\t\tVector Index: %u\n", op->vector_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arm64->update_flags)
|
||||||
|
printf("\tUpdate-flags: True\n");
|
||||||
|
|
||||||
|
if (arm64->writeback)
|
||||||
|
printf("\tWrite-back: True\n");
|
||||||
|
|
||||||
|
if (arm64->cc)
|
||||||
|
printf("\tCode-condition: %u\n", arm64->cc);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 != X86_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
static csh handle;
|
||||||
|
|
||||||
|
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 const char* get_bc_name(int bc)
|
||||||
|
{
|
||||||
|
switch(bc) {
|
||||||
|
default:
|
||||||
|
case PPC_BC_INVALID:
|
||||||
|
return ("invalid");
|
||||||
|
case PPC_BC_LT:
|
||||||
|
return ("lt");
|
||||||
|
case PPC_BC_LE:
|
||||||
|
return ("le");
|
||||||
|
case PPC_BC_EQ:
|
||||||
|
return ("eq");
|
||||||
|
case PPC_BC_GE:
|
||||||
|
return ("ge");
|
||||||
|
case PPC_BC_GT:
|
||||||
|
return ("gt");
|
||||||
|
case PPC_BC_NE:
|
||||||
|
return ("ne");
|
||||||
|
case PPC_BC_UN:
|
||||||
|
return ("un");
|
||||||
|
case PPC_BC_NU:
|
||||||
|
return ("nu");
|
||||||
|
case PPC_BC_SO:
|
||||||
|
return ("so");
|
||||||
|
case PPC_BC_NS:
|
||||||
|
return ("ns");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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%x\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.disp != 0)
|
||||||
|
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PPC_OP_CRX:
|
||||||
|
printf("\t\toperands[%u].type: CRX\n", i);
|
||||||
|
printf("\t\t\toperands[%u].crx.scale: %d\n", i, op->crx.scale);
|
||||||
|
printf("\t\t\toperands[%u].crx.reg: %s\n", i, cs_reg_name(handle, op->crx.reg));
|
||||||
|
printf("\t\t\toperands[%u].crx.cond: %s\n", i, get_bc_name(op->crx.cond));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppc->bc != 0)
|
||||||
|
printf("\tBranch code: %u\n", ppc->bc);
|
||||||
|
|
||||||
|
if (ppc->bh != 0)
|
||||||
|
printf("\tBranch hint: %u\n", ppc->bh);
|
||||||
|
|
||||||
|
if (ppc->update_cr0)
|
||||||
|
printf("\tUpdate-CR0: True\n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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%x\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);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/* Second-Best Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013> */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_insn_detail_x86(csh ud, cs_mode mode, cs_insn *ins)
|
||||||
|
{
|
||||||
|
int count, i;
|
||||||
|
cs_x86 *x86;
|
||||||
|
|
||||||
|
// 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%x\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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
count = cs_op_count(ud, ins, X86_OP_IMM);
|
||||||
|
if (count) {
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* Capstone Disassembler Engine */
|
||||||
|
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <capstone.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
Loading…
Reference in New Issue