void idaapi term(void) { msg(PLUGIN_NAME": collabREate is being unloaded\n"); authenticated = false; if (is_connected()) { msg(PLUGIN_NAME": calling cleanup\n"); cleanup(); msg(PLUGIN_NAME": back from cleanup\n"); } msg(PLUGIN_NAME": closing status form\n"); close_chooser("Collab form:1"); msg(PLUGIN_NAME": status form closed\n"); if (msgHistory.size() > 0) { qstring temp; for (unsigned int i = 0; i < msgHistory.size(); i++) { temp += msgHistory[i]; temp += '\n'; } cnn.setblob(temp.c_str(), temp.length() + 1, 1, COLLABREATE_MSGHISTORY_TAG); msgHistory.clear(); } if (changeCache != NULL && changeCache->length() > 0) { cnn.setblob(changeCache->c_str(), changeCache->length() + 1, 1, COLLABREATE_CACHE_TAG); delete changeCache; changeCache = NULL; } unhookAll(); }
//-------------------------------------------------------------------------- static int notify(processor_t::idp_notify msgid, ...) { // Various messages: va_list va; va_start(va, msgid); int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::newfile: case processor_t::oldfile: tnode.create("$ tms node"); default: break; case processor_t::move_segm:// A segment is moved // Fix processor dependent address sensitive information // args: ea_t from - old segment address // segment_t - moved segment { ea_t from = va_arg(va, ea_t); segment_t *s = va_arg(va, segment_t *); asize_t size = s->size(); tnode.altshift(from, s->startEA, size); tnode.altadjust(from, s->startEA, size, skip_12); } break; } return(1); }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if (code) return code; switch (msgid) { case processor_t::init: inf.mf = 0; inf.s_genflags |= INFFL_LZERO; helper.create("$ CR16"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: // ask for a processor from the config file // use it to handle ports and registers { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if (helper.supval(-1, buf, sizeof(buf)) > 0) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } break; } va_end(va); return 1; }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code != 0 ) return code; switch ( msgid ) { case processor_t::init: inf.mf = 0; inf.s_genflags |= INFFL_LZERO; helper.create("$ C39"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: //Выводит длг. окно процессоров, и позволяет выбрать нужный, считывает для выбраного //процессора информацию из cfg. По считаной информации подписывает порты и регстры { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } break; } va_end(va); return(1); }
static int notify(processor_t::idp_notify msgid, ...) { // Various messages: va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: helper.create("$ z80"); break; case processor_t::newprc: { int np = va_arg(va, int); pflag = features[np]; ph.assemblers = i8085asms; if ( isZ80() ) ph.assemblers = Z80asms; if ( is64180() ) ph.assemblers = HD64180asms; if ( isGB() ) ph.assemblers = GBasms; { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } } break; case processor_t::newfile: if ( strcmp(inf.procName, "z180") == 0 ) { char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_AREA); } break; default: break; } va_end(va); return(1); }
uval_t get_first_class_idx(void) { if (classes_indexes.altval(0)) return 0; else return -1; }
const char *set_idp_options(const char *keyword,int value_type,const void *value) { ushort trans; if ( keyword == NULL ) { trans = macro11.XlatAsciiOutput != NULL; if ( !AskUsingForm_c(form, &trans) ) return IDPOPT_OK; } else { if ( strcmp(keyword, "XlatAsciiOutput") == 0 ) { if ( value_type != IDPOPT_STR ) return IDPOPT_BADTYPE; memcpy(trans_dec_pc1, value, 256); return IDPOPT_OK; } if ( strcmp(keyword, "PDP_XLAT_ASCII") != 0 ) return IDPOPT_BADKEY; if ( value_type != IDPOPT_BIT ) return IDPOPT_BADTYPE; trans = *(ushort*)value; } ovrtrans.altset(n_asciiX, !trans); // it is strange but it is like this ash.XlatAsciiOutput = macro11.XlatAsciiOutput = trans ? trans_dec_pc1 : NULL; msg("Character Translation is %s\n", trans ? "enabled" : "disabled"); return IDPOPT_OK; }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: inf.mf = 1; helper.create("$ fr"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: choose_device(); set_device_name(device, IORESP_ALL); break; case processor_t::oldfile: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.supset(-1, device); break; } va_end(va); return(1); }
//Load the last update id from our netnode uint64_t getLastUpdate() { uint64_t val = 0; cnn.supval(LASTUPDATE_SUPVAL, &val, sizeof(val)); #ifdef DEBUG msg(PLUGIN_NAME": lastupdate supval is 0x%s\n", formatLongLong(val)); #endif return val; }
//-------------------------------------------------------------------------- // // Initialize. // // IDA will call this function only once. // If this function returns PLGUIN_SKIP, IDA will never load it again. // If this function returns PLUGIN_OK, IDA will unload the plugin but // remember that the plugin agreed to work with the database. // The plugin will be loaded again if the user invokes it by // pressing the hotkey or selecting it from the menu. // After the second load the plugin will stay on memory. // If this function returns PLUGIN_KEEP, IDA will keep the plugin // in the memory. In this case the initialization function can hook // into the processor module and user interface notification points. // See the hook_to_notification_point() function. // // In this example we check the input file format and make the decision. // You may or may not check any other conditions to decide what you do: // whether you agree to work with the database or not. // int idaapi init(void) { unsigned char md5[MD5_LEN]; msg(PLUGIN_NAME": collabREate has been loaded\n"); //while the md5 is not used here, it has the side effect of ensuring //that the md5 is taken at the earliest opportunity for storage in //the database in the event that the original binary is deleted getFileMd5(md5, sizeof(md5)); unsigned char gpid[GPID_SIZE]; ssize_t sz = getGpid(gpid, sizeof(gpid)); if (sz > 0) { msg(PLUGIN_NAME": Operating in caching mode until connected.\n"); if (changeCache == NULL) { size_t sz = 0; void *tcache = cnn.getblob(NULL, &sz, 1, COLLABREATE_CACHE_TAG); if (tcache != NULL && sz > 0) { changeCache = new qstring((char*)tcache); } else { changeCache = new qstring(); } qfree(tcache); hookAll(); } } if (msgHistory.size() == 0) { size_t sz = 0; void *thist = cnn.getblob(NULL, &sz, 1, COLLABREATE_MSGHISTORY_TAG); if (thist != NULL && sz > 1) { char *sptr, *endp; sptr = (char*)thist; while ((endp = strchr(sptr, '\n')) != NULL) { msgHistory.push_back(qstring(sptr, endp - sptr)); sptr = endp + 1; } } qfree(thist); } build_handler_map(); if (init_network()) { return PLUGIN_KEEP; } else { return PLUGIN_SKIP; } }
//----------------------------------------------------------------------- static ea_t load_offset(ea_t base, adiff_t value) { if(base == m.ovrtbl_base && value >= m.ovrcallbeg && value <= m.ovrcallend) { ea_t trans = ovrtrans.altval(value); if(trans != 0) return(trans); } return(base + value); }
tid_t get_class_by_idx(uval_t idx) // get class id by class number { tid_t result; if ( idx == -1 ) result = -1; else result = classes_indexes.altval(idx)-1; return result; }
tid_t get_class_by_idx(int index) { int result; // eax@2 if ( index == -1 ) result = -1; else result = classes_indexes.altval(index) -1; return result; }
const char *set_idp_options( const char *keyword, int /*value_type*/, const void * /*value*/ ) { if ( keyword != NULL ) return IDPOPT_BADKEY; if ( !choose_ioport_device(cfgname, device, sizeof(device), NULL) && strcmp(device, NONEPROC) == 0 ) { warning("No devices are defined in the configuration file %s", cfgname); } else { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_ALL); } return IDPOPT_OK; }
//---------------------------------------------------------------------- static void process_symbol_class(uint32 ea, uchar sclass, const char *name) { switch ( sclass ) { case kPEFCodeSymbol : case kPEFGlueSymbol : add_entry(ea, ea, name, 1); break; case kPEFTVectSymbol: process_vector(ea, name); break; case kPEFTOCSymbol : if ( segtype(ea) == SEG_DATA && ea < toc_ea ) { toc_ea = ea; ph.notify(processor_t::idp_notify(ph.loader+1), toc_ea); } toc.charset(ea, XMC_TD+1, 1); /* fall thru */ case kPEFDataSymbol : set_name(ea, name); break; } }
static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: // __emit__(0xCC); // debugger trap helper.create("$ h8/500"); inf.mf = 1; default: break; case processor_t::term: free_syms(); break; case processor_t::oldfile: // old file loaded idpflags = ushort(helper.altval(-1) + 1); create_segment_registers(); // no break case processor_t::newfile: // new file loaded load_symbols("h8500.cfg"); inf.mf = 1; break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags - 1); break; case processor_t::newseg: // new segment { segment_t *sptr = va_arg(va, segment_t *); sptr->defsr[BR-ph.regFirstSreg] = 0; sptr->defsr[DP-ph.regFirstSreg] = 0; } break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
void SuperFamicomCartridge::write_hash(netnode & node) const { node.hashset("rom_size", rom_size); node.hashset("ram_size", ram_size); node.hashset("firmware_appended", firmware_appended ? 1 : 0); node.hashset("header_offset", header_offset); node.hashset("type", type_string()); node.hashset("region", region_string()); node.hashset("mapper", mapper_string()); node.hashset("dsp1_mapper", dsp1_mapper_string()); node.hashset("has_bsx_slot", has_bsx_slot ? 1 : 0); node.hashset("has_superfx", has_superfx ? 1 : 0); node.hashset("has_sa1", has_sa1 ? 1 : 0); node.hashset("has_sharprtc", has_sharprtc ? 1 : 0); node.hashset("has_epsonrtc", has_epsonrtc ? 1 : 0); node.hashset("has_sdd1", has_sdd1 ? 1 : 0); node.hashset("has_spc7110", has_spc7110 ? 1 : 0); node.hashset("has_cx4", has_cx4 ? 1 : 0); node.hashset("has_dsp1", has_dsp1 ? 1 : 0); node.hashset("has_dsp2", has_dsp2 ? 1 : 0); node.hashset("has_dsp3", has_dsp3 ? 1 : 0); node.hashset("has_dsp4", has_dsp4 ? 1 : 0); node.hashset("has_obc1", has_obc1 ? 1 : 0); node.hashset("has_st010", has_st010 ? 1 : 0); node.hashset("has_st011", has_st011 ? 1 : 0); node.hashset("has_st018", has_st018 ? 1 : 0); }
size_t get_class_qty(void) { return classes_indexes.altval(-1); }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: inf.mf = 1; helper.create("$ fr"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: choose_device(); set_device_name(device, IORESP_ALL); break; case processor_t::oldfile: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.supset(-1, device); break; case processor_t::is_basic_block_end: return is_basic_block_end() ? 2 : 0; #ifdef FR_TYPEINFO_SUPPORT // +++ TYPE CALLBACKS case processor_t::max_ptr_size: return 4+1; case processor_t::get_default_enum_size: // get default enum size // args: cm_t cm // returns: sizeof(enum) { // cm_t cm = va_argi(va, cm_t); return 1; // inf.cc.size_e; } case processor_t::based_ptr: { uint ptrt = va_arg(va, unsigned int); qnotused(ptrt); char **ptrname = va_arg(va, char **); *ptrname = NULL; return 0; // returns: size of type } case processor_t::get_stkarg_offset2: // get offset from SP to the first stack argument // args: none // returns: the offset+2 return 0x00 + 2; case processor_t::calc_cdecl_purged_bytes2: // calculate number of purged bytes after call { //ea_t ea = va_arg(va, ea_t); return 0x00 + 2; } #endif // FR_TYPEINFO_SUPPORT #ifdef FR_TINFO_SUPPORT case processor_t::decorate_name3: { qstring *outbuf = va_arg(va, qstring *); const char *name = va_arg(va, const char *); bool mangle = va_argi(va, bool); cm_t cc = va_argi(va, cm_t); return gen_decorate_name3(outbuf, name, mangle, cc) ? 2 : 0; } case processor_t::calc_retloc3: //msg("calc_retloc3\n"); { const tinfo_t *type = va_arg(va, const tinfo_t *); cm_t cc = va_argi(va, cm_t); argloc_t *retloc = va_arg(va, argloc_t *); return calc_fr_retloc(*type, cc, retloc) ? 2 : -1; } break; case processor_t::calc_varglocs3: return 1; // not implemented break; case processor_t::calc_arglocs3: { //msg("calc_arglocs3\n"); func_type_data_t *fti = va_arg(va, func_type_data_t *); return calc_fr_arglocs(fti) ? 2 : -1; } case processor_t::use_stkarg_type3: { //msg("use_stkarg_type3\n"); ea_t ea = va_arg(va, ea_t); const funcarg_t *arg = va_arg(va, const funcarg_t* ); } return false; break; case processor_t::use_regarg_type3: //msg("use_regarg_type3\n"); { int *used = va_arg(va, int *); ea_t ea = va_arg(va, ea_t); const funcargvec_t *rargs = va_arg(va, const funcargvec_t *); *used = use_fr_regarg_type(ea, *rargs); return 2; } break; case processor_t::use_arg_types3: { ea_t ea = va_arg(va, ea_t); func_type_data_t *fti = va_arg(va, func_type_data_t *); funcargvec_t *rargs = va_arg(va, funcargvec_t *); use_fr_arg_types(ea, fti, rargs); return 2; } #ifdef IDA65 case processor_t::get_fastcall_regs2: case processor_t::get_varcall_regs2: { const int **regs = va_arg(va, const int **); return get_fr_fastcall_regs(regs) + 2; } case processor_t::get_thiscall_regs2: { const int **regs = va_arg(va, const int **); *regs = NULL; return 2; } #else case processor_t::get_fastcall_regs3: case processor_t::get_varcall_regs3: { const int *regs; get_fr_fastcall_regs(®s); callregs_t *callregs = va_arg(va, callregs_t *); callregs->set(ARGREGS_INDEPENDENT, regs, NULL); return callregs->nregs + 2; } case processor_t::get_thiscall_regs3: { callregs_t *callregs = va_arg(va, callregs_t *); callregs->reset(); return 2; } #endif IDA65 #endif // FR_TINFO_SUPPORT } va_end(va); return(1); }
// create the netnode helper and fetch idpflags value inline static uint32 refresh_idpflags(void) { helper.create("$ m32r"); idpflags = (uint32)helper.altval(-1); return idpflags; }
//-------------------------------------------------------------------------- static bool idaapi skip_12(ea_t ea) { ea_t target = tnode.altval(ea); return target == 1 || target == 2; }
static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: // __emit__(0xCC); // debugger trap helper.create("$ h8"); helper.supval(0, device, sizeof(device)); inf.mf = 1; default: break; /* +++ START TYPEINFO CALLBACKS +++ */ // see module/{i960,hppa}/reg.cpp starting on line 253 // Decorate/undecorate a C symbol name // Arguments: // const til_t *ti - pointer to til // const char *name - name of symbol // const type_t *type - type of symbol. If NULL then it will try to guess. // char *outbuf - output buffer // size_t bufsize - size of the output buffer // bool mangle - true-mangle, false-unmangle // cm_t cc - real calling convention for VOIDARG functions // returns: true if success case processor_t::decorate_name: { const til_t *ti = va_arg(va, const til_t *); const char *name = va_arg(va, const char *); const type_t *type = va_arg(va, const type_t *); char *outbuf = va_arg(va, char *); size_t bufsize = va_arg(va, size_t); bool mangle = va_argi(va, bool); cm_t real_cc = va_argi(va, cm_t); return gen_decorate_name(ti, name, type, outbuf, bufsize, mangle, real_cc); } // Setup default type libraries (called after loading a new file into the database) // The processor module may load tils, setup memory model and perform other actions // required to set up the type system. // args: none // returns: nothing case processor_t::setup_til: { } // Purpose: get prefix and size of 'segment based' ptr type (something like // char _ss *ptr). See description in typeinf.hpp. // Other modules simply set the pointer to NULL and return 0 // Ilfak confirmed that this approach is correct for the H8. // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8. // Arguments: // unsigned int ptrt - ... // const char **ptrname - output arg // returns: size of type case processor_t::based_ptr: { /*unsigned int ptrt =*/ va_arg(va, unsigned int); char **ptrname = va_arg(va, char **); *ptrname = NULL; return 0; } // The H8 supports normal (64KB addressing, 16 bits) and advanced mode // (16MB addressing, 24 bits). However, according to the Renesas technical // documentation, certain instructions accept 32-bit pointer values where // the upper 8 bits are "reserved". Ilfak confirms that "4+1" is fine. // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8. case processor_t::max_ptr_size: { return 4+1; } // get default enum size // args: cm_t cm // returns: sizeof(enum) case processor_t::get_default_enum_size: { // cm_t cm = va_argi(va, cm_t); return inf.cc.size_e; } case processor_t::use_stkarg_type: { ea_t ea = va_arg(va, ea_t); const type_t *type = va_arg(va, const type_t *); const char *name = va_arg(va, const char *); return h8_use_stkvar_type(ea, type, name); } // calculate number of purged bytes by the given function type // For cdecl functions, 'purged bytes' is always zero // See the IDA Pro Book, 2e, at the end of pp. 107 for details // args: type_t *type - must be function type // returns: number of bytes purged from the stack + 2 case processor_t::calc_purged_bytes: { //e.g. const type_t t_int[] = { BT_INT, 0 }; //const type_t *type = va_arg(va, const type_t *); // must be BT_FUNC return 0+2; } case processor_t::calc_arglocs2: { const type_t *type = va_arg(va, const type_t *); cm_t cc = va_argi(va, cm_t); varloc_t *arglocs = va_arg(va, varloc_t *); return h8_calc_arglocs(type, cc, arglocs); } /* +++ END TYPEINFO CALLBACKS +++ */ case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: // new file loaded load_symbols(); break; case processor_t::oldfile: // old file loaded load_symbols(); break; case processor_t::closebase: case processor_t::savebase: helper.supset(0, device); break; case processor_t::newprc: // new processor type ptype = ptypes[va_arg(va, int)]; setflag(ph.flag, PR_DEFSEG32, ptype & ADV); break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch(msgid) { case processor_t::init: helper.create("$ pic"); helper.supval(0, device, sizeof(device)); default: break; case processor_t::term: free_mappings(); free_ioports(ports, numports); break; case processor_t::newfile: // new file loaded { segment_t *s0 = get_first_seg(); if ( s0 != NULL ) { set_segm_name(s0, "CODE"); dataseg = AdditionalSegment(0x200, 0, "DATA"); segment_t *s1 = get_next_seg(s0->startEA); SetDefaultRegisterValue(s0, BANK, 0); SetDefaultRegisterValue(s1, BANK, 0); SetDefaultRegisterValue(s0, PCLATH, 0); SetDefaultRegisterValue(s1, PCLATH, 0); SetDefaultRegisterValue(s0, PCLATU, 0); SetDefaultRegisterValue(s1, PCLATU, 0); setup_device(IORESP_INT); apply_symbols(); } } break; case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); dataseg = helper.altval(0); create_mappings(); for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( s->defsr[PCLATH-ph.regFirstSreg] == BADSEL ) s->defsr[PCLATH-ph.regFirstSreg] = 0; } break; case processor_t::closebase: case processor_t::savebase: helper.altset(0, dataseg); helper.altset(-1, idpflags); helper.supset(0, device); break; case processor_t::newprc: // new processor type { int n = va_arg(va, int); static bool set = false; if ( set ) return 0; set = true; if ( ptypes[n] != ptype ) { ptype = ptypes[n]; ph.cnbits = 12 + 2*n; } switch ( ptype ) { case PIC12: register_names[PCLATH] = "status"; cfgname = "pic12.cfg"; break; case PIC14: cfgname = "pic14.cfg"; break; case PIC16: register_names[BANK] = "bsr"; cfgname = "pic16.cfg"; idpflags = 0; ph.cnbits = 8; ph.regLastSreg = PCLATU; break; default: error("interr in setprc"); break; } } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; } va_end(va); return 1; }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::newfile: helper.create("$ m7700"); if ( choose_device() ) set_device_name(device, IORESP_ALL); // Set the default segment register values : // -1 (badsel) for DR // 0 for fM and fX for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { SetDefaultRegisterValue(s, rDR, BADSEL); SetDefaultRegisterValue(s, rfM, 0); SetDefaultRegisterValue(s, rfX, 0); } info(m7700_help_message); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newprc: ptype = processor_subtype_t(va_arg(va, int)); break; case processor_t::setsgr: { ea_t ea1 = va_arg(va, ea_t); ea_t ea2 = va_arg(va, ea_t); int reg = va_arg(va, int); sel_t v = va_arg(va, sel_t); sel_t ov = va_arg(va, sel_t); if ( (reg == rfM || reg == rfX) && v != ov ) set_sreg_at_next_code(ea1, ea2, reg, ov); } break; case processor_t::oldfile: helper.create("$ m7700"); { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_ALL); } break; case processor_t::savebase: case processor_t::closebase: helper.supset(-1, device); break; } va_end(va); return(1); }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) // Various messages: { va_list va; va_start(va, msgid); // A well behaved processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; int retcode = 1; switch ( msgid ) { case processor_t::init: helper.create("$ spc700"); break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::oldfile: case processor_t::newfile: { char buf[MAXSTR]; const char *device_ptr = buf; ssize_t len = helper.hashstr("device", buf, sizeof(buf)); if ( len <= 0 ) device_ptr = "spc700"; if ( msgid == processor_t::newfile ) { set_device_name(device_ptr, IORESP_ALL); set_dsp_regs_enum(); set_default_segreg_value(NULL, rDs, 0); set_default_segreg_value(NULL, rFp, 0); } } break; case processor_t::may_be_func: retcode = 0; ea_t cref_addr; for( cref_addr = get_first_cref_to(cmd.ea); cref_addr != BADADDR; cref_addr = get_next_cref_to(cmd.ea, cref_addr) ) { uint8 opcode = get_byte(cref_addr); const struct opcode_info_t &opinfo = get_opcode_info(opcode); if ( opinfo.itype == SPC_call || opinfo.itype == SPC_jmp ) { retcode = 100; break; } } break; case processor_t::is_call_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_call ) retcode = 2; else retcode = 0; } break; case processor_t::is_ret_insn: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_ret || opinfo.itype == SPC_reti ) retcode = 2; else retcode = 0; } break; case processor_t::is_indirect_jump: { const struct opcode_info_t &opinfo = get_opcode_info(get_byte(va_arg(va, ea_t))); if ( opinfo.itype == SPC_jmp ) { if ( opinfo.addr == ABS_IX_INDIR ) retcode = 3; else retcode = 2; } else retcode = 1; } break; default: break; } va_end(va); return retcode; }
// The kernel event notifications // Here you may take desired actions upon some kernel events static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behavior processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: // this processor is big endian inf.mf = 1; default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: if ( choose_ioport_device(cfgname, device, sizeof(device), NULL) ) set_device_name(device, IORESP_ALL); // default configuration if ( refresh_idpflags() == 0 ) { idpflags = 0; idpflags |= NETNODE_USE_INSN_SYNTHETIC; idpflags |= NETNODE_USE_REG_ALIASES; } // patch register names according to idpflags patch_regnames(); break; case processor_t::newprc: ptype = processor_subtype_t(va_arg(va, int)); // msg("ptype = %s\n", ptype == prc_m32r ? "m32r" : ptype == prc_m32rx ? "m32rx" : "???"); break; case processor_t::oldfile: refresh_idpflags(); { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } // patch register names according to idpflags patch_regnames(); break; case processor_t::savebase: case processor_t::closebase: // synchronize the database long variable with the current configuration settings #ifdef DEBUG msg("Saving configuration: synthetic insn %s, aliases registers %s\n", use_synthetic_insn() ? "true " : "false", use_reg_aliases() ? "true" : "false" ); #endif helper.altset(-1, idpflags); helper.supset(-1, device); break; } va_end(va); return(1); }
static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: helper.create("$ tms320c3x"); inf.mf = 1; // MSB first inf.wide_high_byte_first = 1; init_analyzer(); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded inf.wide_high_byte_first = 0; { segment_t *s0 = get_first_seg(); if ( s0 != NULL ) { set_segm_name(s0, "CODE"); segment_t *s1 = get_next_seg(s0->startEA); for (int i = dp; i <= rVds; i++) { SetDefaultRegisterValue(s0, i, BADSEL); SetDefaultRegisterValue(s1, i, BADSEL); } } } select_device(IORESP_ALL); break; case processor_t::oldfile: // old file loaded inf.wide_high_byte_first = 0; idpflags = (ushort)helper.altval(-1); { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags); break; case processor_t::is_basic_block_end: return is_basic_block_end() ? 2 : 0; } va_end(va); return 1; }
static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: helper.create("$ st20"); helper.supval(0, device, sizeof(device)); break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded case processor_t::oldfile: // old file loaded load_symbols(); break; case processor_t::savebase: case processor_t::closebase: helper.supset(0, device); break; case processor_t::newprc: // new processor type procnum = va_arg(va, int); if ( isc4() ) ph.retcodes = retcodes4; break; case processor_t::is_jump_func: { const func_t *pfn = va_arg(va, const func_t *); ea_t *jump_target = va_arg(va, ea_t *); return is_jump_func(pfn, jump_target); } case processor_t::is_sane_insn: return is_sane_insn(va_arg(va, int)); case processor_t::may_be_func: // can a function start here? // arg: none, the instruction is in 'cmd' // returns: probability 0..100 // 'cmd' structure is filled upon the entrace // the idp module is allowed to modify 'cmd' return may_be_func(); } va_end(va); return 1; }
static int notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: helper.create("$ tms320c54"); { char buf[MAXSTR]; if ( helper.supval(0, buf, sizeof(buf)) > 0 ) set_device_name(buf); } inf.mf = 1; // MSB first break; case processor_t::term: free_ioports(ports, numports); default: break; case processor_t::newfile: // new file loaded { { SetDefaultRegisterValue(NULL, ARMS, 0); SetDefaultRegisterValue(NULL, CPL, 1); for (int i = DP; i <= rVds; i++) SetDefaultRegisterValue(NULL, i, 0); } static const char informations[] = { "AUTOHIDE REGISTRY\n" "Default values of flags and registers:\n" "\n" "ARMS bit = 0 (DSP mode operands).\n" "CPL bit = 1 (SP direct addressing mode).\n" "DP register = 0 (Data Page register)\n" "DPH register = 0 (High part of EXTENDED Data Page Register)\n" "PDP register = 0 (Peripheral Data Page register)\n" "\n" "You can change the register values by pressing Alt-G\n" "(Edit, Segments, Change segment register value)\n" }; info(informations); break; } case processor_t::oldfile: // old file loaded idpflags = (ushort)helper.altval(-1); break; case processor_t::closebase: case processor_t::savebase: helper.altset(-1, idpflags); helper.supset(0, device); break; case processor_t::newprc: // new processor type { ptype = ptypes[va_arg(va, int)]; switch ( ptype ) { case TMS320C55: break; default: error("interr: setprc"); break; } device[0] = '\0'; load_symbols(); } break; case processor_t::newasm: // new assembler type break; case processor_t::newseg: // new segment break; case processor_t::get_stkvar_scale_factor: return 2; } va_end(va); return 1; }
//---------------------------------------------------------------------- static int idaapi notify(processor_t::idp_notify msgid, ...) { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: inf.mf = 0; helper.create("$ 78k0s"); default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: { //функция "выбирает" из указанного файла *.cfg все записи(процессора) //и отображает их в диалоговом окне, в котором пользователь может выбрать //нужный ему процессор. После выбора имя процессора заносится в переменную device //Поумолчанию в DLG выделен процессор который указан в переменной .default //которая распологается в начале файла *.cfg inf.s_genflags |= INFFL_LZERO; char cfgfile[QMAXFILE]; get_cfg_filename(cfgfile, sizeof(cfgfile)); if ( choose_ioport_device(cfgfile, device, sizeof(device), parse_area_line0) ) //Устанавливает в ядре иды имя выбранного процессора //Вычитывает все "записи"(порты) относящиеся к этому процессору //И подписывает в файле все байты вычитанные из *.cfg файла set_device_name(device, IORESP_ALL); } break; case processor_t::newprc: { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_PORT); } break; case processor_t::newseg: // new segment { segment_t *s = va_arg(va, segment_t *); // Set default value of DS register for all segments set_default_dataseg(s->sel); } break; } va_end(va); return 1; }