Exemple #1
0
int read_ModR_M(swaddr_t eip, Operand *rm, Operand *reg) {
	ModR_M m;
	m.val = instr_fetch(eip, 1);
    // Log("m.val = %02x", m.val);
	reg->type = OP_TYPE_REG;
	reg->reg = m.reg;

	if(m.mod == 3) {
		rm->type = OP_TYPE_REG;
		rm->reg = m.R_M;
		switch(rm->size) {
			case 1: rm->val = reg_b(m.R_M); break;
			case 2: rm->val = reg_w(m.R_M); break;
			case 4: rm->val = reg_l(m.R_M); break;
			default: assert(0);
		}
#ifdef DEBUG
		switch(rm->size) {
			case 1: sprintf(rm->str, "%%%s", regsb[m.R_M]); break;
			case 2: sprintf(rm->str, "%%%s", regsw[m.R_M]); break;
			case 4: sprintf(rm->str, "%%%s", regsl[m.R_M]); break;
		}
#endif
		return 1;
	}
	else {
		int instr_len = load_addr(eip, &m, rm);
		rm->val = swaddr_read(rm->addr, rm->size, R_DS); //TODO DS or SS
		return instr_len;
	}
}
Exemple #2
0
void print_bin_instr(swaddr_t eip, int len) {
	int i;
	int l = sprintf(asm_buf, "%8x:   ", eip);
	for(i = 0; i < len; i ++) {
		l += sprintf(asm_buf + l, "%02x ", instr_fetch(eip + i, 1));
	}
	sprintf(asm_buf + l, "%*.s", 50 - (12 + 3 * len), "");
}
Exemple #3
0
int mov_rm2sr(swaddr_t eip){
    /* decode rm */
    int len = decode_rm_w(eip + 1);

    /* decode sreg */
    uint8_t addr = instr_fetch(eip + 1, 1);
    int sr_index = (addr >> 3) & 7;
    cpu.Sreg[sr_index].val = op_src -> val;

    /* set sreg base and limit */
    uint64_t base_limit = decode_gdt(cpu.Sreg[sr_index].index);
    cpu.Sreg[sr_index].base = base_limit >> 32;
    cpu.Sreg[sr_index].limit = (base_limit << 32) >> 32;

    return len+1;
}
Exemple #4
0
static make_helper(_2byte_esc) {
	eip ++;
	uint32_t opcode = instr_fetch(eip, 1);
	ops_decoded.opcode = opcode | 0x100;
	return _2byte_opcode_table[opcode](eip) + 1; 
}
Exemple #5
0
int load_addr(swaddr_t eip, ModR_M *m, Operand *rm) {
	assert(m->mod != 3);

	int32_t disp;
	int instr_len, disp_offset, disp_size = 4;
	int base_reg = -1, index_reg = -1, scale = 0;
	swaddr_t addr = 0;

	if(m->R_M == R_ESP) {
		SIB s;
		s.val = instr_fetch(eip + 1, 1);
		base_reg = s.base;
		disp_offset = 2;
		scale = s.ss;

 		
		if(s.index != R_ESP) { index_reg = s.index; }
		/*
		if (s.ss==0&&s.index==R_EBP){
			rm->sreg=R_SS; 
		}
 		*/
 	}
	else {
		/* no SIB */
		base_reg = m->R_M;
		disp_offset = 1;
	}
	
	if (base_reg==R_ESP||base_reg==R_EBP){
		rm->sreg=R_SS;	
	}else{
		rm->sreg=R_DS;
 	}
	
	 if(m->mod == 0) {
		if(base_reg == R_EBP) { base_reg = -1; }
		else { disp_size = 0; }
	}
	else if(m->mod == 1) { disp_size = 1; }

	instr_len = disp_offset;
	if(disp_size != 0) {
		/* has disp */
		disp = instr_fetch(eip + disp_offset, disp_size);
		if(disp_size == 1) { disp = (int8_t)disp; }

		instr_len += disp_size;
		addr += disp;
	}

	if(base_reg != -1) {
		addr += reg_l(base_reg);
	}

 	if(index_reg != -1) {
		addr += reg_l(index_reg) << scale;
	}

#ifdef DEBUG
	char disp_buf[16];
	char base_buf[8];
	char index_buf[8];

	if(disp_size != 0) {
		/* has disp */
		sprintf(disp_buf, "%s%#x", (disp < 0 ? "-" : ""), (disp < 0 ? -disp : disp));
	}
	else { disp_buf[0] = '\0'; }

	if(base_reg == -1) { base_buf[0] = '\0'; }
	else { 
		sprintf(base_buf, "%%%s", regsl[base_reg]); 
	}

	if(index_reg == -1) { index_buf[0] = '\0'; }
	else { 
		sprintf(index_buf, ",%%%s,%d", regsl[index_reg], 1 << scale); 
	}

	if(base_reg == -1 && index_reg == -1) {
		sprintf(rm->str, "%s", disp_buf);
	}
	else {
		sprintf(rm->str, "%s(%s%s)", disp_buf, base_buf, index_buf);
	}
#endif

	rm->type = OP_TYPE_MEM;
	rm->addr = addr;

	return instr_len;
}
Exemple #6
0
/* For more details about instruction format, please refer to i386 manual. */
int read_ModR_M(swaddr_t eip, swaddr_t *addr) {
	ModR_M m;
	m.val = instr_fetch(eip, 1);
	int32_t disp;
	int instr_len, disp_offset, disp_size;
	int base_reg = -1, index_reg = -1, scale = 0;

	/* When m.mod == 3, the instruction is not going to access memory.
	 * This situation should be handle before calling read_ModR_M(). 
	 * Therefore, m.mod should not be 3 here.
	 */
	assert(m.mod != 3);
	disp_size = 4;
	if(m.R_M == R_ESP) {
		SIB s;
		s.val = instr_fetch(eip + 1, 1);
		base_reg = s.base;
		disp_offset = 2;
		scale = s.ss;

		if(s.index != R_ESP) { index_reg = s.index; }
	}
	else {
		/* no SIB */
		base_reg = m.R_M;
		disp_offset = 1;
	}

	if(m.mod == 0) {
		if(base_reg == R_EBP) { base_reg = -1; }
		else { disp_size = 0; }
	}
	else if(m.mod == 1) { disp_size = 1; }


	char disp_buf[16];
	char base_buf[8];
	char index_buf[8];

	instr_len = disp_offset;
	*addr = 0;
	if(disp_size != 0) {
		/* has disp */
		disp = instr_fetch(eip + disp_offset, disp_size);
		if(disp_size == 1) { disp = (int8_t)disp; }
		sprintf(disp_buf, "%s%#x", (disp < 0 ? "-" : ""), (disp < 0 ? -disp : disp));

		instr_len += disp_size;
		*addr += disp;
	}
	else { disp_buf[0] = '\0'; }

	if(base_reg == -1) { base_buf[0] = '\0'; }
	else { 
		sprintf(base_buf, "%%%s", regsl[base_reg]); 
		*addr += reg_l(base_reg);
	}

	if(index_reg == -1) { index_buf[0] = '\0'; }
	else { 
		sprintf(index_buf, ",%%%s,%d", regsl[index_reg], 1 << scale); 
		*addr += reg_l(index_reg) << scale;
	}

	if(base_reg == -1 && index_reg == -1) {
		print_ModR_M_asm("%s", disp_buf);
	}
	else {
		print_ModR_M_asm("%s(%s%s)", disp_buf, base_buf, index_buf);
	}

	return instr_len;
}
Exemple #7
0
/*
 * @describe evaluate the expression and return the value
 * @param {int, int} p, q
 * @return {int} value
 */
