示例#1
0
/*
 * push_shack()
 *  Push next guest eip into shadow stack.
 */
void push_shack(CPUState *env, TCGv_ptr cpu_env, target_ulong next_eip)
{
    // label
    int label_do_push = gen_new_label(); 
    // prepare registers
    TCGv_ptr temp_shack_end = tcg_temp_local_new_ptr(); // store shack end
    TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top
    TCGv temp_next_eip = tcg_temp_local_new(); // store eip
    // load common values
    tcg_gen_ld_ptr(temp_shack_end, cpu_env, offsetof(CPUState, shack_end));
    tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
    tcg_gen_mov_tl(temp_next_eip, tcg_const_tl(next_eip));
    // check shack full?
    tcg_gen_brcond_ptr(TCG_COND_NE,temp_shack_top,temp_shack_end,label_do_push); // if not full
    // flush here
    TCGv_ptr temp_shack_start = tcg_temp_new_ptr(); // store shack start
    //tcg_en_st_tl(tcg_const_tl(0), cpu_env, offsetof(CPUState, shadow_ret_count)); // reset ret count
    tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack));
    tcg_gen_mov_tl(temp_shack_top, temp_shack_start);
    tcg_temp_free_ptr(temp_shack_start);
    // call helper: flush the hash
    gen_helper_shack_flush(cpu_env);
    // end of flush
    gen_set_label(label_do_push);
    // do push here
    // push guest eip
    tcg_gen_st_ptr(temp_next_eip, temp_shack_top, 0); // store guest eip
    tcg_gen_addi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // increase top
    // call helper: check if we can fill the ret directly, or need to add hash-pair
    gen_helper_shack_push(cpu_env, temp_next_eip);
    // store back top
    tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
    // clean up
    tcg_temp_free(temp_next_eip);
    tcg_temp_free_ptr(temp_shack_top);
    tcg_temp_free_ptr(temp_shack_end);
}
示例#2
0
/*
 * pop_shack()
 *  Pop next host eip from shadow stack.
 */
void pop_shack(TCGv_ptr cpu_env, TCGv next_eip)
{
    
    // labels
    int label_end = gen_new_label();
    // prepare registers
    TCGv_ptr temp_shack_start = tcg_temp_local_new_ptr(); // store shack start
    TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top
    TCGv eip_on_shack = tcg_temp_local_new();
    TCGv_ptr host_slot_addr = tcg_temp_local_new();
    TCGv_ptr host_addr = tcg_temp_new();
    // load common values
    tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack));
    tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top));
    // check if stack empty?
    tcg_gen_brcond_ptr(TCG_COND_EQ,temp_shack_top,temp_shack_start,label_end);
    // stack not empty, pop one 
    tcg_gen_subi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // decrease top
    tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store back top
    tcg_gen_ld_tl(eip_on_shack, temp_shack_top, 0); // get eip
    // check if the same?
    tcg_gen_brcond_ptr(TCG_COND_NE,tcg_const_tl(next_eip),eip_on_shack,label_end); // go to "end" if not the same
    tcg_gen_ld_tl(host_slot_addr, temp_shack_top, sizeof(unsigned long)); // get slot addr
    tcg_gen_ld_ptr(host_addr, host_slot_addr, 0) ; // get host addr
    tcg_gen_brcond_ptr(TCG_COND_EQ,tcg_const_tl(0),host_addr,label_end); // go to "end" if addr is zero
    // jump!
    *gen_opc_ptr++ = INDEX_op_jmp;
    *gen_opparam_ptr++ = GET_TCGV_I32(host_addr);
    // label: end
    gen_set_label(label_end);
    tcg_temp_free(eip_on_shack);
    tcg_temp_free_ptr(host_slot_addr);
    tcg_temp_free_ptr(host_addr);
    tcg_temp_free_ptr(temp_shack_top);
    tcg_temp_free_ptr(temp_shack_start);
}
示例#3
0
/*
 * pop_shack()
 *  Pop next host eip from shadow stack.
 */
void pop_shack(TCGv_ptr cpu_env, TCGv next_eip)
{
#ifdef OPT_SHACK
    /* declare variables */
    int lab_end = gen_new_label();
    TCGv tcg_next_eip = tcg_temp_local_new();
    TCGv_ptr tcg_top_host_eip = tcg_temp_local_new_ptr();

    TCGv_ptr tcg_shack_top = tcg_temp_new_ptr();
    TCGv_ptr tcg_shack = tcg_temp_new_ptr();
    TCGv tcg_top_guest_eip = tcg_temp_new();
    
    /* check if shack is empty */
    tcg_gen_mov_tl(tcg_next_eip, next_eip);
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top
    tcg_gen_ld_ptr(tcg_shack, cpu_env, offsetof(CPUState, shack)); //load shack
    tcg_gen_brcond_i32(TCG_COND_EQ, tcg_shack_top, tcg_shack, lab_end); // if(shack_top == shack): jmp to lab_end
    
    /* shack not empty -> update shack top*/
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top
    tcg_gen_subi_i32(tcg_shack_top, tcg_shack_top, sizeof (void *)); //else: shack_top--
    tcg_gen_st_tl(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store shack top

    /* check if shack_top->guest_eip == tcg_next_eip */
    tcg_gen_ld_ptr(tcg_shack_top, tcg_shack_top, 0); // shack top = shack[shack_top]
    tcg_gen_ld_tl(tcg_top_guest_eip, tcg_shack_top, offsetof(struct shadow_pair, guest_eip)); //tcg_top_guest_eip = tcg_shack_top->guest_eip    
    tcg_gen_brcond_i32(TCG_COND_NE, tcg_top_guest_eip, tcg_next_eip, lab_end); // if(shack_top->guest_eip != next_eip): jmp to lab_end

    /* check if shack_top->host_eip is valid */
    
    tcg_gen_ld_ptr(tcg_shack_top, cpu_env, offsetof(CPUState, shack_top)); //load shack top
    tcg_gen_ld_ptr(tcg_shack_top, tcg_shack_top, 0); // shack top = shack[shack_top]
    tcg_gen_ld_ptr(tcg_top_host_eip, tcg_shack_top, offsetof(struct shadow_pair, host_eip)); //tcg_top_host_eip = tcg_shack_top->host_eip
    tcg_gen_brcond_i32(TCG_COND_EQ, tcg_top_host_eip, tcg_const_ptr(NULL), lab_end); // if(shack_top->host_eip == NULL): jmp to lab_end

    /* update return addr*/
    *gen_opc_ptr++ = INDEX_op_jmp;
    *gen_opparam_ptr++ = tcg_top_host_eip;

    /* clean up */
    gen_set_label(lab_end);
    tcg_temp_free_ptr(tcg_shack_top);
    tcg_temp_free_ptr(tcg_shack);
    tcg_temp_free_ptr(tcg_top_host_eip);
    tcg_temp_free(tcg_top_guest_eip);
    tcg_temp_free(tcg_next_eip);
#endif
}