예제 #1
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static int omode = 0;
	int mode, n, ret;
	ut64 off = a->pc;
	cs_insn* insn;

	mode = (a->bits==64)? CS_MODE_64: 
		(a->bits==32)? CS_MODE_32: 0;
	if (handle && mode != omode) {
		cs_close (&handle);
		handle = 0;
	}
	op->size = 0;
	omode = mode;
	if (handle == 0) {
		ret = cs_open (CS_ARCH_PPC, mode, &handle);
		if (ret) return 0;
	}
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_OFF);
	n = cs_disasm_ex (handle, (const ut8*)buf, len, off, 1, &insn);
	if (n>0) {
		if (insn->size>0) {
			op->size = insn->size;
			snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
				insn->mnemonic, insn->op_str[0]?" ":"",
				insn->op_str);
		}
		cs_free (insn, n);
	}
	return op->size;
}
예제 #2
0
파일: armcapstone.cpp 프로젝트: nikaiw/rp
InstructionInformation ArmCapstone::disass(const unsigned char *data, unsigned long long len, unsigned long long vaddr, DisassEngineReturn &ret)
{
	InstructionInformation instr;

	cs_insn *insn = NULL;
	size_t count = cs_disasm_ex(m_handle, data, len, vaddr, 1, &insn);
	if(count != 1)
	{
		ret = UnknownInstruction;
		goto end;
	}

	instr.address = (unsigned long long)data;
	instr.virtual_address_in_memory = vaddr;
	instr.mnemonic = std::string(insn[0].mnemonic);
	instr.disassembly = instr.mnemonic + ' ' + std::string(insn[0].op_str);
	instr.size = insn[0].size;

	instr.cap_is_branch = false;
	if(insn[0].detail != NULL)
	{
		if(cs_insn_group(m_handle, insn, ARM_GRP_JUMP))
			instr.cap_is_branch = true;
		else if(instr.mnemonic == "bx" && insn[0].detail->arm.operands[0].type == ARM_OP_REG)
			instr.cap_is_branch = true;
		else if(instr.mnemonic == "blx")
			instr.cap_is_branch = true;
		else if(instr.mnemonic == "pop")
		{
			bool has_pc = false;
			for(size_t i = 0; i < insn[0].detail->arm.op_count; ++i)
			{
				if(insn[0].detail->arm.operands[i].type == ARM_OP_REG && insn[0].detail->arm.operands[i].reg == ARM_REG_PC)
				{
					has_pc = true;
					break;
				}
			}

			if(has_pc)
				instr.cap_is_branch = true;
		}
	}

	ret = AllRight;

	end:
	if(insn != NULL)
		cs_free(insn, count);

	return instr;
}
예제 #3
0
int instruction_length_at_address(uint64_t address) {
  csh handle;
  cs_insn *insn;
  size_t count;
  int retval = 0;

  if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
    return -1;
  count = cs_disasm_ex(handle, (uint8_t *)address, 12, 0x1000, 0, &insn);
  if (count > 0) {
    retval = insn[0].size;
    cs_free(insn, count);
  }
  cs_close(&handle);
  return retval;
}
예제 #4
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	cs_insn* insn = NULL;
	cs_mode mode = 0;
	int ret, n = 0;
	csh cd;
	mode = (a->bits==16)? CS_MODE_THUMB: CS_MODE_ARM;
	if (a->big_endian)
		mode |= CS_MODE_BIG_ENDIAN;
	else
		mode |= CS_MODE_LITTLE_ENDIAN;

	op->size = 4;
	op->buf_asm[0] = 0;
	ret = (a->bits==64)?
		cs_open (CS_ARCH_ARM64, mode, &cd):
		cs_open (CS_ARCH_ARM, mode, &cd);
	if (ret) {
		ret = -1;
		goto beach;
	}
	if (a->syntax == R_ASM_SYNTAX_REGNUM) {
		cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
	} else cs_option (cd, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
	cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	n = cs_disasm_ex (cd, buf, R_MIN (4, len),
		a->pc, 1, &insn);
	if (n<1) {
		ret = -1;
		goto beach;
	}
	if (insn->size<1) {
		ret = -1;
		goto beach;
	}
	op->size = insn->size;
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
		insn->mnemonic,
		insn->op_str[0]?" ":"",
		insn->op_str);
	r_str_rmch (op->buf_asm, '#');
	cs_free (insn, n);
	beach:
	cs_close (&cd);
	if (!op->buf_asm[0])
		strcpy (op->buf_asm, "invalid");
	return op->size;
}
예제 #5
0
int disasm(const void *addr, char *str)
{
    if(g_capstone == 0) {
        pipe("CRITICAL:Capstone has not been initialized yet!");
        return *str = 0, 0;
    }

    cs_insn *insn;

    size_t count =
        cs_disasm_ex(g_capstone, addr, 16, (uintptr_t) addr, 1, &insn);
    if(count == 0) return -1;

    our_snprintf(str, DISASM_BUFSIZ, "%s %s", insn->mnemonic, insn->op_str);

    cs_free(insn, count);
    return 0;
}
예제 #6
0
int lde(const void *addr)
{
    if(g_capstone == 0) {
        MessageBox(NULL, "Capstone has not been initialized yet!",
            "Error", 0);
        return 0;
    }

    cs_insn *insn;

    size_t count =
        cs_disasm_ex(g_capstone, addr, 16, (uintptr_t) addr, 1, &insn);
    if(count == 0) return 0;

    int size = insn->size;

    cs_free(insn, count);
    return size;
}
예제 #7
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	csh handle;
	cs_insn* insn;
	int mode, n, ret = -1;
	mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;
	if (a->cpu) {
		if (!strcmp (a->cpu, "n64")) {
			mode |= CS_MODE_N64;
		} else
		if (!strcmp (a->cpu, "micro")) {
			mode |= CS_MODE_MICRO;
		}
	}
	mode |= (a->bits==64)? CS_MODE_64: CS_MODE_32;
	memset (op, 0, sizeof (RAsmOp));
	op->size = 4;
	ret = cs_open (CS_ARCH_MIPS, mode, &handle);
	if (ret) goto fin;
	if (a->syntax == R_ASM_SYNTAX_REGNUM) {
		cs_option (handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME);
	} else cs_option (handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_DEFAULT);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_OFF);
	n = cs_disasm_ex (handle, (ut8*)buf, len, a->pc, 1, &insn);
	if (n<1) {
		strcpy (op->buf_asm, "invalid");
		op->size = 4;
		ret = -1;
		goto beach;
	} else ret = 4;
	if (insn->size<1)
		goto beach;
	op->size = insn->size;
	snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
		insn->mnemonic, insn->op_str[0]? " ": "",
		insn->op_str);
	// TODO: remove the '$'<registername> in the string
	beach:
	cs_free (insn, n);
	cs_close (&handle);
	fin:
	return ret;
}
예제 #8
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
	cs_insn *insn;
	int mode = (a->bits==64)? CS_MODE_64: 
		(a->bits==32)? CS_MODE_32: 0;
	int n, ret = cs_open (CS_ARCH_PPC, mode, &handle);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = 0;
	if (ret == CS_ERR_OK) {
		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
		// capstone-next
		n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			op->size = insn->size;
		}
		cs_free (insn, n);
		cs_close (&handle);
	}
	return op->size;
}
예제 #9
0
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
	static int omode = 0;
	int mode, n, ret;
	ut64 off = a->pc;
	cs_insn* insn = NULL;
	mode = CS_MODE_BIG_ENDIAN;
	if (cd && mode != omode) {
		cs_close (&cd);
		cd = 0;
	}
	op->size = 0;
	omode = mode;
	if (cd == 0) {
		ret = cs_open (CS_ARCH_SYSZ, mode, &cd);
		if (ret) return 0;
		cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
	}
	n = cs_disasm_ex (cd, (const ut8*)buf, len, off, 1, &insn);
	if (n>0) {
		if (insn->size>0) {
			op->size = insn->size;
			if (insn->op_str) {
				char *ptrstr;
				snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
					insn->mnemonic, insn->op_str[0]?" ":"",
					insn->op_str);
				ptrstr = strstr (op->buf_asm, "ptr ");
				if (ptrstr) {
					memmove (ptrstr, ptrstr+4, strlen (ptrstr+4)+1);
				}
			} else {
				eprintf ("op_str is null wtf\n");
			}
		}
	}
	cs_free (insn, n);
	return op->size;
}
unsigned int get_nb_params(const uint8_t* fct)
{
    csh handle;
    cs_insn* insn = 0;
    t_state regs[X86_REG_MAX] = {not_used_in_fct};
    size_t count = 0;
    size_t i = 0;
    unsigned char stop = 0;

    if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK)
        return (-1);
    cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
    while (!stop)
    {
        count = cs_disasm_ex(handle, fct, 100, 0, 0, &insn);
        for (i = 0; i < count && !stop; ++i)
            if (strncmp(insn[i].mnemonic, "ret", 3) == 0)
                stop = 1;
            else
                update_register_state(regs, &(insn[i].detail->x86));
    }
    cs_close(&handle);
    return (nb_params(regs));
}
예제 #11
0
static void test()
{
//#define MIPS_CODE "\x8f\xa2\x00\x00"
//#define MIPS_CODE "\x00\x00\xa7\xac\x10\x00\xa2\x8f"
//#define MIPS_CODE "\x21\x30\xe6\x70"	// clo $6, $7
//#define MIPS_CODE "\x00\x00\x00\x00" // nop
//#define MIPS_CODE "\xc6\x23\xe9\xe4"	// swc1	$f9, 0x23c6($7)
//#define MIPS_CODE "\x21\x38\x00\x01"	// move $7, $8
#define MIPS_CODE "\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56"
//#define MIPS_CODE "\x04\x11\x00\x01"	// bal	0x8
#define MIPS_CODE2 "\x56\x34\x21\x34\xc2\x17\x01\x00"

	struct platform platforms[] = {
		{
			CS_ARCH_MIPS,
			(cs_mode)(CS_MODE_32 + CS_MODE_BIG_ENDIAN),
			(unsigned char *)MIPS_CODE,
			sizeof(MIPS_CODE) - 1,
			"MIPS-32 (Big-endian)"
		},
		{
			CS_ARCH_MIPS,
			(cs_mode)(CS_MODE_64 + CS_MODE_LITTLE_ENDIAN),
			(unsigned char *)MIPS_CODE2,
			sizeof(MIPS_CODE2) - 1,
			"MIPS-64-EL (Little-endian)"
		},
	};

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

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

		cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);

		count = cs_disasm_ex(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
		if (count) {
			size_t j;

			printf("****************\n");
			printf("Platform: %s\n", platforms[i].comment);
			print_string_hex("Code:", platforms[i].code, platforms[i].size);
			printf("Disasm:\n");

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

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

		printf("\n");

		cs_close(&handle);
	}
}
예제 #12
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
	cs_insn *insn;
	int mode = (a->bits==16)? CS_MODE_THUMB: CS_MODE_ARM;
	int i, n, ret = (a->bits==64)?
	cs_open (CS_ARCH_ARM64, mode, &handle):
	cs_open (CS_ARCH_ARM, mode, &handle);
	cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = (a->bits==16)? 2: 4;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	if (ret == CS_ERR_OK) {
		n = cs_disasm_ex (handle, (ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			op->size = insn->size;
			switch (insn->id) {
			case ARM_INS_POP:
			case ARM_INS_LDM:
				op->type = R_ANAL_OP_TYPE_POP;

				for (i = 0; i < insn->detail->arm.op_count; i++) {
					if (insn->detail->arm.operands[i].type == ARM_OP_REG &&
							insn->detail->arm.operands[i].reg == ARM_REG_PC) {
						if (insn->detail->arm.cc == ARM_CC_AL)
							op->type = R_ANAL_OP_TYPE_RET;
						else
							op->type = R_ANAL_OP_TYPE_CRET;
						break;
					}
				}
				break;
			case ARM_INS_SUB:
				op->type = R_ANAL_OP_TYPE_SUB;
				break;
			case ARM_INS_ADD:
				op->type = R_ANAL_OP_TYPE_ADD;
				break;
			case ARM_INS_MOV:
			case ARM_INS_MOVS:
			case ARM_INS_MOVT:
			case ARM_INS_MOVW:
			case ARM_INS_VMOVL:
			case ARM_INS_VMOVN:
			case ARM_INS_VQMOVUN:
			case ARM_INS_VQMOVN:
				op->type = R_ANAL_OP_TYPE_MOV;
				break;
			case ARM_INS_CMP:
			case ARM_INS_TST:
				op->type = R_ANAL_OP_TYPE_CMP;
				break;
			case ARM_INS_ROR:
			case ARM_INS_ORN:
			case ARM_INS_LSL:
			case ARM_INS_LSR:
				break;
			case ARM_INS_PUSH:
			case ARM_INS_STR:
				//case ARM_INS_POP:
			case ARM_INS_LDR:
				op->type = R_ANAL_OP_TYPE_LOAD;
				break;
			case ARM_INS_BL:
			case ARM_INS_BLX:
				op->type = R_ANAL_OP_TYPE_CALL;
				op->jump = IMM(0);
				break;
			case ARM_INS_B:
			case ARM_INS_BX:
			case ARM_INS_BXJ:
				if (insn->detail->arm.cc) {
					op->type = R_ANAL_OP_TYPE_CJMP;
					op->jump = IMM(0);
					op->fail = addr+op->size;
				} else {
					op->type = R_ANAL_OP_TYPE_JMP;
					op->jump = IMM(0);
				}
				break;
			}
			if (a->decode) {
				if (!analop_esil (a, op, addr, buf, len, &handle, insn))
					r_strbuf_fini (&op->esil);
			}
			cs_free (insn, n);
		}
	}
	cs_close (&handle);
	return op->size;
}
예제 #13
0
파일: disas.c 프로젝트: bheesham/binflow
int build_code_profile(handle_t *h)
{
	csh disas_handle;
 	cs_insn *insn;
 	size_t count;
	int mode = h->arch == 32 ? CS_MODE_32 : CS_MODE_64;
	ElfW(Off) offset = h->elf.entry - h->elf.textVaddr;
	uint8_t *code = &h->elf.mem[offset];
	struct branch_instr *branch_instr;
	unsigned long target_address, callsite;
	char *tmp;
	int c, argc;

 	if (cs_open(CS_ARCH_X86, CS_MODE_64, &disas_handle) != CS_ERR_OK)
		return -1;
	
	ElfW(Addr) dot_text = get_section_address(h, ".text");
	/*
	if (dot_text != 0) {
		size_t text_section_size = get_section_size(h, ".text");
		count = cs_disasm_ex(disas_handle, code, text_section_size, dot_text, 0, &insn);
	}
	else */
	count = cs_disasm_ex(disas_handle, code, h->elf.textSize, h->elf.entry, 0, &insn);
	if (count < 1) {
		fprintf(stderr, "Failed to disassemble code\n");
		return -1;
	}
	size_t j;
	for (j = 0; j < count; j++)  {
	//if (opts.debug) 
		/*
		 * Is the instruction a type of jmp?
		 */
		if ((branch_instr = search_branch_instr(insn[j].bytes[0])) != NULL) {
			/* Found a non-call branch instruction */
			h->branch_site[h->branch_count].branch_type = IMMEDIATE_JMP;
			h->branch_site[h->branch_count].branch.location = callsite = insn[j].address;
			h->branch_site[h->branch_count].branch.target_vaddr = target_address = strtoul(insn[j].op_str, NULL, 16);
			h->branch_site[h->branch_count].branch.target_offset = target_address - callsite - 1;
			h->branch_site[h->branch_count].branch.mnemonic = xstrdup(insn[j].mnemonic);
			if (opts.debug)
				printf("[+] Storing information for instruction: jmp %lx\n", target_address);
			h->branch_count++;
			continue;
		} 
		/*
		 * Is the instruction a call?
	    	 */
		if ((strncmp(insn[j].mnemonic, "call", 4) != 0)) 
			continue;

		/*
		 * Which type of call?
		 */
		switch(insn[j].bytes[0]) {
			
			case 0xE8:
				h->branch_site[h->branch_count].branch_type = IMMEDIATE_CALL;
				h->branch_site[h->branch_count].branch.location = callsite = insn[j].address;
				h->branch_site[h->branch_count].branch.target_vaddr = target_address = strtoul(insn[j].op_str, NULL, 16);
				h->branch_site[h->branch_count].branch.target_offset = target_address - callsite - sizeof(uint32_t);
				h->branch_site[h->branch_count].branch.ret_target = insn[j + 1].address; 
				h->branch_site[h->branch_count].branch.mnemonic = xstrdup(insn[j].mnemonic);
				if ((tmp = get_fn_name(h, target_address)) != NULL)
					h->branch_site[h->branch_count].branch.function = xstrdup(tmp);
				else	
					tmp = h->branch_site[h->branch_count].branch.function = xfmtstrdup("sub_%lx", target_address);
				if (fn_is_local(h, tmp))
					h->branch_site[h->branch_count].branch.calltype = LOCAL_CALL;
				else
					h->branch_site[h->branch_count].branch.calltype = PLT_CALL;
				int t;
				for (argc = 0, c = 0; c < MAX_ARGS; c++) {
					switch(c) {
						case 0:
							argc += check_for_reg(insn[j - (c + 1)].op_str, EDI);
							break;
						case 1:
							argc += check_for_reg(insn[j - (c + 1)].op_str, ESI);
							break;
						case 2:
							argc += check_for_reg(insn[j - (c + 1)].op_str, EDX);
							break;
						case 3:
							argc += check_for_reg(insn[j - (c + 1)].op_str, ECX);
							break;
						case 4:
							argc += check_for_reg(insn[j - (c + 1)].op_str, R8D);
							break;
						case 5:
							argc += check_for_reg(insn[j - (c + 1)].op_str, R9D);
							break;
					}
				} 
				/*
				 * We search to see if the same function has been called before, and if so
				 * is the argument count larger than what we just found? If so then use that
				 * argc value because it is likely correct over the one we just found (Which may
				 * be thrown off due to gcc optimizations
				 */
				
				h->branch_site[h->branch_count].branch.argc = argc;
				for (c = 0; c < h->branch_count; c++) {
					if (h->branch_site[c].branch_type != IMMEDIATE_CALL)
						continue;
					if (!strcmp(h->branch_site[c].branch.function, h->branch_site[h->branch_count].branch.function))
						if (h->branch_site[c].branch.argc > argc)
							h->branch_site[h->branch_count].branch.argc = h->branch_site[c].branch.argc;
				} 
				int r;
				int found_edi = 0;
				int found_esi = 0;
				int found_edx = 0;
				int found_ecx = 0;
				int found_r9 = 0;
				int found_r8 = 0;
				int k = 0;
				if (argc == 0) {
					/* Try aggressive arg resolution */
					for (c = 0; c < MAX_ARGS + 4; c++) {
						argc += r = check_for_reg(insn[j - (c + 1)].op_str, EDI);
						if (r != 0) {
							found_edi++;
							break;
						}	
					}	
					if (found_edi) {
						for (c = 0; c < MAX_ARGS + 4; c++) {
                                                        argc += r = check_for_reg(insn[j - (c + 1)].op_str, ESI);
                                                 	if (r != 0) {
								found_esi++;
								break;
							}       
                                                }
					}
					
				     	if (found_esi) {
                                        	for (c = 0; c < MAX_ARGS + 4; c++) {             
						   	argc += r = check_for_reg(insn[j - (c + 1)].op_str, EDX);
                                                        if (r != 0) {
                                                        	found_edx++;
                                                       		break;
							}
                                                }
					}
					
					if (found_edx) {
						for (c = 0; c < MAX_ARGS + 4; c++) {
                                                        argc += r = check_for_reg(insn[j - (c + 1)].op_str, ECX);
                                                        if (r != 0) {
								found_ecx++;
								break;
							}
                                                }
					}
					if (found_ecx) {
						for (c = 0; c < MAX_ARGS + 4; c++) {
							argc += r = check_for_reg(insn[j - (c + 1)].op_str, R8D);
							if (r != 0) {
								found_r8++;
								break;
							}
						}
					}
					if (found_r8) {
						for (c = 0; c < MAX_ARGS + 4; c++) {
                                                        argc += r = check_for_reg(insn[j - (c + 2)].op_str, R9D);
                                                        if (r != 0) {
                                                        	found_r9++;
                                                        	break;
							}
                                                } 

					}
					h->branch_site[h->branch_count].branch.argc = argc;
				}	
				h->branch_count++;	
                                break;

			case 0xFF: // not yet supported
				break;
		}
	}

	cs_free(insn, count);

	
}
예제 #14
0
파일: rop.c 프로젝트: chubbymaggie/ropchain
int rop_parse_gadgets(struct Node *root, unsigned char *binary, unsigned long binary_len, struct Arg *arg)
{
    size_t count;
    csh handle;
    cs_insn *insn;
    char gadget_string[MaxGadgetLen];
    unsigned int text_address = 0x08048000;
    int total_gadget = 0;
    size_t i,j,k;

    tree_init(root);

    if(cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
    {
        return -1;
    }
    for(i = 0; i < binary_len - MaxGadgetByte; i++)
    {
        count = cs_disasm_ex(handle, binary + i, MaxGadgetByte, text_address + i, 0, &insn);
        if(count > 0)
        {
            strcpy(gadget_string, "");
            for(j = 0; j < count; j++)
            {
                /* Drop the gadgets start with ret */
                if(!strcmp(insn[0].mnemonic, "ret"))
                {
                    break;
                }
                /* Ret-type gadgets */
                else if(!strcmp(insn[j].mnemonic, "ret") && j)
                {
                    total_gadget++;
                    for(k = 0; k < j; k++)
                    {
                        if(arg->print && strlen(gadget_string)
                        + strlen(insn[k].mnemonic) + strlen(insn[k].op_str) + 7 < MaxGadgetLen)
                        {
                            strcat(gadget_string, insn[k].mnemonic);
                            if(strlen(insn[k].op_str) > 0)
                            {
                                strcat(gadget_string, " ");
                                strcat(gadget_string, insn[k].op_str);
                            }
                            strcat(gadget_string, " ; ");
                        }
                    }
                    /* tree build */
                    tree_build(root, 0, insn, j+1);
                    if(arg->print && strlen(gadget_string) + 3 < MaxGadgetLen)
                    {
                        strcat(gadget_string, "ret");
                        /* print all gadgets */
                        printf("%d\t0x0%x:\t%s\n", j+1, text_address + i, gadget_string);
                    }
                    strcpy(gadget_string, "");
                    break;
                }
                else if(j == 0 && !strcmp(insn[j].mnemonic, "int") && !strcmp(insn[j].op_str, "0x80"))
                {
                    total_gadget++;
                    /* tree build */
                    tree_build(root, 0, insn, j+1);
                    if(arg->print == 1)
                    {
                        /* print int80 gadgets */
                        printf("%d\t0x0%"PRIx64":\tint 0x80\n", j+1, insn[j].address);
                    }
                    break;
                }
            }
            cs_free(insn, count);
        }
    }
    printf("Gadget find = %d\n",total_gadget);
    cs_close(&handle);
    return 0;
}
예제 #15
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
	cs_insn *insn;
	int mode = (a->bits==64)? CS_MODE_64: 
		(a->bits==32)? CS_MODE_32:
		(a->bits==16)? CS_MODE_16: 0;
	int n, ret = cs_open (CS_ARCH_X86, mode, &handle);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = 0;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	if (ret == CS_ERR_OK) {
		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
		// capstone-next
		n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			int rs = a->bits/8;
			const char *pc = (a->bits==16)?"ip":
				(a->bits==32)?"eip":"rip";
			const char *sp = (a->bits==16)?"sp":
				(a->bits==32)?"esp":"rsp";
			op->size = insn->size;
			switch (insn->id) {
			case X86_INS_FNOP:
			case X86_INS_NOP:
			case X86_INS_HLT:
				op->type = R_ANAL_OP_TYPE_NOP;
				if (a->decode)
					esilprintf (op, "");
				break;
			case X86_INS_CLI:
			case X86_INS_STI:
			case X86_INS_CLC:
			case X86_INS_STC:
				break;
			case X86_INS_MOV:
			case X86_INS_MOVZX:
			case X86_INS_MOVABS:
			case X86_INS_MOVHPD:
			case X86_INS_MOVHPS:
			case X86_INS_MOVLPD:
			case X86_INS_MOVLPS:
			case X86_INS_MOVBE:
			case X86_INS_MOVSB:
			case X86_INS_MOVSD:
			case X86_INS_MOVSQ:
			case X86_INS_MOVSS:
			case X86_INS_MOVSW:
			case X86_INS_MOVD:
			case X86_INS_MOVQ:
			case X86_INS_MOVDQ2Q:
				op->type = R_ANAL_OP_TYPE_MOV;
				break;
			case X86_INS_CMP:
			case X86_INS_VCMP:
			case X86_INS_CMPPD:
			case X86_INS_CMPPS:
			case X86_INS_CMPSW:
			case X86_INS_CMPSD:
			case X86_INS_CMPSQ:
			case X86_INS_CMPSB:
			case X86_INS_CMPSS:
			case X86_INS_TEST:
				op->type = R_ANAL_OP_TYPE_CMP;
				break;
			case X86_INS_LEA:
				op->type = R_ANAL_OP_TYPE_LEA;
				break;
			case X86_INS_ENTER:
			case X86_INS_PUSH:
			case X86_INS_PUSHAW:
			case X86_INS_PUSHAL:
			case X86_INS_PUSHF:
				op->type = R_ANAL_OP_TYPE_PUSH;
				break;
			case X86_INS_LEAVE:
			case X86_INS_POP:
			case X86_INS_POPAW:
			case X86_INS_POPAL:
			case X86_INS_POPF:
			case X86_INS_POPCNT:
				op->type = R_ANAL_OP_TYPE_POP;
				break;
			case X86_INS_RET:
			case X86_INS_RETF:
			case X86_INS_IRET:
			case X86_INS_IRETD:
			case X86_INS_IRETQ:
			case X86_INS_SYSRET:
				op->type = R_ANAL_OP_TYPE_RET;
				if (a->decode)
					esilprintf (op, "%s,[%d],%s,=,%d,%s,+=",
						sp, rs, pc, rs, sp);
				break;
			case X86_INS_INT1:
			case X86_INS_INT3:
			case X86_INS_INTO:
			case X86_INS_INT:
			case X86_INS_VMCALL:
			case X86_INS_VMMCALL:
			case X86_INS_SYSCALL:
				op->type = R_ANAL_OP_TYPE_TRAP;
				if (a->decode)
					esilprintf (op, "%d,$", (int)INSOP(0).imm);
				break;
			case X86_INS_JL:
			case X86_INS_JLE:
			case X86_INS_JA:
			case X86_INS_JAE:
			case X86_INS_JB:
			case X86_INS_JBE:
			case X86_INS_JCXZ:
			case X86_INS_JECXZ:
			case X86_INS_JO:
			case X86_INS_JNO:
			case X86_INS_JS:
			case X86_INS_JNS:
			case X86_INS_JP:
			case X86_INS_JNP:
			case X86_INS_JE:
			case X86_INS_JNE:
			case X86_INS_JG:
			case X86_INS_JGE:
				op->type = R_ANAL_OP_TYPE_CJMP;
				op->jump = INSOP(0).imm;
				op->fail = addr+op->size;
				if (a->decode) {
					if (INSOP(0).type==X86_OP_IMM) {
// TODO
					}
				}
				break;
			case X86_INS_CALL:
			case X86_INS_LCALL:
				if (INSOP(0).type==X86_OP_IMM) {
					op->type = R_ANAL_OP_TYPE_CALL;
					// TODO: what if UCALL?
					// TODO: use imm_size
					op->jump = INSOP(0).imm;
					op->fail = addr+op->size;
				} else {
					op->type = R_ANAL_OP_TYPE_UCALL;
				}
				break;
			case X86_INS_JMP:
			case X86_INS_LJMP:
				// TODO: what if UJMP?
				op->jump = INSOP(0).imm;
				op->type = R_ANAL_OP_TYPE_JMP;
				if (a->decode) {
					ut64 dst = INSOP(0).imm;
					esilprintf (op, "0x%"PFMT64x",%s,=", dst, pc);
				}
				break;
			case X86_INS_IN:
			case X86_INS_INSW:
			case X86_INS_INSD:
			case X86_INS_INSB:
			case X86_INS_OUT:
			case X86_INS_OUTSB:
			case X86_INS_OUTSD:
			case X86_INS_OUTSW:
				op->type = R_ANAL_OP_TYPE_IO;
				break;
			case X86_INS_VXORPD:
			case X86_INS_VXORPS:
			case X86_INS_VPXORD:
			case X86_INS_VPXORQ:
			case X86_INS_VPXOR:
			case X86_INS_KXORW:
			case X86_INS_PXOR:
			case X86_INS_XOR:
				op->type = R_ANAL_OP_TYPE_XOR;
				break;
			case X86_INS_OR:
				op->type = R_ANAL_OP_TYPE_OR;
				break;
			case X86_INS_SUB:
			case X86_INS_DEC:
			case X86_INS_PSUBB:
			case X86_INS_PSUBW:
			case X86_INS_PSUBD:
			case X86_INS_PSUBQ:
			case X86_INS_PSUBSB:
			case X86_INS_PSUBSW:
			case X86_INS_PSUBUSB:
			case X86_INS_PSUBUSW:
				op->type = R_ANAL_OP_TYPE_SUB;
				break;
			case X86_INS_AND:
			case X86_INS_ANDN:
			case X86_INS_ANDPD:
			case X86_INS_ANDPS:
			case X86_INS_ANDNPD:
			case X86_INS_ANDNPS:
				op->type = R_ANAL_OP_TYPE_AND;
				break;
			case X86_INS_DIV:
				op->type = R_ANAL_OP_TYPE_DIV;
				break;
			case X86_INS_MUL:
				op->type = R_ANAL_OP_TYPE_MUL;
				break;
			case X86_INS_INC:
			case X86_INS_ADD:
			case X86_INS_FADD:
			case X86_INS_ADDPD:
				op->type = R_ANAL_OP_TYPE_ADD;
				break;
			}
		}
		cs_free (insn, n);
		cs_close (&handle);
	}
	return op->size;
}
예제 #16
0
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
	csh handle;
	cs_insn *insn;
	int mode, n, ret;
	mode = CS_MODE_BIG_ENDIAN;
	ret = cs_open (CS_ARCH_SYSZ, mode, &handle);
	op->type = R_ANAL_OP_TYPE_NULL;
	op->size = 0;
	op->delay = 0;
	r_strbuf_init (&op->esil);
	if (ret == CS_ERR_OK) {
		cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
		// capstone-next
		n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
		if (n<1) {
			op->type = R_ANAL_OP_TYPE_ILL;
		} else {
			op->size = insn->size;
			switch (insn->id) {
			case SYSZ_INS_BRCL:
			case SYSZ_INS_BRASL:
				op->type = R_ANAL_OP_TYPE_CALL;
				break;
			case SYSZ_INS_BR:
				op->type = R_ANAL_OP_TYPE_JMP;
				break;
			case SYSZ_INS_BRC:
			case SYSZ_INS_BER:
			case SYSZ_INS_BHR:
			case SYSZ_INS_BHER:
			case SYSZ_INS_BLR:
			case SYSZ_INS_BLER:
			case SYSZ_INS_BLHR:
			case SYSZ_INS_BNER:
			case SYSZ_INS_BNHR:
			case SYSZ_INS_BNHER:
			case SYSZ_INS_BNLR:
			case SYSZ_INS_BNLER:
			case SYSZ_INS_BNLHR:
			case SYSZ_INS_BNOR:
			case SYSZ_INS_BOR:
			case SYSZ_INS_BASR:
			case SYSZ_INS_BRAS:
			case SYSZ_INS_BRCT:
			case SYSZ_INS_BRCTG:
				op->type = R_ANAL_OP_TYPE_CJMP;
				break;
			case SYSZ_INS_JE:
			case SYSZ_INS_JGE:
			case SYSZ_INS_JHE:
			case SYSZ_INS_JGHE:
			case SYSZ_INS_JH:
			case SYSZ_INS_JGH:
			case SYSZ_INS_JLE:
			case SYSZ_INS_JGLE:
			case SYSZ_INS_JLH:
			case SYSZ_INS_JGLH:
			case SYSZ_INS_JL:
			case SYSZ_INS_JGL:
			case SYSZ_INS_JNE:
			case SYSZ_INS_JGNE:
			case SYSZ_INS_JNHE:
			case SYSZ_INS_JGNHE:
			case SYSZ_INS_JNH:
			case SYSZ_INS_JGNH:
			case SYSZ_INS_JNLE:
			case SYSZ_INS_JGNLE:
			case SYSZ_INS_JNLH:
			case SYSZ_INS_JGNLH:
			case SYSZ_INS_JNL:
			case SYSZ_INS_JGNL:
			case SYSZ_INS_JNO:
			case SYSZ_INS_JGNO:
			case SYSZ_INS_JO:
			case SYSZ_INS_JGO:
			case SYSZ_INS_JG:
				op->type = R_ANAL_OP_TYPE_CJMP;
				op->jump = INSOP(0).imm;
				op->fail = addr+op->size;
				break;
			case SYSZ_INS_J:
				op->type = R_ANAL_OP_TYPE_JMP;
				op->jump = INSOP(0).imm;
				op->fail = UT64_MAX;
				break;
			}
		}
		cs_free (insn, n);
		cs_close (&handle);
	}
	return op->size;
}
예제 #17
0
파일: test.c 프로젝트: Kernal-GH/monitor
static void test()
{
#define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
#define X86_CODE32 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00"
//#define X86_CODE32 "\x0f\xa7\xc0"	// xstorerng
#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00"
//#define ARM_CODE "\x04\xe0\x2d\xe5"
#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3"
#define ARM_CODE2 "\x10\xf1\x10\xe7\x11\xf2\x31\xe7\xdc\xa1\x2e\xf3\xe8\x4e\x62\xf3"
#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68"
#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0"
#define MIPS_CODE "\x0C\x10\x00\x97\x00\x00\x00\x00\x24\x02\x00\x0c\x8f\xa2\x00\x00\x34\x21\x34\x56"
#define MIPS_CODE2 "\x56\x34\x21\x34\xc2\x17\x01\x00"
//#define ARM64_CODE "\x00\x40\x21\x4b"	// 	sub		w0, w0, w1, uxtw
//#define ARM64_CODE "\x21\x7c\x02\x9b"	// mul	x1, x1, x2
//#define ARM64_CODE "\x20\x74\x0b\xd5"	// dc	zva, x0
//#define ARM64_CODE "\xe1\x0b\x40\xb9"	// ldr		w1, [sp, #0x8]
#define ARM64_CODE "\x21\x7c\x02\x9b\x21\x7c\x00\x53\x00\x40\x21\x4b\xe1\x0b\x40\xb9"
#define PPC_CODE "\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21"
#define SPARC_CODE "\x80\xa0\x40\x02\x85\xc2\x60\x08\x85\xe8\x20\x01\x81\xe8\x00\x00\x90\x10\x20\x01\xd5\xf6\x10\x16\x21\x00\x00\x0a\x86\x00\x40\x02\x01\x00\x00\x00\x12\xbf\xff\xff\x10\xbf\xff\xff\xa0\x02\x00\x09\x0d\xbf\xff\xff\xd4\x20\x60\x00\xd4\x4e\x00\x16\x2a\xc2\x80\x03"
#define SPARCV9_CODE "\x81\xa8\x0a\x24\x89\xa0\x10\x20\x89\xa0\x1a\x60\x89\xa0\x00\xe0"
#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"
#define XCORE_CODE "\xfe\x0f\xfe\x17\x13\x17\xc6\xfe\xec\x17\x97\xf8\xec\x4f\x1f\xfd\xec\x37\x07\xf2\x45\x5b\xf9\xfa\x02\x06\x1b\x10"
	struct platform {
		cs_arch arch;
		cs_mode mode;
		unsigned char *code;
		size_t size;
		char *comment;
		cs_opt_type opt_type;
		cs_opt_value opt_value;
	};
	struct platform platforms[] = {
		{ 
			CS_ARCH_X86,
			CS_MODE_16,
			(unsigned char*)X86_CODE16,
			sizeof(X86_CODE16) - 1,
			"X86 16bit (Intel syntax)"
		},
		{
			CS_ARCH_X86,
			CS_MODE_32,
			(unsigned char*)X86_CODE32,
			sizeof(X86_CODE32) - 1,
			"X86 32bit (ATT syntax)",
			CS_OPT_SYNTAX,
			CS_OPT_SYNTAX_ATT,
		},
		{
			CS_ARCH_X86,
			CS_MODE_32,
			(unsigned char*)X86_CODE32,
			sizeof(X86_CODE32) - 1,
			"X86 32 (Intel syntax)"
		},
		{
			CS_ARCH_X86,
			CS_MODE_64,
			(unsigned char*)X86_CODE64,
			sizeof(X86_CODE64) - 1,
			"X86 64 (Intel syntax)"
		},
		{ 
			CS_ARCH_ARM,
			CS_MODE_ARM,
			(unsigned char*)ARM_CODE,
			sizeof(ARM_CODE) - 1,
			"ARM"
		},
		{
			CS_ARCH_ARM,
			CS_MODE_THUMB,
			(unsigned char*)THUMB_CODE2,
			sizeof(THUMB_CODE2) - 1,
			"THUMB-2"
		},
		{ 
			CS_ARCH_ARM,
			CS_MODE_ARM,
			(unsigned char*)ARM_CODE2,
			sizeof(ARM_CODE2) - 1,
			"ARM: Cortex-A15 + NEON"
		},
		{
			CS_ARCH_ARM,
			CS_MODE_THUMB,
			(unsigned char*)THUMB_CODE,
			sizeof(THUMB_CODE) - 1,
			"THUMB"
		},
		{
			CS_ARCH_MIPS,
			(cs_mode)(CS_MODE_32 + CS_MODE_BIG_ENDIAN),
			(unsigned char*)MIPS_CODE,
			sizeof(MIPS_CODE) - 1,
			"MIPS-32 (Big-endian)"
		},
		{
			CS_ARCH_MIPS,
			(cs_mode)(CS_MODE_64 + CS_MODE_LITTLE_ENDIAN),
			(unsigned char*)MIPS_CODE2,
			sizeof(MIPS_CODE2) - 1,
			"MIPS-64-EL (Little-endian)"
		},
		{
			CS_ARCH_ARM64,
			CS_MODE_ARM,
			(unsigned char*)ARM64_CODE,
			sizeof(ARM64_CODE) - 1,
			"ARM-64"
		},
		{
			CS_ARCH_PPC,
			CS_MODE_BIG_ENDIAN,
			(unsigned char*)PPC_CODE,
			sizeof(PPC_CODE) - 1,
			"PPC-64"
		},
		{
			CS_ARCH_PPC,
			CS_MODE_BIG_ENDIAN,
			(unsigned char*)PPC_CODE,
			sizeof(PPC_CODE) - 1,
			"PPC-64, print register with number only",
			CS_OPT_SYNTAX,
			CS_OPT_SYNTAX_NOREGNAME
		},
		{
			CS_ARCH_SPARC,
			CS_MODE_BIG_ENDIAN,
			(unsigned char*)SPARC_CODE,
			sizeof(SPARC_CODE) - 1,
			"Sparc"
		},
		{
			CS_ARCH_SPARC,
			(cs_mode)(CS_MODE_BIG_ENDIAN + CS_MODE_V9),
			(unsigned char*)SPARCV9_CODE,
			sizeof(SPARCV9_CODE) - 1,
			"SparcV9"
		},
		{
			CS_ARCH_SYSZ,
			(cs_mode)0,
			(unsigned char*)SYSZ_CODE,
			sizeof(SYSZ_CODE) - 1,
			"SystemZ"
		},
		{
			CS_ARCH_XCORE,
			(cs_mode)0,
			(unsigned char*)XCORE_CODE,
			sizeof(XCORE_CODE) - 1,
			"XCore"
		},
	};

	csh handle;
	uint64_t address = 0x1000;
	cs_insn *insn;
	int i;
	size_t count;
	cs_err err;

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

		if (platforms[i].opt_type)
			cs_option(handle, platforms[i].opt_type, platforms[i].opt_value);

		count = cs_disasm_ex(handle, platforms[i].code, platforms[i].size, address, 0, &insn);
		if (count) {
			size_t j;

			print_string_hex(platforms[i].code, platforms[i].size);
			printf("Disasm:\n");

			for (j = 0; j < count; j++) {
				printf("0x%"PRIx64":\t%s\t\t%s\n",
						insn[j].address, insn[j].mnemonic, insn[j].op_str);
			}

			// print out the next offset, after the last insn
			printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size);

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

		printf("\n");

		cs_close(&handle);
	}
}