uint32_t eval(int p, int q) {
    if(p > q) {
        /* Bad expression */
        assert(0);
    }
    else if(p == q) {
        /*
         * Single token
         * For now, this token should be a number
         * return the value of the exprssion
         */

        if(tokens[p].type == VAR) {
            int res = find_var(tokens[p].str);
            if(res == -1) {
                printf("undefined reference to %s!\n", tokens[p].str);
                return 0;
            }
            return res;
        }
        if(tokens[p].type == DEC_NUM) {
            return atoi(tokens[p].str);
        }
        if(tokens[p].type == HEX_NUM) {
            return strtol(tokens[p].str, NULL, 16);
        }
        if(tokens[p].type == REG) {
            return getreg(tokens[p].str);
        }
    }
    else if(check_parentness(p, q) == true) {
        /*
         * The expression is surrounded by a matched pair of parentheses.
         * If that is the case, just throw away the parentheses.
         */
         return eval(p + 1, q - 1);
    }
    else {
        int i;
        int j;
        int op = -1;
        int flag = 0;		//操作符优先级标志

        uint32_t val1;
        uint32_t val2;

        if(tokens[p].type == NEG) {
            if(check_parentness(p + 1, q) || p + 1 == q) {
                return -1 * eval(p + 1, q);
            }
        }
        else if(tokens[p].type == DEREF) {
            if(check_parentness(p + 1, q) || p + 1 == q) {
                return instr_fetch(eval(p + 1, q), 1);
            }
        }
        else if(tokens[p].type == '!') {
            if(check_parentness(p + 1, q) || p + 1 == q) {
                return !eval(p + 1, q);
            }
        }
        for(i = p, j = 0; i <= q; i++) {
            //操作符优先级
            if(tokens[i].type == '(' ) {
                j++;
            }
            else if(tokens[i].type == ')') {
                j--;
            }
            else if(j == 0
                    && (tokens[i].type == EQ || tokens[i].type == NEQ
                    || tokens[i].type == LEQ || tokens[i].type == GEQ
                    || tokens[i].type == L || tokens[i].type == G)) {
                if(flag < 4) {
                    flag = 4;
                    op = i;
                }
            }
            else if(j == 0
                && (tokens[i].type == AND || tokens[i].type == OR)) {
                if(flag < 3) {
                    op = i;
                    flag = 3;
                }
            }
            else if(j == 0
                    && (tokens[i].type == '+' || tokens[i].type == '-')) {
                if(flag < 2) {
                    op = i;
                    flag = 2;
                }
            }
            else if(j == 0
                    && (tokens[i].type == '*' || tokens[i].type == '/')) {
                if(flag < 1) {
                    op = i;
                    flag = 1;
                }
            }
        }

        val1 = eval(p, op - 1);
        val2 = eval(op + 1, q);
        switch(tokens[op].type) {
            case '+':
                return val1 + val2;
                break;
            case '-':
                return val1 - val2;
                break;
            case '*':
                return val1 * val2;
                break;
            case '/':
                if(val2 == 0) {
                    printf("Error\n");
                    break;
                }
                return val1 / val2;
                break;
            case EQ:
                return val1 == val2 ? 1 : 0;
                break;
            case NEQ:
                return val1 != val2 ? 1 : 0;
                break;
            case LEQ:
                return val1 <= val2 ? 1 : 0;
                break;
            case GEQ:
                return val1 >= val2 ? 1 : 0;
                break;
            case L:
                return val1 < val2 ? 1 : 0;
                break;
            case G:
                return val1 > val2 ? 1 : 0;
                break;
            case AND:
                return val1 && val2;
                break;
            case OR:
                return val1 || val2;
                break;
            default: assert(0);
		}
	}

	return 0;
}