//---------------------------------------------------------------------- // емулятер int idaapi T900_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); 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_JUMP) QueueSet(Q_jumps,cmd.ea ); // поставим изменения if ( Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0 ); if ( Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0 ); // если не стоп - продолжим на след. инструкции if ( flow) ua_add_cref(0,cmd.ea+cmd.size,fl_F ); return(1); }
//---------------------------------------------------------------------- static void outmem(op_t &x, ea_t ea) { char buf[MAXSTR]; if ( get_name_expr(cmd.ea+x.offb, x.n, ea, BADADDR, buf, sizeof(buf)) <= 0 ) { const ioport_t *p = find_sym(x.addr); if ( p == NULL ) { out_tagon(COLOR_ERROR); OutLong(x.addr, 16); out_tagoff(COLOR_ERROR); QueueSet(Q_noName,cmd.ea); } else { out_line(p->name, COLOR_IMPNAME); } } else { bool complex = strchr(buf, '+') || strchr(buf, '-'); if ( complex ) out_symbol(ash.lbrace); OutLine(buf); if ( complex ) out_symbol(ash.rbrace); } }
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 ) QueueSet( 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: split_srarea(cmd.ea, WSR, BADSEL, SR_auto); split_srarea(cmd.ea, WSR1, BADSEL, SR_auto); break; } if( flow ) ua_add_cref( 0, cmd.ea+cmd.size, fl_F ); return 1; }
void out_print_address(op_t &x, ea_t /*pc*/) { if (!out_name_expr(x, x.addr)) { OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN); QueueSet(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { if ( !out_port_address(addr) ) { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueSet(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x) { segment_t *s = getseg(ea); ea_t value = s != NULL ? ea - get_segm_base(s) : ea; if ( !out_name_expr(x, ea, value) ) { out_tagon(COLOR_ERROR); out_snprintf("%a", ea); out_tagoff(COLOR_ERROR); QueueSet(Q_noName, cmd.ea); } }
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; }
//---------------------------------------------------------------------- void OutAddr(op_t& x, ea_t ea, ea_t off, bool isSigned = false) { // try and find the real name expression if ( !out_name_expr(x, ea, off) ) { // work out flags correctly uint32 flags = OOF_ADDR | OOFW_16; if ( isSigned ) flags |= OOF_SIGNED; else flags |= OOFS_NOSIGN; // if name wasn't found, just output the value & add to noname queue OutValue(x, flags); QueueSet(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- char outName(ea_t from, int n, ea_t ea, uval_t off, uchar *rbad) { char buf[MAXSTR]; if ( get_name_expr(from, n, ea + off, off, buf, sizeof(buf)) <= 0 ) { if ( loadpass >= 0 ) QueueSet(Q_noName, cmd.ea); return 0; } if ( chkOutLine(buf, tag_strlen(buf)) ) { *rbad = 1; return 0; } return 1; }
//---------------------------------------------------------------------- bool idaapi outop(op_t &x) { uval_t v; switch ( x.type ) { case o_imm: out_symbol('#'); OutValue(x, OOFW_IMM); break; case o_ind_reg: out_symbol('@'); case o_reg: OutReg(x.reg); break; case o_phrase: //ig: лучше out_keyword, чем простой OutLine() // так цвет будет правильный out_keyword(phrases[x.phrase]); break; case o_displ: OutValue(x, OOF_ADDR | OOFW_IMM); // x.addr out_symbol('('); OutReg(x.reg); out_symbol(')'); break; case o_ind_mem: out_symbol('@'); case o_mem: case o_near: v = map_addr(x.addr, x.n, x.type != o_near); if ( !out_name_expr(x, v, x.addr) ) { const char *name = z8_find_ioport(v); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16); QueueSet(Q_noName, cmd.ea); } } break; case o_void: return 0; default: warning("out: %a: bad optype %d", cmd.ea, x.type); } return 1; }
//---------------------------------------------------------------------- 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_CHG1 ) handle_operand(cmd.Op1, 0); if ( Feature & CF_CHG2 ) handle_operand(cmd.Op2, 0); if ( Feature & CF_JUMP ) QueueSet(Q_jumps, cmd.ea); if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); uint8 code = get_byte(cmd.ea); const struct opcode_info_t &opinfo = get_opcode_info(code); if ( opinfo.itype == M65816_jmp || opinfo.itype == M65816_jsr ) { if ( opinfo.addr == ABS_INDIR || opinfo.addr == ABS_INDIR_LONG || opinfo.addr == ABS_IX_INDIR ) { QueueSet(Q_jumps,cmd.ea); } } #if 0 switch ( opinfo.addr ) { case ABS_LONG_IX: { ea_t orig_ea = cmd.Op1.addr; ea_t ea = xlat(orig_ea); bool read_access; if ( cmd.itype == M65816_sta ) read_access = false; else read_access = true; if ( !read_access ) doVar(ea); ua_add_dref(cmd.Op1.offb, ea, read_access ? dr_R : dr_W); break; } case DP: { bool read_access; if ( cmd.itype == M65816_tsb || cmd.itype == M65816_asl || cmd.itype == M65816_trb || cmd.itype == M65816_rol || cmd.itype == M65816_lsr || cmd.itype == M65816_ror || cmd.itype == M65816_dec || cmd.itype == M65816_inc ) read_access = false; else read_access = true; int32 val = backtrack_value(cmd.ea, 2, BT_DP); if ( val != -1 ) { ea_t orig_ea = val + cmd.Op1.addr; ea_t ea = xlat(orig_ea); ua_dodata2(cmd.Op1.offb, ea, cmd.Op1.dtyp); if ( !read_access ) doVar(ea); ua_add_dref(cmd.Op1.offb, ea, read_access ? dr_R : dr_W); } } break; } #endif switch ( cmd.itype ) { case M65816_sep: case M65816_rep: { // Switching 8 -> 16 bits modes. uint8 flag_data = get_byte(cmd.ea + 1); uint8 m_flag = flag_data & 0x20; uint8 x_flag = flag_data & 0x10; uint8 val = (cmd.itype == M65816_rep) ? 0 : 1; if ( m_flag ) split_srarea(cmd.ea + 2, rFm, val, SR_auto); if ( x_flag ) split_srarea(cmd.ea + 2, rFx, val, SR_auto); } break; case M65816_xce: { // Switching to native mode? uint8 prev = get_byte(cmd.ea - 1); const struct opcode_info_t &opinf = get_opcode_info(prev); if ( opinf.itype == M65816_clc ) split_srarea(cmd.ea + 1, rFe, 0, SR_auto); else if ( opinf.itype == M65816_sec ) split_srarea(cmd.ea + 1, rFe, 1, SR_auto); } break; case M65816_jmp: case M65816_jml: case M65816_jsl: case M65816_jsr: { if ( cmd.Op1.full_target_ea ) { ea_t ftea = cmd.Op1.full_target_ea; if ( cmd.itype != M65816_jsl && cmd.itype != M65816_jml ) ftea = toEA(codeSeg(ftea, 0), ftea); else ftea = xlat(ftea); split_srarea(ftea, rFm, get_segreg(cmd.ea, rFm), SR_auto); split_srarea(ftea, rFx, get_segreg(cmd.ea, rFx), SR_auto); split_srarea(ftea, rFe, get_segreg(cmd.ea, rFe), SR_auto); split_srarea(ftea, rPB, ftea >> 16, SR_auto); split_srarea(ftea, rB, get_segreg(cmd.ea, rB), SR_auto); split_srarea(ftea, rDs, get_segreg(cmd.ea, rDs), SR_auto); split_srarea(ftea, rD, get_segreg(cmd.ea, rD), SR_auto); } } break; case M65816_plb: { int32 val = backtrack_value(cmd.ea, 1, BT_STACK); if ( val != -1 ) { split_srarea(cmd.ea + cmd.size, rB, val, SR_auto); split_srarea(cmd.ea + cmd.size, rDs, val << 12, SR_auto); } } break; case M65816_pld: { int32 val = backtrack_value(cmd.ea, 2, BT_STACK); if ( val != -1 ) split_srarea(cmd.ea + cmd.size, rD, val, SR_auto); } break; case M65816_plp: { // Ideally, should pass another parameter, specifying when to stop // backtracking. // For example, in order to avoid this: // PHP // PLP <-- this one is causing interference // (dunno if that even happens, though) // PLP ea_t ea = backtrack_prev_ins(cmd.ea, M65816_php); if ( ea != BADADDR ) { uint16 p = get_cpu_status(ea); split_srarea(cmd.ea + cmd.size, rFm, (p >> 5) & 0x1, SR_auto); split_srarea(cmd.ea + cmd.size, rFx, (p >> 4) & 0x1, SR_auto); } }