📄 emit.c
字号:
return false;}boolemit_sysenter(machine_t *M, decode_t *d){ DEBUG(emits) fprintf(DBG, "sysenter "); #ifdef PROFILE // Calls emit_normal. #endif emit_syscall_handler(M, EMIT_SYSENTER_SYSCALL); return false;}/*********************************************************************Control-flow instructions I - Jumps, Calls, Returns, etc.*********************************************************************/boolemit_jcond(machine_t *M, decode_t *d){ unsigned char cond; unsigned long jmp_destn; DEBUG(emits) fprintf(DBG, "%lu: Jcond\n", M->nTrInstr); #ifdef PROFILE M->ptState->s_jmp_cond_cnt++; bb_emit_inc(M, MFLD(M, ptState->jmp_cond_cnt));#endif /* M->next_eip points to following instruction. Destination of * jump is M->next_eip + d->immediate. * * Solve this by setting M->next_eip to the target address and * then performing a conditional jump (in fact, the *same* * conditional jump) to the basic block exit point. */ jmp_destn = (unsigned long) (M->next_eip + d->immediate); /* Now, AND jmp_destn with 0x0000FFFFu if 16-bit mode instruction */ if (!THIRTY_TWO_BIT_INSTR(d)) jmp_destn = jmp_destn & 0x0000FFFFu; /* Now issue a (the same) conditional but always 32-bit jump either to the Patch Block or to the Destination Basic Block (if already present). The destination of this jump will be decided and filled up by the translator after completing the translation of the entire basic block. The short versions are all of the form 0x7?. The corresponding long versions are all of the form 0f 8? */ cond = (d->instr[0] == 0x0fu) ? d->instr[1] : d->instr[0]; if (d->flags & DSFL_GROUP2_PREFIX) bb_emit_byte(M, d->Group2_Prefix); bb_emit_byte(M, 0x0fu); bb_emit_byte(M, (cond & 0x0fu) | 0x80u); bb_emit_w32(M, 0); note_patch(M, M->bbOut - 4, (unsigned char *)jmp_destn, M->curr_bb_entry->proc_entry); /* M->patch_array[M->patch_count].to = (unsigned char *) jmp_destn; M->patch_array[M->patch_count].at = M->bbOut - 4; M->patch_array[M->patch_count].proc_addr = M->curr_bb_entry->proc_entry; M->patch_count ++; */#ifdef BUILD_BBS_FOR_JCOND_TRACE return continue_trace(M, d, M->next_eip);#else return false; /* continue with extended basic block! */#endif}boolemit_other_jcond(machine_t *M, decode_t *d){ unsigned long jmp_destn = (unsigned long) (M->next_eip + d->immediate); DEBUG(emits) fprintf(DBG, "%lu: Other-Jcond\n", M->nTrInstr);#ifdef PROFILE M->ptState->s_jmp_cond_cnt++; bb_emit_inc(M, MFLD(M, ptState->jmp_cond_cnt));#endif /* Now, AND jmp_destn with 0x0000FFFFu if 16-bit mode instruction */ if (!THIRTY_TWO_BIT_INSTR(d)) jmp_destn = jmp_destn & 0x0000FFFFu; if (d->flags & DSFL_GROUP2_PREFIX) bb_emit_byte(M, d->Group2_Prefix); if (d->opstate & OPSTATE_ADDR16) bb_emit_byte(M, 0x67u); /* Address-size Override Prefix - to indicate CX instead of ECX */ bb_emit_byte(M, ((OpCode *)(d->pEntry))->index); /* jcxz, loop, loope, loopne */ bb_emit_byte(M, 0x2u); /* Skip the following "skipping jump" instruction */ bb_emit_byte(M, 0xEBu); /* jmp rel8 */ bb_emit_byte(M, 5); /* len (Jump rel32) = 5 */ bb_emit_jump (M, 0); /* Dummy jump instruction which would be patched later by the translator */ note_patch(M, M->bbOut - 4, (unsigned char *)jmp_destn, M->curr_bb_entry->proc_entry);#ifdef BUILD_BBS_FOR_JCOND_TRACE return continue_trace(M, d, M->next_eip);#else return false; /* continue with extended basic block! */#endif}boolemit_jmp(machine_t *M, decode_t *d){ unsigned long jmp_destn = (unsigned long) (M->next_eip + d->immediate); DEBUG(emits) fprintf(DBG, "%lu: Jmp-Dir\n", M->nTrInstr);#ifdef PROFILE M->ptState->s_jmp_dir_cnt++; bb_emit_inc(M, MFLD(M, ptState->jmp_dir_cnt));#endif return continue_trace(M, d, jmp_destn);}boolemit_call_disp(machine_t *M, decode_t *d){ unsigned long jmp_destn = (unsigned long) (M->next_eip + d->immediate); /* unsigned long callee_index = jmp_destn & (CALL_HASH_MASK); */ /* unsigned long hash_entry_addr = ((unsigned long) &M->call_hash_table) + callee_index; */ /* unsigned long callee_index = jmp_destn & (CALL_HASH_MASK); */ unsigned long hash_entry_addr = CALL_HASH_BUCKET(M->call_hash_table, jmp_destn); bb_entry *entry, *temp_entry; DEBUG(emits) /* */ fprintf(DBG, "%lu: Call-Dir\n", M->nTrInstr);#ifdef PROFILE M->ptState->s_call_dir_cnt++; bb_emit_inc(M, MFLD(M, ptState->call_dir_cnt));#endif /* Now, AND jmp_destn with 0x0000FFFFu if 16-bit mode instruction */ if (!THIRTY_TWO_BIT_INSTR(d)) jmp_destn = jmp_destn & 0x0000FFFFu; /* M->next_eip points to following instruction. Push M->next_eip */ /* We just Push */ bb_emit_byte(M, 0x68u); /* PUSH */ bb_emit_w32(M, M->next_eip);#ifdef CALL_RET_OPT /* MOV M->proc_hash_table[callee_index], expected_return_address */ // fprintf(DBG, "Came in Disp 1\n"); bb_emit_store_immediate_to(M, (unsigned long)(M->bbOut + 10 + 5), hash_entry_addr); #endif bb_emit_jump (M, 0); /* Dummy jump instruction which would be patched later by the translator */ note_patch(M, M->bbOut - 4, (unsigned char *)jmp_destn, hash_entry_addr); DEBUG(call_ret_opt) fprintf(DBG, "Encountered a CALL(%lx); set Patch Block[%d]'s proc_addr to %lx\n", jmp_destn, M->patch_count, hash_entry_addr); #ifdef CALL_RET_OPT /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ //fprintf(DBG, "Came in Disp 2\n"); /* push %ecx */ bb_emit_byte(M, 0x51u); /* mov 4(%esp) %ecx */ bb_emit_byte(M, 0x8bu); bb_emit_byte(M, 0x4cu); // 01 001 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_byte(M, 0x4u); /* lea -(M->next_eip)(%ecx) , %ecx */ bb_emit_byte(M, 0x8du); // 8D /r bb_emit_byte(M, 0x89u); // 10 001 001 bb_emit_w32(M, (-((long)M->next_eip)));#ifdef SIEVE_WITHOUT_PPF /* jecxz equal */ bb_emit_byte(M, 0xe3u); bb_emit_byte(M, 0x5u);#else /* jecxz equal */ bb_emit_byte(M, 0xe3u); bb_emit_byte(M, 0x6u); /* pop ecx */ bb_emit_byte(M, 0x59u);#endif /* SIEVE_WITHOUT_PPF */ /* jmp fast_dispatch */ bb_emit_jump(M, M->call_calls_fast_dispatch_bb); /* equal: pop ecx */ bb_emit_byte(M, 0x59u); // esp += 4; leal 4(%esp), %esp bb_emit_byte(M, 0x8du); bb_emit_byte(M, 0xA4u); /* 10 100 100 */ bb_emit_byte(M, 0x24u); /* 00 100 100 */ bb_emit_w32(M, 0x4u);#endif /* CALL_RET_OPT */#ifdef PROFILE_BB_STATS M->curr_bb_entry->flags |= NEEDS_RELOC;#endif return continue_trace(M, d, M->next_eip);}boolemit_jmp_near_mem(machine_t *M, decode_t *d){#ifdef PROFILE M->ptState->s_jmp_indr_cnt++; bb_emit_inc(M, MFLD(M, ptState->jmp_indr_cnt));#endif DEBUG(emits) fprintf(DBG, "%lu: Jump-Indir\n", M->nTrInstr); // fprintf(DBG, "Jmp near mem at %lx %lx\n", M->next_eip, M->bbOut); bb_emit_push_rm(M, d); bb_emit_jump (M, M->fast_dispatch_bb); return true;}boolemit_call_near_mem(machine_t *M, decode_t *d){ bool dest_based_on_esp = false; #ifdef PROFILE M->ptState->s_call_indr_cnt++; bb_emit_inc(M, MFLD(M, ptState->call_indr_cnt));#endif DEBUG(emits) fprintf(DBG, "%lu: Call-Indir\n", M->nTrInstr); if(d->modrm.parts.reg == 0x4u) dest_based_on_esp = true; else if(d->modrm.parts.mod == 0x3u) { if(d->modrm.parts.rm == 0x4u) dest_based_on_esp = true; } else if(d->modrm.parts.rm == 0x4u && d->sib.parts.base == 0x4u) dest_based_on_esp = true; if(!dest_based_on_esp) { /* Push M->next_eip */ bb_emit_byte(M, 0x68u); /* PUSH */ bb_emit_w32(M, M->next_eip); bb_emit_push_rm(M, d); } else { /* Push the computed destination */ /*** has to be done without touching the value of %esp ***/ bb_emit_push_rm(M, d); /* xchg %eax, (%esp) */ bb_emit_byte(M, 0x87u); // 87 /r bb_emit_byte(M, 0x04u); // 00 000 100 bb_emit_byte(M, 0x24u); // 00 100 100 /* push %eax */ bb_emit_byte(M, 0x50u); /* mov 4(%esp), %eax */ bb_emit_byte(M, 0x8bu); // 8b /r bb_emit_byte(M, 0x44u); // 01 000 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_byte(M, 0x04u); /* mov $M->next_eip, 4(%esp) */ bb_emit_byte(M, 0xc7u); // C7 /0 bb_emit_byte(M, 0x44u); // 01 000 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_byte(M, 0x04u); bb_emit_w32(M, M->next_eip); }#ifdef CALL_RET_OPT //fprintf(DBG, "Came in mem 1\n"); /* PUSH %ecx */ bb_emit_byte (M, 0x51u); /* mov 4(%esp), %ecx */ bb_emit_byte(M, 0x8bu); // 8b /r bb_emit_byte(M, 0x4Cu); // 01 001 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_byte(M, 0x04u); /* AND ECX with (CALL_HASH_MASK = CALL_TABLE_SIZE -1) */ /* achieved by movzx %cl %ecx This is because CALL_TABLE SIZE is 2^8 = 256 */ bb_emit_byte(M, 0x0Fu); // 0F B6 /r bb_emit_byte(M, 0xB6u); // 10 110 110 bb_emit_byte(M, 0xC9u); // 11 001 001 #ifdef SIEVE_WITHOUT_PPF /* MOV $(M->bbOut + past_jump), M->call_hash_table(,%ecx,4) */ bb_emit_byte(M, 0xC7u); // C7 /0 bb_emit_byte(M, 0x04u); /* 00 000 100 */ bb_emit_byte(M, 0x8Du); /* 10 001 101 */ bb_emit_w32 (M, (unsigned long) M->call_hash_table); bb_emit_w32 (M, (((unsigned long)M->bbOut) + 4 + 5));#ifdef USE_SIEVE#ifdef SEPARATE_SIEVES /* JMP M->fast_dispatch */ bb_emit_jump (M, M->cfast_dispatch_bb);#else bb_emit_jump (M, (unsigned char *) ((unsigned long)M->fast_dispatch_bb + 1));#endif#else bb_emit_jump (M, (unsigned char *) ((unsigned long)M->fast_dispatch_bb));#endif /* USE_SIEVE */#else /* MOV $(M->bbOut + past_jump), M->call_hash_table(,%ecx,4) */ bb_emit_byte(M, 0xC7u); // C7 /0 bb_emit_byte(M, 0x04u); /* 00 000 100 */ bb_emit_byte(M, 0x8Du); /* 10 001 101 */ bb_emit_w32 (M, (unsigned long) M->call_hash_table); bb_emit_w32 (M, (((unsigned long)M->bbOut) + 4 + 6)); /* POP %ecx */ bb_emit_byte (M, 0x59u); /* JMP M->fast_dispatch */ bb_emit_jump (M, M->fast_dispatch_bb);#endif /* SIEVE_WITHOUT_PPF */#else /* JMP M->fast_dispatch */ bb_emit_jump (M, M->fast_dispatch_bb);#endif /* CALL_RET_OPT */#ifdef CALL_RET_OPT /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ // fprintf(DBG, "Came in mem 2\n"); /* push %ecx */ bb_emit_byte(M, 0x51u); /* mov 4(%esp) %ecx */ bb_emit_byte(M, 0x8bu); bb_emit_byte(M, 0x4cu); // 01 001 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_byte(M, 0x4u); /* lea -(M->next_eip)(%ecx) , %ecx */ bb_emit_byte(M, 0x8du); // 8D /r bb_emit_byte(M, 0x89u); // 10 001 001 bb_emit_w32(M, (-((long)M->next_eip)));#ifdef SIEVE_WITHOUT_PPF /* jecxz equal */ bb_emit_byte(M, 0xe3u); bb_emit_byte(M, 0x5u);#else /* jecxz equal */ bb_emit_byte(M, 0xe3u); bb_emit_byte(M, 0x6u); /* pop ecx */ bb_emit_byte(M, 0x59u);#endif /* jmp fast_dispatch */ bb_emit_jump(M, M->call_calls_fast_dispatch_bb); /* pop ecx */ bb_emit_byte(M, 0x59u); // esp += 4; leal 4(%esp), %esp bb_emit_byte(M, 0x8du); bb_emit_byte(M, 0xA4u); /* 10 100 100 */ bb_emit_byte(M, 0x24u); /* 00 100 100 */ bb_emit_w32(M, 0x4u);#endif /* CALL_RET_OPT */#ifdef PROFILE_BB_STATS M->curr_bb_entry->flags |= NEEDS_RELOC;#endif return continue_trace(M, d, M->next_eip);}boolemit_ret(machine_t *M, decode_t *d){#ifdef PROFILE M->ptState->s_ret_cnt++; bb_emit_inc(M, MFLD(M, ptState->ret_cnt));#endif DEBUG(emits) fprintf(DBG, "%lu: Ret\n", M->nTrInstr);#ifdef CALL_RET_OPT // fprintf(DBG, "Came in ret\n"); /* Jmp *M->curr_bb_entry->proc_entry */ bb_emit_byte(M, 0xFFu); bb_emit_byte(M, 0x25u); /* 00 100 101 */ bb_emit_w32(M, M->curr_bb_entry->proc_entry);#else /* JMP M->fast_dispatch */ bb_emit_jump (M, M->fast_dispatch_bb);#endif#ifdef PROFILE_BB_STATS M->curr_bb_entry->flags |= NEEDS_RELOC;#endif return true;}boolemit_ret_Iw(machine_t *M, decode_t *d){#ifdef PROFILE M->ptState->s_ret_Iw_cnt++; bb_emit_inc(M, MFLD(M, ptState->ret_Iw_cnt));#endif DEBUG(emits) fprintf(DBG, "%lu: Ret-IW\n", M->nTrInstr); /* Will there be a problem if d->imm16 < 4 ?? I think this should not be the case */ /* Pop (d->imm16-4)(%esp) */ if (d->opstate & OPSTATE_ADDR16) bb_emit_byte(M, 0x66u); /* Operand-size Override Prefix - to indicate 16 bit Return address */ bb_emit_byte(M, 0x8Fu); // 8F /0 bb_emit_byte(M, 0x84u); // 10 000 100 bb_emit_byte(M, 0x24u); // 00 100 100 bb_emit_w32(M, (unsigned long)d->imm16-4); if(d->imm16 - 4 != 0) { /* leal (d->imm16-4)(%esp), %esp */ bb_emit_byte(M, 0x8du); bb_emit_byte(M, 0xA4u); /* 10 100 100 */ bb_emit_byte(M, 0x24u); /* 00 100 100 */ bb_emit_w32(M, (unsigned long)d->imm16 - 4); } #ifdef CALL_RET_OPT /* Jmp *M->curr_bb_entry->proc_entry */ // fprintf(DBG, "Came in ret IW \n"); bb_emit_byte(M, 0xFFu); bb_emit_byte(M, 0x25u); /* 00 100 101 */ bb_emit_w32(M, M->curr_bb_entry->proc_entry);#else /* JMP M->fast_dispatch */ bb_emit_jump (M, M->fast_dispatch_bb);#endif#ifdef PROFILE_BB_STATS M->curr_bb_entry->flags |= NEEDS_RELOC;#endif return true;}/* asm volatile ("movl %0, %%eax\n\t" *//* "push %1\n\t" *//* "call init_thread_trans\n\t" *//* "mov (%%eax), %%eax\n\t" *//* "movl %%eax, %2\n\t" *//* "leal 4(%%esp), %%esp\n\t" *//* "popa\n\t" *//* "mov %2, %%esp\n\t" *//* "leave\n\t" *//* "retl\n\t" *//* : *//* : "m" (regs.eax), "m" (next_eip), "m" (Maddr) *//* ); *//* asm volatile ("mov %0, %%esi\n\t" *//* "mov %1, %%esp\n\t" *//* "push %%esi\n\t" *//* "call init_thread_trans\n\t" *//* "leal 4(%%esp), %%esp\n\t" *//* "mov (%%eax), %%eax\n\t" *//* "jmp *%%eax\n\t" *//* : *//* : "m" (next_eip), "m" (pastM) *//* : "%eax" *//* ); */ /* Not reached */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -