DWORD get_id() const { DWORD id; if ( get_dword(t_symIndexId, &id) != S_OK ) INTERR(30211); return id; }
// output an operand bool idaapi outop(op_t &op) { switch ( op.type ) { // register case o_reg: outreg(op.reg); break; // immediate case o_imm: if ( (op.specflag1 & OP_IMM_BIT) == 0 ) out_symbol('#'); OutValue(op, OOFW_IMM); break; // data / code memory address case o_near: case o_mem: outaddr(op); break; // displ case o_displ: outdispl(); break; // ignore void operands case o_void: break; default: INTERR(10024); } return 1; }
static void out_reglist(op_t &op) { static const uint16 regs_ldm0[] = { rR7, rR6, rR5, rR4, rR3, rR2, rR1, rR0 }; static const uint16 regs_stm0[] = { rR0, rR1, rR2, rR3, rR4, rR5, rR6, rR7 }; static const uint16 regs_ldm1[] = { rR15, rR14, rR13, rR12, rR11, rR10, rR9, rR8 }; static const uint16 regs_stm1[] = { rR8, rR9, rR10, rR11, rR12, rR13, rR14, rR15 }; const uint16 *regs; bool left; switch ( cmd.itype ) { case fr_ldm0: regs = regs_ldm0; left = false; break; case fr_stm0: regs = regs_stm0; left = true; break; case fr_ldm1: regs = regs_ldm1; left = false; break; case fr_stm1: regs = regs_stm1; left = true; break; default: INTERR(10018); } print_comma = false; out_symbol('('); if ( left ) { for (int i = 0, bit = 128; bit != 0; bit >>= 1, i++) out_reg_if_bit(regs[i], op.value, bit); } else { for (int i = 7, bit = 1; bit <= 128; bit <<= 1, i--)
// output a displacement static void outdispl(void) { if ( is_displ_indx() ) { out_symbol('('); outaddr(cmd.Op1, false); out_symbol(','); if ( !(ash.uflag & UAS_INDX_NOSPACE)) OutChar(' ' ); outreg(cmd.Op1.reg); out_symbol(')'); return; } if ( is_displ_indy() ) { out_symbol('('); outaddr(cmd.Op1, false); out_symbol(')'); out_symbol(','); OutChar(' '); outreg(cmd.Op1.reg); return; } if ( is_displ_zpx() || is_displ_zpy() || is_displ_absx() || is_displ_absy() ) { outaddr(cmd.Op1, false); out_symbol(','); OutChar(' '); outreg(cmd.Op1.reg); return; } INTERR(10023); }
static int idaapi options_cb(int fid, form_actions_t &fa) { if ( fid == 2 || fid == -1 ) { ushort opt; if ( !fa.get_field_value(3, &opt) ) INTERR(30001); // hide recursion level textbox fa.show_field(4, (opt & FWO_RECURSE_UNLIM) == 0); } return 1; }
//-------------------------------------------------------------------------- static int idaapi modcb(int fid, form_actions_t &fa) { switch ( fid ) { case -1: msg("initializing\n"); break; case -2: msg("terminating\n"); break; case 5: // operand msg("changed operand\n"); break; case 6: // check msg("changed check\n"); break; case 7: // button msg("changed button\n"); break; case 8: // color button msg("changed color button\n"); break; default: msg("unknown id %d\n", fid); break; } bool is_gui = callui(ui_get_hwnd).vptr != NULL; char buf0[MAXSTR]; if ( !fa.get_field_value(5, buf0) ) INTERR(); if ( strcmp(buf0, "on") == 0 ) fa.enable_field(12, true); if ( strcmp(buf0, "off") == 0 ) fa.enable_field(12, false); ushort buf1; if ( !fa.get_field_value(12, &buf1) ) INTERR(); fa.show_field(7, (buf1 & 1) != 0); fa.enable_field(8, (buf1 & 2) != 0); ushort c13; if ( !fa.get_field_value(13, &c13) ) INTERR(); fa.enable_field(10, c13); ushort c14; if ( !fa.get_field_value(14, &c14) ) INTERR(); fa.enable_field(5, c14); ushort c15; if ( !fa.get_field_value(15, &c15) ) INTERR(); if ( (buf1 & 8) != 0 ) { uval_t x, y, w, h; fa.get_field_value(4, &x); fa.get_field_value(3, &y); fa.get_field_value(2, &w); fa.get_field_value(1, &h); fa.move_field(5, x, y, w, h); if ( x != -1 && c15 ) fa.move_field(-5, x-7, y, w, h); } if ( fa.get_field_value(7, NULL) ) INTERR(); bgcolor_t bgc = -1; if ( is_gui && !fa.get_field_value(8, &bgc) ) INTERR(); msg(" op=%s change=%x color=%x\n", buf0, buf1, bgc); fa.set_field_value(9, buf0); return 1; }
//---------------------------------------------------------------------- static void process_operand(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: case o_reglist: return; case o_imm: QASSERT(10090, isload); process_immediate_number(x.n); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, calc_opimm_flags()); break; case o_phrase: case o_displ: process_immediate_number(x.n); if ( isAlt ) break; if ( op_adds_xrefs(uFlag, x.n) ) { ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, calc_opdispl_flags()); if ( ea != BADADDR ) { ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } } // create stack variables if required if ( x.type == o_displ && may_create_stkvars() && !isDefArg(uFlag, x.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && (issp(x.phrase) || isbp(x.phrase) && (pfn->flags & FUNC_FRAME) != 0) ) { if ( ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) ) op_stkvar(cmd.ea, x.n); } } break; case o_near: case o_far: { cref_t ftype = x.type == o_near ? fl_JN : fl_JF; ea_t ea = calc_mem(x); if ( InstrIsSet(cmd.itype, CF_CALL) ) { if ( !func_does_return(ea) ) flow = false; ftype = x.type == o_near ? fl_CN : fl_CF; } ua_add_cref(x.offb, ea, ftype); } break; case o_mem: { ea_t ea = calc_mem(x); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } break; default: INTERR(10091); } }
void assert_token(sym_token_t token) const { if ( !token_present(token) ) INTERR(30210); }
//---------------------------------------------------------------------- static void process_operand(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: case o_phrase: case o_reglist: return; case o_imm: QASSERT(10094, isload); process_immediate_number(x.n); if ( op_adds_xrefs(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN|OOFW_IMM); break; case o_displ: process_immediate_number(x.n); if ( isAlt ) break; if ( op_adds_xrefs(uFlag, x.n) ) { ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, get_displ_outf(x)); if ( ea != BADADDR ) { ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } } // create stack variables if required if ( may_create_stkvars() && !isDefArg(uFlag, x.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && (issp(x.phrase) || isbp(x.phrase) && (pfn->flags & FUNC_FRAME) != 0) ) { if ( ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) ) op_stkvar(cmd.ea, x.n); } } break; case o_near: add_code_xref(x, calc_mem(x.addr)); break; case o_mem: case o_memind: { ea_t ea = calc_mem(x.addr); if ( !isEnabled(ea) && find_sym(ea) ) break; // address not here ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( x.type == o_memind ) { ssize_t size = get_dtyp_size(x.dtyp); flags_t F = getFlags(ea); if ( (isWord(F) || isDwrd(F)) && (!isDefArg0(F) || isOff0(F)) ) { ea_t target = calc_mem(size == 2 ? get_word(ea) : (get_long(ea) & 0xFFFFFFL)); if ( isEnabled(target) ) add_code_xref(x, target); if ( !isOff0(F) ) set_offset(ea, 0, calc_mem(0)); } break; } if ( !isload ) doVar(ea); } break; default: INTERR(10095); } }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_add_bpt(bpttype_t, ea_t, int) { INTERR(30114); }
//-------------------------------------------------------------------------- int idaapi rpc_debmod_t::dbg_del_bpt(bpttype_t, ea_t, const uchar *, int) { INTERR(30115); }
// Emulate an operand. static void handle_operand(op_t &op, bool write) { switch ( op.type ) { // Code address case o_near: { cref_t mode; ea_t ea = toEA(cmd.cs, op.addr); // call or jump ? if ( cmd.itype == st9_call || cmd.itype == st9_calls ) { if ( !func_does_return(ea) ) flow = false; mode = fl_CN; } else { mode = fl_JN; } ua_add_cref(op.offb, ea, mode); } break; // Memory address case o_mem: { enum dref_t mode; mode = write ? dr_W: dr_R; ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode); ua_dodata2(op.offb, op.addr, op.dtyp); } break; // Immediate value case o_imm: doImmd(cmd.ea); // create a comment if this immediate is represented in the .cfg file { const ioport_t * port = find_sym(op.value); if ( port != NULL && !has_cmt(uFlag) ) { set_cmt(cmd.ea, port->cmt, false); } } // if the value was converted to an offset, then create a data xref: if ( op_adds_xrefs(uFlag, op.n) ) ua_add_off_drefs2(op, dr_O, 0); break; // Displacement case o_displ: doImmd(cmd.ea); if ( op_adds_xrefs(uFlag, op.n) ) { ea_t ea = ua_add_off_drefs2(op, dr_O, OOF_ADDR); ua_dodata2(op.offb, ea, op.dtyp); } // create stack variables if required if ( may_create_stkvars() && !isDefArg(uFlag, op.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && pfn->flags & FUNC_FRAME ) { if ( ua_stkvar2(op, op.addr, STKVAR_VALID_SIZE) ) { op_stkvar(cmd.ea, op.n); if ( cmd.Op2.type == o_reg ) { regvar_t *r = find_regvar(pfn, cmd.ea, ph.regNames[cmd.Op2.reg]); if ( r != NULL ) { struc_t *s = get_frame(pfn); member_t *m = get_stkvar(op, op.addr, NULL); if ( s != NULL && m != NULL ) { char b[20]; qsnprintf(b, sizeof b, "%scopy", r->user); set_member_name(s, m->soff, b); } } } } } } break; // Register - Phrase - Void: do nothing case o_reg: case o_phrase: case o_void: break; default: INTERR(10076); } }
//---------------------------------------------------------------------- static void handle_operand(op_t &x, bool read_access) { ea_t ea; dref_t dreftype; switch ( x.type ) { case o_void: case o_reg: break; case o_imm: QASSERT(557, read_access); dreftype = dr_O; MAKE_IMMD: doImmdValue(); if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dreftype); break; case o_displ: dreftype = read_access ? dr_R : dr_W; switch ( x.phrase ) { case rD: // "dp" case rDX: // "dp, X" case rDY: // "dp, Y" case riDX: // "(dp, X)" case rDi: // "(dp,n)" case rDiL: // "long(dp,n)" case rDiY: // "(dp,n), Y" case rDiLY: // "long(dp,n), Y" { sel_t dp = get_segreg(cmd.ea, rD); if ( dp != BADSEL ) { ea_t orig_ea = dp + x.addr; ea = xlat(orig_ea); goto MAKE_DREF; } else { goto MAKE_IMMD; } } case rAbsi: // "(abs)" case rAbsX: // "abs, X" case rAbsY: // "abs, Y" case rAbsiL: // "long(abs)" ea = toEA(dataSeg_op(x.n), x.addr); goto MAKE_DREF; case rAbsXi: // "(abs,X)" ea = toEA(codeSeg(cmd.ea, x.n), x.addr); // jmp, jsr goto MAKE_DREF; case rAbsLX: // "long abs, X" ea = x.addr; goto MAKE_DREF; default: goto MAKE_IMMD; } case o_mem: case o_mem_far: ea = calc_addr(x); MAKE_DREF: ua_dodata2(x.offb, ea, x.dtyp); if ( !read_access ) doVar(ea); ua_add_dref(x.offb, ea, read_access ? dr_R : dr_W); break; case o_near: case o_far: { ea_t orig_ea; ea = calc_addr(x, &orig_ea); if ( cmd.itype == M65816_per ) { ua_add_dref(x.offb, ea, dr_O); } else { bool iscall = InstrIsSet(cmd.itype, CF_CALL); cref_t creftype = x.type == o_near ? iscall ? fl_CN : fl_JN : iscall ? fl_CF : fl_JF; ua_add_cref(x.offb, ea, creftype); if ( flow && iscall ) flow = func_does_return(ea); } } break; default: INTERR(558); } }
// Emulate an operand. static void handle_operand(op_t &op) { bool offset = false; switch ( op.type ) { case o_near: ua_add_cref(op.offb, toEA(cmd.cs, op.addr), (cmd.itype == fr_call) ? fl_CN : fl_JN); break; case o_mem: { enum dref_t mode = dr_U; if ( op.specflag1 & OP_ADDR_R ) mode = dr_R; else if ( op.specflag1 & OP_ADDR_W ) mode = dr_W; ea_t ea = toEA(cmd.cs, op.addr); ua_add_dref(op.offb, ea, mode); ua_dodata2(op.offb, ea, op.dtyp); } break; case o_imm: // if current insn is ldi:32 #imm, r1 // and next insn is call @r1, // replace the immediate value with an offset. if (cmd.itype == fr_ldi_32 && cmd.Op1.type == o_imm && cmd.Op2.type == o_reg) { const int callreg = cmd.Op2.reg; insn_t cmd_backup = cmd; if ( next_insn(cmd.ea + cmd.size ) > 0 && cmd.itype == fr_call && cmd.Op1.type == o_phrase && cmd.Op1.specflag2 == fIGR && cmd.Op1.reg == callreg) { offset = true; } const ea_t from = cmd.ea; cmd = cmd_backup; if ( !isDefArg(uFlag, 0) && offset && set_offset(cmd.ea, 0, 0) ) add_cref(from, toEA(cmd.cs, cmd.Op1.value), fl_CN); } doImmd(cmd.ea); if ( !offset ) // 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); // create stack variables if necessary { bool ok = false; // ldi8 #our_value, R1 // extsb R1 // addn R14, R1 if (cmd.itype == fr_ldi_8 && cmd.Op2.type == o_reg && cmd.Op2.reg == rR1) { insn_t current_insn = cmd; next_insn(cmd.ea + cmd.size); if (cmd.itype == fr_extsb && cmd.Op1.type == o_reg && cmd.Op1.reg == rR1) { ok = true; } if ( ok ) { ok = false; next_insn(cmd.ea + cmd.size); if (cmd.itype == fr_addn && cmd.Op1.type == o_reg && cmd.Op1.reg == rR14 && cmd.Op2.type == o_reg && cmd.Op2.reg == rR1) { ok = true; } } cmd = current_insn; } // ldi32 #our_value, Ri // addn R14, Ri // // (where Ri is either R1 or R2) else if (cmd.itype == fr_ldi_32 && cmd.Op2.type == o_reg && (cmd.Op2.reg == rR1 || cmd.Op2.reg == rR2)) { ushort the_reg = cmd.Op2.reg; insn_t current_insn = cmd; next_insn(cmd.ea + cmd.size); if (cmd.itype == fr_addn && cmd.Op1.type == o_reg && cmd.Op1.reg == rR14 && cmd.Op2.type == o_reg && cmd.Op2.reg == the_reg) { ok = true; } cmd = current_insn; } if ( ok && may_create_stkvars() && !isDefArg(uFlag, op.n) ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL && pfn->flags & FUNC_FRAME ) { if ( ua_stkvar2(op, op.value, 0) ) { op_stkvar(cmd.ea, op.n); } } } } break; case o_displ: case o_phrase: // XXX case o_reglist: case o_void: case o_reg: break; default: INTERR(10017); } }
// Output an operand bool idaapi outop(op_t &op) { switch ( op.type ) { // Data / Code memory address case o_near: case o_mem: BEG_TAG(op); out_addr(op); END_TAG(op); break; // Immediate value case o_imm: BEG_TAG(op); { const ioport_t * port = find_sym(op.value); // this immediate is represented in the .cfg file if ( port != NULL ) // output the port name instead of the numeric value out_line(port->name, COLOR_IMPNAME); // otherwise, simply print the value else out_imm(op); } END_TAG(op); break; // Displacement case o_displ: out_addr(op, false); out_symbol('('); out_reg(op); out_symbol(')'); break; // Register case o_reg: BEG_TAG(op); out_reg(op); END_TAG(op); if ( is_reg_with_bit(op) ) { out_symbol('.'); if ( is_bit_compl(op) ) out_symbol('!'); out_imm(op, true); } break; // Phrase case o_phrase: switch ( op.specflag2 ) { case fPI: // post increment out_symbol('('); out_reg(op); out_symbol(')'); out_symbol('+'); break; case fPD: // pre decrement out_symbol('-'); out_symbol('('); out_reg(op); out_symbol(')'); break; case fDISP: // displacement out_reg(op); out_symbol('('); { ushort reg = op.specflag2 << 8; reg |= op.specflag3; out_reg(reg); } out_symbol(')'); break; default: INTERR(10077); } break; // No operand case o_void: break; default: INTERR(10078); } return 1; }
//------------------------------------------------------------------------- // Converts an IDC variable to a Python variable // If py_var points to an existing object then the object will be updated // If py_var points to an existing immutable object then ZERO is returned // Returns one of CIP_xxxx. Check pywraps.hpp int idcvar_to_pyvar( const idc_value_t &idc_var, ref_t *py_var) { PYW_GIL_CHECK_LOCKED_SCOPE(); switch ( idc_var.vtype ) { case VT_PVOID: if ( *py_var == NULL ) { newref_t nr(PyCObject_FromVoidPtr(idc_var.pvoid, NULL)); *py_var = nr; } else { return CIP_IMMUTABLE; } break; case VT_INT64: { // Recycle? if ( *py_var != NULL ) { // Recycling an int64 object? int t = get_pyidc_cvt_type(py_var->o); if ( t != PY_ICID_INT64 ) return CIP_IMMUTABLE; // Cannot recycle immutable object // Update the attribute PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, PyLong_FromLongLong(idc_var.i64)); return CIP_OK; } ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_INT64)); if ( py_cls == NULL ) return CIP_FAILED; *py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, PyLong_FromLongLong(idc_var.i64), NULL)); if ( PyW_GetError() || *py_var == NULL ) return CIP_FAILED; break; } #if !defined(NO_OBSOLETE_FUNCS) || defined(__EXPR_SRC) case VT_STR: *py_var = newref_t(PyString_FromString(idc_var.str)); break; #endif case VT_STR2: if ( *py_var == NULL ) { const qstring &s = idc_var.qstr(); *py_var = newref_t(PyString_FromStringAndSize(s.begin(), s.length())); break; } else return CIP_IMMUTABLE; // Cannot recycle immutable object case VT_LONG: // Cannot recycle immutable objects if ( *py_var != NULL ) return CIP_IMMUTABLE; *py_var = newref_t(cvt_to_pylong(idc_var.num)); break; case VT_FLOAT: if ( *py_var == NULL ) { double x; if ( ph.realcvt(&x, (uint16 *)idc_var.e, (sizeof(x)/2-1)|010) != 0 ) INTERR(30160); *py_var = newref_t(PyFloat_FromDouble(x)); break; } else return CIP_IMMUTABLE; case VT_REF: { if ( *py_var == NULL ) { ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_BYREF)); if ( py_cls == NULL ) return CIP_FAILED; // Create a byref object with None value. We populate it later *py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, Py_None, NULL)); if ( PyW_GetError() || *py_var == NULL ) return CIP_FAILED; } int t = get_pyidc_cvt_type(py_var->o); if ( t != PY_ICID_BYREF ) return CIP_FAILED; // Dereference // (Since we are not using VREF_COPY flag, we can safely const_cast) idc_value_t *dref_v = VarDeref(const_cast<idc_value_t *>(&idc_var), VREF_LOOP); if ( dref_v == NULL ) return CIP_FAILED; // Can we recycle the object? ref_t new_py_val(PyW_TryGetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR)); if ( new_py_val != NULL ) { // Recycle t = idcvar_to_pyvar(*dref_v, &new_py_val); // Success? Nothing more to be done if ( t == CIP_OK ) return CIP_OK; // Clear it so we don't recycle it new_py_val = ref_t(); } // Try to convert (not recycle) if ( idcvar_to_pyvar(*dref_v, &new_py_val) != CIP_OK ) return CIP_FAILED; // Update the attribute PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, new_py_val.o); break; } // Can convert back into a Python object or Python dictionary // (Depending if py_var will be recycled and it was a dictionary) case VT_OBJ: { // Check if this IDC object has __cvt_id__ and the __idc_cvt_value__ fields idc_value_t idc_val; if ( VarGetAttr(&idc_var, S_PY_IDCCVT_ID_ATTR, &idc_val) == eOk && VarGetAttr(&idc_var, S_PY_IDCCVT_VALUE_ATTR, &idc_val) == eOk ) { // Extract the object *py_var = borref_t((PyObject *) idc_val.pvoid); return CIP_OK_OPAQUE; } ref_t obj; bool is_dict = false; // Need to create a new object? if ( *py_var == NULL ) { // Get skeleton class reference ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_APPCALL_SKEL_OBJ)); if ( py_cls == NULL ) return CIP_FAILED; // Call constructor obj = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, NULL)); if ( PyW_GetError() || obj == NULL ) return CIP_FAILED; } else { // Recycle existing variable obj = *py_var; if ( PyDict_Check(obj.o) ) is_dict = true; } // Walk the IDC attributes and store into python for (const char *attr_name = VarFirstAttr(&idc_var); attr_name != NULL; attr_name = VarNextAttr(&idc_var, attr_name) ) { // Get the attribute idc_value_t v; VarGetAttr(&idc_var, attr_name, &v, true); // Convert attribute to a python value (recursively) ref_t py_attr; int cvt = idcvar_to_pyvar(v, &py_attr); if ( cvt <= CIP_IMMUTABLE ) return CIP_FAILED; if ( is_dict ) PyDict_SetItemString(obj.o, attr_name, py_attr.o); else PyObject_SetAttrString(obj.o, attr_name, py_attr.o); } *py_var = obj; break; } // Unhandled type default: *py_var = ref_t(); return CIP_FAILED; } return CIP_OK; }