core/kernel_linux/clients/umbra/instrument.c
/* check if reg update is static known */
check if reg update is static known
check if reg update is static known
static bool
reg_update_is_known(instr_t *instr, ref_group_t ref_group[], reg_id_t reg, int pos)
{
    int opcode = instr_get_opcode(instr);
    int offset = 0;
    if ((opcode == OP_add || opcode == OP_sub) &&
        opnd_is_immed_int(instr_get_src(instr, 0))) {
        offset = opnd_get_immed_int(instr_get_src(instr, 0));
        if (opcode == OP_add)
            ref_group[pos].offset += offset;
        else
            ref_group[pos].offset -= offset;
        return true;
    }
    if (opcode == OP_inc) {
        ref_group[pos].offset += 1;
        return true;
    } else if (opcode == OP_dec) {
        ref_group[pos].offset -= 1;
        return true;
    }
    if (reg != REG_XSP)
        return false;
    if (opcode == OP_push || opcode == OP_push_imm || opcode == OP_pushf || 
        opcode == OP_call || opcode == OP_call_ind) {
        ref_group[pos].offset -= STACK_ALIGN_SIZE;
        return true;
    }
    if (opcode == OP_pusha) {
        ref_group[pos].offset -= 32;
        return true;
    }
    if (opcode == OP_pop || opcode == OP_ret) {
        if (opcode == OP_pop && opnd_same(instr_get_dst(instr, 0),
                                          opnd_create_reg(REG_XSP)))
            return false;
        ref_group[pos].offset += STACK_ALIGN_SIZE;
        return true;
    }
    if (opcode == OP_popf) {
        ref_group[pos].offset += STACK_ALIGN_SIZE;
        return true;
    }
    if (opcode == OP_popa) {
        ref_group[pos].offset += 32;
        return true;
    }
    return false;
}
static bool reg_update_is_known ( instr_t * instr , ref_group_t ref_group [ ] , reg_id_t reg , int pos ) { int opcode = instr_get_opcode ( instr ) ; int offset = 0 ; if ( ( opcode == OP_add || opcode == OP_sub ) && opnd_is_immed_int ( instr_get_src ( instr , 0 ) ) ) { offset = opnd_get_immed_int ( instr_get_src ( instr , 0 ) ) ; if ( opcode == OP_add ) ref_group [ pos ] . offset += offset ; else ref_group [ pos ] . offset -= offset ; return true ; } if ( opcode == OP_inc ) { ref_group [ pos ] . offset += 1 ; return true ; } else if ( opcode == OP_dec ) { ref_group [ pos ] . offset -= 1 ; return true ; } if ( reg != REG_XSP ) return false ; if ( opcode == OP_push || opcode == OP_push_imm || opcode == OP_pushf || opcode == OP_call || opcode == OP_call_ind ) { ref_group [ pos ] . offset -= STACK_ALIGN_SIZE ; return true ; } if ( opcode == OP_pusha ) { ref_group [ pos ] . offset -= 32 ; return true ; } if ( opcode == OP_pop || opcode == OP_ret ) { if ( opcode == OP_pop && opnd_same ( instr_get_dst ( instr , 0 ) , opnd_create_reg ( REG_XSP ) ) ) return false ; ref_group [ pos ] . offset += STACK_ALIGN_SIZE ; return true ; } if ( opcode == OP_popf ) { ref_group [ pos ] . offset += STACK_ALIGN_SIZE ; return true ; } if ( opcode == OP_popa ) { ref_group [ pos ] . offset += 32 ; return true ; } return false ; }
check if reg update is static known
check if reg update is static known
/* for case like eax + sizeof(element) => eax */ /* for case like push, pop */ /* only 32-bit instr */ /* pop %rsp */ /* XXX: add ENTER and LEAVE Instr */