//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) process_operand(cmd.Op1, true); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, true); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, true); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, false); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, false); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, false); // // Determine if the next instruction should be executed // if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); // // convert "lda imm, reg" to "lda mem, reg" // if ( cmd.itype == I960_lda && cmd.Op1.type == o_imm && !isDefArg(uFlag, 0) && isEnabled(cmd.Op1.value) ) set_offset(cmd.ea, 0, 0); return 1; }
static void TouchArg( op_t &x, int isload ) { switch( x.type ) { case o_displ: case o_imm: if ( isOff(uFlag, x.n) ) { int outf = x.type != o_imm ? OOF_ADDR : 0; ua_add_off_drefs2(x, dr_O, outf|OOF_SIGNED); } break; case o_mem: case o_ind_mem: { ea_t dea = intmem + x.addr; ua_dodata2(x.offb, dea, x.dtyp); if( !isload ) doVar( dea ); ua_add_dref( x.offb, dea, isload ? dr_R : dr_W ); } break; case o_near: ea_t ea = toEA( cmd.cs, x.addr ); int iscall = InstrIsSet( cmd.itype, CF_CALL ); ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN ); if( flow && iscall ) { if ( !func_does_return(ea) ) flow = false; } } }
int idaapi emu( void ) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if( Feature & CF_USE1 ) TouchArg( cmd.Op1, 1 ); if( Feature & CF_USE2 ) TouchArg( cmd.Op2, 1 ); if( Feature & CF_USE3 ) TouchArg( cmd.Op3, 1 ); if( Feature & CF_JUMP ) QueueMark( Q_jumps, cmd.ea ); if( Feature & CF_CHG1 ) TouchArg( cmd.Op1, 0 ); if( Feature & CF_CHG2 ) TouchArg( cmd.Op2, 0 ); if( Feature & CF_CHG3 ) TouchArg( cmd.Op3, 0 ); switch ( cmd.itype ) { case I196_popa: splitSRarea1(cmd.ea, WSR, BADSEL, SR_auto); splitSRarea1(cmd.ea, WSR1, BADSEL, SR_auto); break; } if( flow ) ua_add_cref( 0, cmd.ea+cmd.size, fl_F ); return 1; }
static void TouchArg( op_t &x, int isload ) { switch( x.type ) { case o_imm: case o_displ: if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O); break; case o_mem: case o_ind_mem: { ulong dea = intmem + x.addr; ua_dodata( dea, x.dtyp ); if( !isload ) doVar( dea ); ua_add_dref( x.offb, dea, isload ? dr_R : dr_W ); } break; case o_near: ulong ea = toEA( cmd.cs, x.addr ); int iscall = InstrIsSet( cmd.itype, CF_CALL ); ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN ); if( flow && iscall ) { if ( !func_does_return(ea) ) flow = false; } } }
//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) TouchArg(cmd.Op1,1); if ( Feature & CF_USE2 ) TouchArg(cmd.Op2,1); if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) TouchArg(cmd.Op1,0); if ( Feature & CF_CHG2 ) TouchArg(cmd.Op2,0); if ( flow && canFlow() ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); switch ( cmd.itype ) { case TMS_ldp: // change DP register case TMS2_ldp: // change DP register case TMS2_ldpk: // change DP register { uint v = (cmd.Op1.type == o_imm) ? uint(cmd.Op1.value) : -1u; splitSRarea1(get_item_end(cmd.ea),rDP,v,SR_auto); } break; } return 1; }
//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) TouchArg(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) TouchArg(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) TouchArg(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) TouchArg(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) TouchArg(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) TouchArg(cmd.Op3, flag3, 0); // // Determine if the next instruction should be executed // if ( !flow ) flow = may_be_skipped(); if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
//---------------------------------------------------------------------- // емулятер int idaapi C39_emu(void) { #if IDP_INTERFACE_VERSION > 37 uint32 Feature = cmd.get_canon_feature(); #else uint32 Feature = Instructions[cmd.itype].feature; uFlag = getFlags(cmd.ea); #endif // получим типы операндов int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); flow = ((Feature & CF_STOP) == 0); // пометим ссылки двух операндов if(Feature & CF_USE1) TouchArg(cmd.Op1, flag1, 1); if(Feature & CF_USE2) TouchArg(cmd.Op2, flag2, 1); if(Feature & CF_USE3) TouchArg(cmd.Op3, flag3, 1); // поставим переход в очередь if(Feature & CF_JUMP) QueueMark(Q_jumps,cmd.ea); // поставим изменения if(Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0); if(Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0); if(Feature & CF_CHG3) TouchArg(cmd.Op3, flag3, 0); // если не стоп - продолжим на след. инструкции if(flow) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return(1); }
// emulate an instruction int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if (cmd.Op1.type != o_void) handle_operand(cmd.Op1); if (cmd.Op2.type != o_void) handle_operand(cmd.Op2); if (cmd.Op3.type != o_void) handle_operand(cmd.Op3); /* we can't use this code if (feature & CF_USE1) handle_operand(cmd.Op1, 1); if (feature & CF_USE2) handle_operand(cmd.Op2, 1); if (feature & CF_USE3) handle_operand(cmd.Op3, 1); */ // we don't use CF_JUMP //if (feature & CF_JUMP) switch (cmd.itype) { case m740_jmp: case m740_jsr: if (cmd.Op1.type != o_void && is_addr_ind(cmd.Op1)) QueueMark(Q_jumps, cmd.ea); break; } /* if (feature & CF_CHG1) handle_operand(cmd.Op1, 0); if (feature & CF_CHG2) handle_operand(cmd.Op2, 0); if (feature & CF_CHG3) handle_operand(cmd.Op3, 0); */ if (flow) { // skip the next byte if the current insn is brk if (cmd.itype == m740_brk) { ua_add_cref(0, cmd.ea + cmd.size + 1, fl_JN); doByte(cmd.ea + cmd.size, 1); } else { ua_add_cref(0, cmd.ea + cmd.size, fl_F); } } return 1; }
//---------------------------------------------------------------------- static void process_operand(op_t &x, bool isload) { ea_t ea; dref_t dref; if ( is_forced_operand(cmd.ea, x.n) ) return; switch ( x.type ) { case o_reg: case o_phrase: break; case o_imm: if ( !isload ) interr("emu1"); process_immediate_number(x.n); if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN|OOFW_IMM); break; case o_mem: ea = calc_mem(x.addr); ua_dodata2(x.offb, ea, x.dtyp); dref = cmd.itype == I960_lda ? dr_O : isload ? dr_R : dr_W; ua_add_dref(x.offb, ea, dref); break; case o_near: { cref_t ftype = fl_JN; ea = calc_mem(x.addr); if ( InstrIsSet(cmd.itype, CF_CALL) ) { flow = func_does_return(ea); ftype = fl_CN; } ua_add_cref(x.offb, ea, ftype); } break; case o_displ: dref = cmd.itype == I960_lda ? dr_O : isload ? dr_R : dr_W; process_immediate_number(x.n); if ( x.reg == IP ) { ea_t ea = cmd.ea + 8 + x.addr; ua_add_dref(x.offb, ea, dref); } else { if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dref, OOFS_IFSIGN|OOF_SIGNED|OOF_ADDR|OOFW_32); } break; default: interr("emu"); } }
static void handle_operand(op_t &op) { switch (op.type) { // code address case o_near: { ea_t ea = toEA(cmd.cs, op.addr); cref_t mode = fl_JN; if (cmd.itype == m740_jsr) { if ( !func_does_return(ea) ) flow = false; mode = fl_CN; } ua_add_cref(op.offb, ea, mode); } break; // data address case o_mem: { enum dref_t mode = dr_U; if (is_addr_ind(op)) mode = dr_R; /* NOT dr_O */ else if (is_addr_read(op)) mode = dr_R; else if (is_addr_write(op)) mode = dr_W; ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // immediate case o_imm: handle_imm(op); // if the value was converted to an offset, then create a data xref: if (isOff(uFlag, op.n)) ua_add_off_drefs2(op, dr_O, 0); break; // displ case o_displ: if (isOff(uFlag, op.n)) { ua_add_off_drefs2(op, dr_O, OOF_ADDR); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // reg - do nothing case o_reg: case o_void: break; default: IDA_ERROR("Invalid op.type in handle_operand()"); } }
//---------------------------------------------------------------------- int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = (feature & CF_STOP) == 0; if ((cmd.auxpref & DBrFlag) == 0) // У отложенных переходов не надо обрабатывать операнды, т.к. // регистры и так не обрабатываются, а адр. перехода будет обработан через 3 команды { if ( feature & CF_USE1 ) process_operand(cmd.Op1, 1); if ( feature & CF_USE2 ) process_operand(cmd.Op2, 1); if ( feature & CF_USE3 ) process_operand(cmd.Op3, 1); if ( feature & CF_CHG1 ) process_operand(cmd.Op1, 0); if ( feature & CF_CHG2 ) process_operand(cmd.Op2, 0); if ( feature & CF_CHG3 ) process_operand(cmd.Op3, 0); } if (GetDelayedBranchAdr() != BADADDR) // добавить ссылку по отложенному переходу ua_add_cref(0, toEA(cmd.cs, GetDelayedBranchAdr()), fl_JN); if (cmd.itype == TMS320C3X_RETScond) // добавить ссылку по условному выходу ua_add_cref(0, cmd.ea, fl_JN); // check for DP changes if ( ((cmd.itype == TMS320C3X_LDIcond) || (cmd.itype == TMS320C3X_LDI)) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == dp)) splitSRarea1(get_item_end(cmd.ea), dp, cmd.Op1.value & 0xFF, SR_auto); // determine if the next instruction should be executed if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow && delayed_stop() ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); // you may emulate selected instructions with a greater care: switch ( cmd.itype ) { case I51_mov: if ( cmd.Op1.type == o_mem && cmd.Op1.addr == 0x81 ) // mov SP, #num { if ( cmd.Op2.type == o_imm && !isDefArg(uFlag,1) ) set_offset(cmd.ea,1,intmem); // convert it to an offset } break; case I51_trap: ua_add_cref(0, 0x7B, fl_CN); break; case I51_pop: add_stkpnt(1); break; case I51_push: add_stkpnt(-1); break; } if ( Feature & CF_USE1 ) handle_operand(cmd.Op1, 1); if ( Feature & CF_USE2 ) handle_operand(cmd.Op2, 1); if ( Feature & CF_USE3 ) handle_operand(cmd.Op3, 1); if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) handle_operand(cmd.Op1, 0); if ( Feature & CF_CHG2 ) handle_operand(cmd.Op2, 0); if ( Feature & CF_CHG3 ) handle_operand(cmd.Op3, 0); // if the execution flow is not stopped here, then create // a xref to the next instruction. // Thus we plan to analyze the next instruction. if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; // actually the return value is unimportant, but let's it be so }
//---------------------------------------------------------------------- static void add_code_xref(op_t &x, ea_t ea) { cref_t ftype = fl_JN; if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = fl_CN; } ua_add_cref(x.offb, ea, ftype); }
//---------------------------------------------------------------------- static void TouchArg( op_t &x, int isload ) { switch( x.type ) { case o_imm: doImmd(cmd.ea); if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOF_SIGNED); break; case o_indexed: // addr[value] doImmd(cmd.ea); if ( x.value == 0 && !isDefArg(uFlag, x.n) ) set_offset(cmd.ea, x.n, toEA(cmd.cs, 0)); if ( isOff(uFlag, x.n) ) // xref to addr { uval_t saved = x.value; x.value = x.addr; ua_add_off_drefs2(x, saved ? dr_O : isload ? dr_R : dr_W, OOF_SIGNED|OOF_ADDR); x.value = saved; } if ( x.value != 0 ) // xref to value { // no references to ZERO_REG ea_t ea = toEA(cmd.cs, x.value); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W ); ua_dodata2(x.offb, ea, x.dtyp); } break; case o_indirect: case o_indirect_inc: case o_mem: { ea_t dea = toEA( cmd.cs, x.addr ); ua_dodata2(x.offb, dea, x.dtyp); if( !isload ) doVar(dea); ua_add_dref( x.offb, dea, isload ? dr_R : dr_W ); if ( !isload && (x.addr == 0x14 || x.addr == 0x15) ) { sel_t wsrval = BADSEL; if ( cmd.Op2.type == o_imm ) wsrval = sel_t(cmd.Op2.value); splitSRarea1(cmd.ea, x.addr == 0x14 ? WSR : WSR1, wsrval, SR_auto); } } break; case o_near: ea_t ea = toEA( cmd.cs, x.addr ); int iscall = InstrIsSet( cmd.itype, CF_CALL ); ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN ); if ( flow && iscall ) flow = func_does_return(ea); } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: case o_phrase: case o_port: break; case o_imm: if ( !isload ) goto badTouch; doImmdValue(x.n); if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOF_SIGNED); break; case o_displ: doImmdValue(x.n); if ( isAlt ) break; if ( isOff(uFlag, x.n) ) { ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR); ea_t ea = calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } break; case o_near: { cref_t ftype = fl_JN; ea_t ea = toEA(cmd.cs, x.addr); if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = fl_CN; } ua_add_cref(x.offb, ea, ftype); } break; case o_mem: { ea_t ea = toEA(dataSeg(), x.addr); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); } break; default: badTouch: if ( cmd.itype != AVR_lpm && cmd.itype != AVR_elpm ) warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }
// check and create a flat 32 bit jump table -- the most common case static void check_and_create_flat32( jump_table_type_t /*jtt*/, switch_info_ex_t &si) { // check the table contents ea_t table = si.jumps; segment_t *s = getseg(table); if ( s == NULL ) return; size_t maxsize = size_t(s->endEA - table); int size = si.ncases; if ( size > maxsize ) size = (int)maxsize; int i; insn_t saved = cmd; for ( i=0; i < size; i++ ) { ea_t ea = table + 4*i; flags_t F = getFlags(ea); if ( !hasValue(F) ) break; if ( i && (has_any_name(F) || hasRef(F)) ) break; ea_t target = segm_adjust_ea(getseg(table), si.elbase + get_long(ea)); if ( !isLoaded(target) ) break; flags_t F2 = get_flags_novalue(target); if ( isTail(F2) || isData(F2) ) break; if ( !isCode(F2) && !decode_insn(target) ) break; } cmd = saved; size = i; // create the table for ( i=0; i < size; i++ ) { ea_t ea = table + 4*i; doDwrd(ea, 4); op_offset(ea, 0, REF_OFF32, BADADDR, si.elbase); ea_t target = si.elbase + segm_adjust_diff(getseg(table), get_long(ea)); ua_add_cref(0, target, fl_JN); } si.flags |= SWI_J32; if ( si.defjump != BADADDR ) si.flags |= SWI_DEFAULT; si.ncases = (uint16)size; si.startea = cmd.ea; set_switch_info_ex(cmd.ea, &si); }
//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); // // Check for table and generic indirect jumps // if ( cmd.itype == H8_jmp && cmd.Op1.type == o_phrase ) { if ( !check_for_table_jump() ) check_for_generic_indirect_jump(); } if ( cmd.itype == H8_jsr && cmd.Op1.type == o_phrase ) { check_for_generic_indirect_call(); } // // Determine if the next instruction should be executed // if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); // // Handle SP modifications // if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
int idaapi emu(void) { int features; // // Determine the current instruction's features. // features = cmd.get_canon_feature(); bool flow = (features & CF_STOP) == 0; // // Examine each operand and determine what effect, if any, // it makes on the environment. // // Operands that are read if ( features & CF_USE1 ) flow &= handle_operand(cmd.Op1, hop_READ); if ( features & CF_USE2 ) flow &= handle_operand(cmd.Op2, hop_READ); if ( features & CF_USE3 ) flow &= handle_operand(cmd.Op3, hop_READ); // Operands that are written if ( features & CF_CHG1 ) flow &= handle_operand(cmd.Op1, hop_WRITE); if ( features & CF_CHG2 ) flow &= handle_operand(cmd.Op2, hop_WRITE); if ( features & CF_CHG3 ) flow &= handle_operand(cmd.Op3, hop_WRITE); // // Determine whether the instruction stops the execution flow. // if ( flow ) { // // This instruction doesn't stop execution flow. // Add a cross reference to the next instrction. // ua_add_cref(0,cmd.ea+cmd.size,fl_F); } // // If the instruction makes a branch, let the IDA kernel // know. // if ( features & CF_JUMP ) QueueSet(Q_jumps, cmd.ea); return 1; }
int emu( void ) { ulong Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if( Feature & CF_USE1 ) TouchArg( cmd.Op1, 1 ); if( Feature & CF_USE2 ) TouchArg( cmd.Op2, 1 ); if( Feature & CF_JUMP ) QueueMark( Q_jumps, cmd.ea ); if( Feature & CF_CHG1 ) TouchArg( cmd.Op1, 0 ); if( Feature & CF_CHG2 ) TouchArg( cmd.Op2, 0 ); if( flow ) ua_add_cref( 0, cmd.ea+cmd.size, fl_F ); return 1; }
//---------------------------------------------------------------------- int i860_emu(void) { bool funcret = true; uint32 Feature = cmd.get_canon_feature(); if ( Feature & CF_USE1 ) if ( !TouchArg(cmd.Op1,1) ) funcret = false; if ( Feature & CF_USE2 ) if ( !TouchArg(cmd.Op2,1) ) funcret = false; if ( Feature & CF_USE3 ) if ( !TouchArg(cmd.Op3,1) ) funcret = false; if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) if ( !TouchArg(cmd.Op1,0) ) funcret = false; if ( Feature & CF_CHG2 ) if ( !TouchArg(cmd.Op2,0) ) funcret = false; if ( Feature & CF_CHG3 ) if ( !TouchArg(cmd.Op3,0) ) funcret = false; if ( funcret && canFlow() ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
// emulate an instruction int idaapi emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if ( feature & CF_USE1) handle_operand(cmd.Op1, 1 ); if ( feature & CF_USE2) handle_operand(cmd.Op2, 1 ); if ( feature & CF_USE3) handle_operand(cmd.Op3, 1 ); if ( feature & CF_JUMP) QueueMark(Q_jumps, cmd.ea ); if ( feature & CF_CHG1) handle_operand(cmd.Op1, 0 ); if ( feature & CF_CHG2) handle_operand(cmd.Op2, 0 ); if ( feature & CF_CHG3) handle_operand(cmd.Op3, 0 ); if ( flow) ua_add_cref(0, cmd.ea + cmd.size, fl_F ); return 1; }
//---------------------------------------------------------------------- static bool TouchArg(op_t &x,int isload) { dref_t xreftype; uchar outf; switch ( x.type ) { case o_phrase: // 2 registers case o_reg: break; case o_imm: if ( !isload ) goto badTouch; xreftype = dr_O; outf = OOF_SIGNED; goto makeImm; case o_displ: xreftype = isload ? dr_R : dr_W; outf = OOF_SIGNED|OOF_ADDR; makeImm: doImmdValue(); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, xreftype, outf); break; case o_mem: ua_dodata2(x.offb, x.addr, x.dtyp); if ( !isload ) doVar(x.addr); ua_add_dref(x.offb,x.addr,isload ? dr_R : dr_W); break; case o_near: { int iscall = InstrIsSet(cmd.itype,CF_CALL); ua_add_cref(x.offb,x.addr,iscall ? fl_CN : fl_JN); if ( iscall && !func_does_return(x.addr) ) return false; } break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } return true; }
// Emulate an instruction. int idaapi emu(void) { bool flow = !is_stop() || (cmd.auxpref & INSN_DELAY_SHOT); if ( flow ) { insn_t cmd_backup = cmd; if ( decode_prev_insn(cmd.ea) != BADADDR ) { flow = !(is_stop() && (cmd.auxpref & INSN_DELAY_SHOT)); } cmd = cmd_backup; } if ( cmd.Op1.type != o_void) handle_operand(cmd.Op1 ); if ( cmd.Op2.type != o_void) handle_operand(cmd.Op2 ); if ( cmd.Op3.type != o_void) handle_operand(cmd.Op3 ); if ( cmd.Op4.type != o_void) handle_operand(cmd.Op4 ); if ( flow ) ua_add_cref(0, cmd.ea + cmd.size, fl_F); return 1; }
//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = (Feature & CF_STOP) == 0; int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); if(Feature & CF_USE1) TouchArg(cmd.Op1, flag1, 1); if(Feature & CF_USE2) TouchArg(cmd.Op2, flag2, 1); if(Feature & CF_USE3) TouchArg(cmd.Op3, flag3, 1); if(Feature & CF_JUMP) QueueMark(Q_jumps, cmd.ea); if(Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0); if(Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0); if(Feature & CF_CHG3) TouchArg(cmd.Op3, flag3, 0); if(flow) ua_add_cref(0, cmd.ea + cmd.size, fl_F); return(1); }
//---------------------------------------------------------------------- int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = (feature & CF_STOP) == 0; if ( feature & CF_USE1 ) process_operand(cmd.Op1, 1); if ( feature & CF_USE2 ) process_operand(cmd.Op2, 1); if ( feature & CF_USE3 ) process_operand(cmd.Op3, 1); if ( feature & CF_CHG1 ) process_operand(cmd.Op1, 0); if ( feature & CF_CHG2 ) process_operand(cmd.Op2, 0); if ( feature & CF_CHG3 ) process_operand(cmd.Op3, 0); // check for CPL changes if ((cmd.itype == TMS320C54_rsbx1 || cmd.itype == TMS320C54_ssbx1) && cmd.Op1.type == o_reg && cmd.Op1.reg == CPL) splitSRarea1(get_item_end(cmd.ea), CPL, cmd.itype == TMS320C54_rsbx1 ? 0 : 1, SR_auto); // check for DP changes if (cmd.itype == TMS320C54_ld2 && cmd.Op1.type == o_imm && cmd.Op1.dtyp == dt_byte && cmd.Op2.type == o_reg && cmd.Op2.reg == DP) splitSRarea1(get_item_end(cmd.ea), DP, cmd.Op1.value & 0x1FF, SR_auto); // determine if the next instruction should be executed if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow && delayed_stop() ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
//---------------------------------------------------------------------- int idaapi emu(void) { if ( segtype(cmd.ea) == SEG_XTRN ) return 1; uint32 Feature = cmd.get_canon_feature(); int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); fill_additional_args(); for ( int i=0; i < aa.nargs; i++ ) { op_t *x = aa.args[i]; for ( int j=0; j < 2; j++,x++ ) { if ( x->type == o_void ) break; process_operand(*x, 0, j==0); } } // // Determine if the next instruction should be executed // if ( Feature & CF_STOP ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
//---------------------------------------------------------------------- // change value of virtual register "BANK" and switch to another bank static void split(int reg, sel_t v) { if ( reg == -1 ) { flow = 0; if ( v != BADSEL ) { sel_t pclath = getSR(cmd.ea, PCLATH) & 0x1F; ea_t ea = calc_code_mem(uchar(v) | (pclath<<8)); ua_add_cref(0, ea, fl_JN); } } else { if ( v == BADSEL ) v = 0; // assume bank0 if bank is unknown if ( reg == BANK ) { if ( ptype != PIC16 ) v &= 3; else v &= 0xF; } splitSRarea1(get_item_end(cmd.ea), reg, v, SR_auto); } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isload) { switch ( x.type ) { case o_regpair: case o_reg: case o_phrase: case o_spmask: case o_stgcyc: break; case o_imm: if ( !isload ) goto badTouch; /* no break */ case o_displ: doImmdValue(x.n); if ( op_adds_xrefs(uFlag, x.n) ) { int outf = x.type != o_imm ? OOF_ADDR : 0; if ( x.dtyp == dt_word ) outf |= OOF_SIGNED; ua_add_off_drefs2(x, dr_O, outf); } break; case o_near: { ea_t ea = toEA(cmd.cs,x.addr); ea_t ref = find_first_insn_in_packet(ea); ua_add_cref(x.offb, ref, fl_JN); } break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }
//---------------------------------------------------------------------- static void TouchArg(op_t &x,int isload) { switch ( x.type ) { case o_regpair: case o_reg: case o_phrase: break; case o_imm: if ( !isload ) goto badTouch; /* no break */ case o_displ: doImmdValue(x.n); if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O); break; case o_near: ua_add_cref(x.offb,toEA(cmd.cs,x.addr),fl_JN); break; default: badTouch: warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type); break; } }
//---------------------------------------------------------------------- // поставим использование/изменение операндов static void near TouchArg(op_t &x,int isAlt,int isload) { ea_t ea = toEA(codeSeg(x.addr,x.n), x.addr); switch ( x.type ) { // эта часть не используется ! case o_void: break; // тут тоже нечего делать case o_reg: break; // непосредственный операнд case o_imm: // непосредственный не может меняться if ( ! isload ) goto badTouch; // поставим флажок непосредственного операнда doImmd(cmd.ea); // если не форсирован и помечен смещением if ( !isAlt && isOff(uFlag,x.n) ) // это смещение ! ua_add_dref(x.offb,ea,dr_O); break; // переход или вызов case o_near: // это вызов ? (или переход) if(InstrIsSet(cmd.itype,CF_CALL)){ // поставим ссылку на код ua_add_cref(x.offb,ea,fl_CN); // это функция без возврата ? #if IDP_INTERFACE_VERSION > 37 flow = func_does_return(ea); #else // получим описатель функции func_t *pfn = get_func(ea); // если функция описана и не имеет возврата - остановим if(pfn != NULL && (pfn->flags & FUNC_NORET) ) flow = false; #endif } else ua_add_cref(x.offb,ea,fl_JN); break; // ссылка на ячейку памяти case o_mem: // сделаем данные по указанному адресу ua_dodata2(x.offb, ea, x.dtyp); // если изменяется - поставим переменную if ( ! isload ) doVar(ea); // добавим ссылку на память ua_add_dref(x.offb,ea,isload ? dr_R : dr_W); break; // прочее - сообщим ошибку default: badTouch: #if IDP_INTERFACE_VERSION > 37 warning("%a %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), #else warning("%08lX %s,%d: bad optype (%x)", cmd.ea,(char far *)Instructions[cmd.itype].name, #endif x.n, x.type); break; } }