Home | History | Annotate | Download | only in tests
      1 /* Capstone Disassembler Engine */
      2 /* By Nguyen Anh Quynh <aquynh (at) gmail.com>, 2013-2014 */
      3 
      4 #include <stdio.h>
      5 
      6 #include <platform.h>
      7 #include <capstone.h>
      8 
      9 struct platform {
     10 	cs_arch arch;
     11 	cs_mode mode;
     12 	unsigned char *code;
     13 	size_t size;
     14 	char *comment;
     15 };
     16 
     17 static csh handle;
     18 
     19 static void print_string_hex(char *comment, unsigned char *str, size_t len)
     20 {
     21 	unsigned char *c;
     22 
     23 	printf("%s", comment);
     24 	for (c = str; c < str + len; c++) {
     25 		printf("0x%02x ", *c & 0xff);
     26 	}
     27 
     28 	printf("\n");
     29 }
     30 
     31 static void print_insn_detail(cs_insn *ins)
     32 {
     33 	cs_sysz *sysz;
     34 	int i;
     35 
     36 	// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
     37 	if (ins->detail == NULL)
     38 		return;
     39 
     40 	sysz = &(ins->detail->sysz);
     41 	if (sysz->op_count)
     42 		printf("\top_count: %u\n", sysz->op_count);
     43 
     44 	for (i = 0; i < sysz->op_count; i++) {
     45 		cs_sysz_op *op = &(sysz->operands[i]);
     46 		switch((int)op->type) {
     47 			default:
     48 				break;
     49 			case SYSZ_OP_REG:
     50 				printf("\t\toperands[%u].type: REG = %s\n", i, cs_reg_name(handle, op->reg));
     51 				break;
     52 			case SYSZ_OP_ACREG:
     53 				printf("\t\toperands[%u].type: ACREG = %u\n", i, op->reg);
     54 				break;
     55 			case SYSZ_OP_IMM:
     56 				printf("\t\toperands[%u].type: IMM = 0x%" PRIx64 "\n", i, op->imm);
     57 				break;
     58 			case SYSZ_OP_MEM:
     59 				printf("\t\toperands[%u].type: MEM\n", i);
     60 				if (op->mem.base != SYSZ_REG_INVALID)
     61 					printf("\t\t\toperands[%u].mem.base: REG = %s\n",
     62 							i, cs_reg_name(handle, op->mem.base));
     63 				if (op->mem.index != SYSZ_REG_INVALID)
     64 					printf("\t\t\toperands[%u].mem.index: REG = %s\n",
     65 							i, cs_reg_name(handle, op->mem.index));
     66 				if (op->mem.length != 0)
     67 					printf("\t\t\toperands[%u].mem.length: 0x%" PRIx64 "\n", i, op->mem.length);
     68 				if (op->mem.disp != 0)
     69 					printf("\t\t\toperands[%u].mem.disp: 0x%" PRIx64 "\n", i, op->mem.disp);
     70 
     71 				break;
     72 		}
     73 	}
     74 
     75 	if (sysz->cc != 0)
     76 		printf("\tCode condition: %u\n", sysz->cc);
     77 
     78 	printf("\n");
     79 }
     80 
     81 static void test()
     82 {
     83 #define SYSZ_CODE "\xed\x00\x00\x00\x00\x1a\x5a\x0f\x1f\xff\xc2\x09\x80\x00\x00\x00\x07\xf7\xeb\x2a\xff\xff\x7f\x57\xe3\x01\xff\xff\x7f\x57\xeb\x00\xf0\x00\x00\x24\xb2\x4f\x00\x78\xec\x18\x00\x00\xc1\x7f"
     84 
     85 	struct platform platforms[] = {
     86 		{
     87 			CS_ARCH_SYSZ,
     88 			CS_MODE_BIG_ENDIAN,
     89 			(unsigned char*)SYSZ_CODE,
     90 			sizeof(SYSZ_CODE) - 1,
     91 			"SystemZ",
     92 		},
     93 	};
     94 
     95 	uint64_t address = 0x1000;
     96 	cs_insn *insn;
     97 	int i;
     98 	size_t count;
     99 
    100 	for (i = 0; i < sizeof(platforms)/sizeof(platforms[0]); i++) {
    101 		cs_err err = cs_open(platforms[i].arch, platforms[i].mode, &handle);
    102 		if (err) {
    103 			printf("Failed on cs_open() with error returned: %u\n", err);
    104 			continue;
    105 		}
    106 
    107 		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
    108 
    109 		count = cs_disasm(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
    110 		if (count) {
    111 			size_t j;
    112 
    113 			printf("****************\n");
    114 			printf("Platform: %s\n", platforms[i].comment);
    115 			print_string_hex("Code:", platforms[i].code, platforms[i].size);
    116 			printf("Disasm:\n");
    117 
    118 			for (j = 0; j < count; j++) {
    119 				printf("0x%" PRIx64 ":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
    120 				print_insn_detail(&insn[j]);
    121 			}
    122 			printf("0x%" PRIx64 ":\n", insn[j-1].address + insn[j-1].size);
    123 
    124 			// free memory allocated by cs_disasm()
    125 			cs_free(insn, count);
    126 		} else {
    127 			printf("****************\n");
    128 			printf("Platform: %s\n", platforms[i].comment);
    129 			print_string_hex("Code:", platforms[i].code, platforms[i].size);
    130 			printf("ERROR: Failed to disasm given code!\n");
    131 		}
    132 
    133 		printf("\n");
    134 
    135 		cs_close(&handle);
    136 	}
    137 }
    138 
    139 int main()
    140 {
    141 	test();
    142 
    143 	return 0;
    144 }
    145