byte * _f_handler_inst_jmp2(byte * inst) { dword target = *(dword*)(inst+1); //flux_staple(RADDR(inst),5); if (do_jmp((dword)RADDR(inst), (dword)RADDR(inst+5+target),2)) { log_data("jmping (32-bits) rel: (%i)",target); return inst+5+target; } return 0; }
byte * _f_handler_inst_jmp(byte * inst) { char target = *(char*)(inst+1); if (do_jmp((dword)RADDR(inst), (dword)RADDR(inst+2+target),2)) { log_data("jmping (8-bits) rel: (%i)",target); return inst+2+target; } return 0; }
byte * _f_handler_inst_shl32(byte * inst) { /*mod reg gives an operand here, but it's irrelevant for this phase */ dword rtype, arg1, arg2; MODREGDEC(inst+1,arg1,arg2,rtype); flux_staple(RADDR(inst),3); return inst+3; }
byte * _f_handler_inst_gen5_inst(byte * inst) { dword rtype, arg1, arg2; MODREGDEC(inst+1,arg1,arg2,rtype); switch (arg2) { case INST_GEN_TEST1: case INST_GEN_TEST2: break; case INST_GEN_NOT: flux_staple(RADDR(inst),2); return inst+2; } flux_staple(RADDR(inst),2); return inst+2; }
byte * _f_handler_inst_inc_2(byte * inst) { mem_full_ref src,dest; dword flags = 0; byte * o = inst; inst = modreg_analysis(inst, &dest, &src, &flags); flux_staple(RADDR(o),inst-o); return inst; }
void mem2() { struct inst * curr; if( MEM2 == EMPTY ) return; else if( MEM2_stall ) { fprintf( fout, "I%d-stall ", MEM2_count ); return; } else /* not stall, not empty */ { curr = Instructions[MEM2]; if( (*curr).itype == LD ) Registers[ RADDR((*curr).rt) ] = Memory[ MEMLOC( Registers[ RADDR((*curr).rs) ] + (*curr).value) ]; else if( (*curr).itype == SD ) Memory[ MEMLOC(Registers[ RADDR((*curr).rs) ] + (*curr).value) ] = Registers[ RADDR((*curr).rt) ]; fprintf( fout, "I%d-MEM2 ", MEM2_count ); } }
byte * _f_handler_inst_imul2(byte * inst) { byte * o = inst; mem_full_ref dest; dword flags = MOD_FLAG_DEST_ONLY; inst = modreg_analysis(inst,0,&dest,&flags); flux_staple(RADDR(o),(inst-o)+1); return inst+1; }
byte * _f_handler_inst_gen_32bits2(byte * inst) { dword rtype, arg1, arg2; MODREGDEC(inst+1,arg1,arg2,rtype); //log_debug("gen %X",arg2); int disp; if (*inst == INST_GEN_32BITS2 || *inst == INST_GEN_8BITS || *inst == INST_GEN_8BITS2) { disp = 1; } else if (*inst == INST_GEN_32BITS) { disp = 4; } /* TODO embbed this on the mphash */ switch (arg2) { case INST_GEN_ADD: case INST_GEN_OR: case INST_GEN_ADC: case INST_GEN_SBB: case INST_GEN_AND: case INST_GEN_SUB: case INST_GEN_XOR: case INST_GEN_CMP: log_debug("rtype %X",disp); if (rtype == smod_reg_I32R) { if (arg1 == mod_reg_SIB) { flux_staple(RADDR(inst),7+disp); return inst+7+disp; } flux_staple(RADDR(inst),6+disp); return inst+6+disp; } else if (rtype == smod_reg_I8R) { flux_staple(RADDR(inst),3+disp); log_debug("ret +%i",3+disp); return inst+3+disp; } else if (rtype == smod_reg_RR) { flux_staple(RADDR(inst),2+disp); return inst+2+disp; } else if (rtype == smod_reg_IR) { if (arg1 == mod_reg_EBP) { flux_staple(RADDR(inst),2+disp+4); return inst+2+disp+4; } flux_staple(RADDR(inst),2+disp); return inst+2+disp; } flux_staple(RADDR(inst),2+disp); return inst+2+disp; } }
byte * _f_handler_inst_gen_mov(byte * inst) { dword size = 0; if ((*inst) & 0x8) { /* 32 bits */ size = 4; } else { size = 1; } byte * o = inst; inst = inst+1+size; flux_staple(RADDR(o),inst-o); return inst; }
byte * _f_handler_inst_db_op(byte * inst) { dword flags = 0; mem_full_ref dest; mem_full_ref src; dword rtype, arg1, arg2; byte * o = inst; dword target; /* these instructions have two operands */ byte op = *(inst+1); switch(op) { case DB_INST_MOVZX: inst = modreg_analysis(inst+1, &dest, &src, &flags); flux_staple(RADDR(o),inst-o); return inst; break; case DB_INST_SETZ: inst = modreg_analysis(inst+1, &dest, &src, &flags); flux_staple(RADDR(o),inst-o); return inst; break; case DB_INST_SETNZ: inst = modreg_analysis(inst+1, &dest, &src, &flags); flux_staple(RADDR(o),inst-o); return inst; case DB_INST_JZ: case DB_INST_JGE: //flux_staple(RADDR(o),6); target = *(dword*)(inst+2); do_branch(RADDR(inst),(dword)RADDR(inst+6+target),6); return inst+6; case DB_INST_ADD: flux_staple(RADDR(o),6); return inst+6; case DB_INST_JNZ: flux_staple(RADDR(o),6); return inst+6; case DB_INST_IMUL: flux_staple(RADDR(o),4); return inst+4; } return inst; }
byte * _f_handler_inst_leave(byte * inst) { flux_staple(RADDR(inst),1); log_debug("leave"); return inst+1; }
byte * _f_handler_inst_preover(byte * inst) { byte * o = inst; inst = cur_handlers->handler[*(inst+1)](inst+1); flux_staple(RADDR(o),inst-o); return inst; }
byte * _f_handler_inst_dec(byte * inst) { flux_staple(RADDR(inst),1); return (inst+1); }
byte * _f_handler_inst_retn(byte * inst) { log_data("RETN reached"); do_ret(RADDR(inst),1); return 0; }
byte * _f_handler_inst_gen_1op(byte * inst) { dword rtype, arg1, arg2; MODREGDEC(inst+1,arg1,arg2,rtype); dword target; it_inner_entry *it; /* TODO embbed this on the mphash */ switch (arg2) { case INST_GEN_CALL: if (rtype == smod_reg_RR) { flux_staple(RADDR(inst),2); return inst+2; } target = *(dword*)(inst+2); log_debug("CALL to %X",target); if (!is_code(target,&it)) { if (it) { /* maybe examine here the arguments for ease of analysis? */ log_debug("External function (%s) (%s)",it->name,it->libname); if (!strcmp("ExitProcess",it->name)) { /* its an exit process, function ends here */ do_ret(RADDR(inst),6); log_debug("exit function reached"); return 0; } } } else { //return (byte*)target; /* queue function for analysis */ } flux_staple(RADDR(inst),6); return inst+6; case INST_GEN_JMP: target = *(dword*)(inst+2); it_inner_entry * it; if (!is_code(target,&it)) { log_debug("JMP to outside, assuming ret"); /* this is used normally to call external functions in a relloc fashion, assume RET here */ do_ret(RADDR(inst),6); return 0; } else { } flux_staple(RADDR(inst),6); return inst+6; case INST_GEN_JMPF: /* jmp far, let's check the target */ break; case INST_GEN_INC: case INST_GEN_DEC: case INST_GEN_CALLF: /* this is a register call, we must flag it, but we cannot know what was called right now */ case INST_GEN_PUSH: if (rtype == smod_reg_IR) { if (arg1 == mod_reg_EBP) { /* not really ebp here, but disp32 */ flux_staple(RADDR(inst),6); return inst+6; } if (arg1 == mod_reg_SIB) { MODREGDEC(inst+2,arg1,arg2,rtype); flux_staple(RADDR(inst),7); return inst+7; } flux_staple(RADDR(inst),2); return inst+2; } if (rtype == smod_reg_I8R) { flux_staple(RADDR(inst),3); return inst+3; } if (rtype == smod_reg_RR) { flux_staple(RADDR(inst),2); return inst+2; } flux_staple(RADDR(inst),6); return inst+6; break; } return inst; }
void ex() { struct inst * curr; int i; if( EX == EMPTY ) return; curr = Instructions[EX]; if( EX_stall ) { if( check_stall( (*curr).rs ) || check_stall( (*curr).rt ) ) /* check if stall still present */ { fprintf( fout, "I%d-stall ", EX_count ); return; } else { IF1_stall = IF2_stall = ID_stall = EX_stall = NOSTALL; } } if( (*curr).itype == DADD ) { if( check_stall( (*curr).rs ) || check_stall( (*curr).rt ) ) { IF1_stall = IF2_stall = ID_stall = EX_stall = STALL; fprintf( fout, "I%d-stall ", EX_count ); return; } if( (*curr).rt == NOTUSED ) Registers[ RADDR((*curr).rd) ] = Registers[ RADDR((*curr).rs) ] + (*curr).value; else Registers[ RADDR((*curr).rd) ] = Registers[ RADDR((*curr).rs) ] + Registers[ RADDR((*curr).rt) ]; } else if( (*curr).itype == SUB ) { if( check_stall( (*curr).rs ) || check_stall( (*curr).rt ) ) { IF1_stall = IF2_stall = ID_stall = EX_stall = STALL; fprintf( fout, "I%d-stall ", EX_count ); return; } if( (*curr).rt == NOTUSED ) Registers[ RADDR((*curr).rd) ] = Registers[ RADDR((*curr).rs) ] - (*curr).value; else Registers[ RADDR((*curr).rd) ] = Registers[ RADDR((*curr).rs) ] - Registers[ RADDR((*curr).rt) ]; } else if( (*curr).itype == BNEZ ) { /* check condition */ if( check_stall( (*curr).rs ) ) { IF1_stall = IF2_stall = ID_stall = EX_stall = STALL; fprintf( fout, "I%d-stall ", EX_count ); return; } if( Registers[ RADDR((*curr).rs) ] != 0 ) { for( i = 0; i < instcount; ++i ) { if( strcmp( (*Instructions[i]).label, (*curr).btarget ) == 0 ) break; } if( i >= instcount ) /* unable to find branch target!!! */ return; inst_counter = i; /* flush pipeline */ flush = TRUE; } else EX = EMPTY; } fprintf( fout, "I%d-EX ", EX_count ); }
byte * _f_handler_inst_cdq(byte * inst) { flux_staple(RADDR(inst),1); return inst+1; }
byte * _f_handler_inst_cmp2(byte * inst) { flux_staple(RADDR(inst),3); return inst+3; }
byte * _f_handler_inst_push_imm2(byte * inst) { flux_staple(RADDR(inst),2); return inst+2; }
byte * _f_handler_inst_jo(byte * inst) { char target = *(char*)(inst+1); do_branch(RADDR(inst),(dword)RADDR(inst+2+target),2); return inst+2; }
/* mov AL to 4-byte offset */ byte * _f_handler_inst_mov9(byte * inst) { flux_staple(RADDR(inst),5); return inst+5; }
/* ** then we do the actual copy. */ SCR_COPY (sizeof (struct head)), /* ** continued after the next label ... */ }/*-------------------------< SKIP2 >---------------------*/,{ 0, NADDR (header), /* ** Initialize the status registers */ SCR_COPY (4), NADDR (header.status), RADDR (scr0), /* ** Force host status. */ SCR_FROM_REG (scratcha), 0, SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)), 16, SCR_REG_REG (HS_REG, SCR_OR, HS_SKIPMASK), 0, SCR_JUMPR, 8, SCR_TO_REG (HS_REG), 0, SCR_LOAD_REG (SS_REG, S_GOOD), 0,