//-------------------------------------------------------------------------- static void declare_class(ea_t ea, const char *entryname) { static const char class_name[] = "ClassStruct"; struc_t *sptr = get_struc(get_struc_id(class_name)); if ( sptr == NULL ) { sptr = get_struc(add_struc(BADADDR, class_name)); if ( sptr == NULL ) return; opinfo_t mt; mt.ri.flags = REF_OFF32; mt.ri.target = BADADDR; mt.ri.base = 0; mt.ri.tdelta = 0; add_struc_member(sptr, "superClass", BADADDR, offflag()|dwrdflag(), &mt, 4); add_struc_member(sptr, "masterOffset", BADADDR, wordflag(), NULL, 2); add_struc_member(sptr, "methodCount", BADADDR, decflag()|wordflag(), NULL, 2); add_struc_member(sptr, "instanceSize", BADADDR, decflag()|wordflag(), NULL, 2); add_struc_member(sptr, "vdRelocTable", BADADDR, wordflag(), NULL, 2); add_struc_member(sptr, "relocTable", BADADDR, wordflag(), NULL, 2); mt.ec.tid = get_class_struct_flags_enum(); mt.ec.serial = 0; add_struc_member(sptr, "flags", BADADDR, enumflag()|byteflag(), &mt, 1); add_struc_member(sptr, "masterMethods",BADADDR, byteflag(), NULL, 1); } asize_t size = get_struc_size(sptr); doStruct(ea, size, sptr->id); int count = get_word(ea+6); // bool c_handlers = get_byte(ea+14) & (1<<6); ea += size; ea_t messages = ea; doWord(ea, count*2); op_dec(ea, 0); ea += 2*count; doDwrd(ea, count*4); set_offset(ea, 0, 0); for ( int i=0; i < count; i++ ) { ea_t idx = ea + 4*i; ea_t pea = toEA(get_word(idx+2), get_word(idx)); auto_make_proc(pea); char name[MAXSTR]; qsnprintf(name, sizeof(name), "%s_%u", entryname, get_word(messages+2*i)); add_entry(pea, pea, name, true); } // commented out because it doesn't work properly // see geoplan.geo, entry number 1 for example // if ( c_handlers ) // declare_parameter_types(ea+count*4, count); }
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::newfile: { // ig: вообще у меня теперь такая точка зрения: // не надо в коде задавать вид имен. // при желании это можно сделать в ida.cfg: // #ifdef __80196__ // DUMMY_NAMES_TYPE = NM_SHORT // #endif segment_t *sptr = get_first_seg(); if( sptr != NULL ) set_segm_class( sptr, "CODE" ); ea_t ea, ea1; for( int i = 0; i < qnumber(entries); i++ ) { ea = toEA( inf.baseaddr, entries[i].off ); if( isEnabled(ea) ) { switch( entries[i].type ) { case I196F_BTS: doByte( ea, entries[i+1].off-entries[i].off ); set_cmt( ea, entries[i].cmt, 0 ); break; case I196F_CMT: if( entries[i].cmt ) add_long_cmt( ea, 1, "%s", entries[i].cmt ); else describe( ea, 1, "" ); break; case I196F_OFF: doWord( ea, 2 ); set_offset( ea, 0, toEA( inf.baseaddr, 0 ) ); ea1 = toEA( inf.baseaddr, get_word( ea ) ); auto_make_proc( ea1 ); //dash: long_cmt здесь не смотрится, так как рисуется до заголовка // хорошо бы поставить func_cmt, но к этому моменту функций еще нет // как быть? //ig: воспользоваться простым комментарием // при создании функции комментарий перетащится set_cmt( ea1, entries[i].cmt, 1 ); } set_name( ea, entries[i].name ); } } ea = toEA( inf.baseaddr, 0x2080 ); if( isEnabled( ea ) ) { inf.beginEA = ea; inf.startIP = 0x2080; } segment_t s; s.startEA = toEA( inf.baseaddr, 0 ); s.endEA = toEA( inf.baseaddr, 0x400 ); s.sel = inf.baseaddr; s.type = SEG_IMEM; // internal memory // ig: лучше искать дырку не от нуля, а от базы загрузки // ea_t bottom = toEA( inf.baseaddr, 0 ); // intmem = s.startEA = freechunk( bottom, 1024, 0xF ); // s.endEA = s.startEA + 1024; // s.sel = ushort(s.startEA >> 4); // dash: дырку искать не пришлось, но я оставил это как пример на будущее add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE); predefined_t *ptr; for( ptr = iregs; ptr->name != NULL; ptr++ ) { ea_t ea = toEA( inf.baseaddr, ptr->addr ); ea_t oldea = get_name_ea( BADADDR, ptr->name ); if( oldea != ea ) { if( oldea != BADADDR ) set_name( oldea, NULL ); do_unknown( ea, DOUNK_EXPAND ); set_name( ea, ptr->name ); } if( ptr->cmt != NULL ) set_cmt( ea, ptr->cmt, 1 ); } } // do16bit( 0x18, 2 ); // SP always word break; case processor_t::oldfile: for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( getSRarea(s->startEA) == NULL ) { segreg_t sr; sr.startEA = s->startEA; sr.endEA = s->endEA; sr.reg(WSR) = 0; sr.reg(WSR1) = 0; sr.reg(rVds) = inf.baseaddr; sr.settags(SR_autostart); SRareas.create_area(&sr); } } break; case processor_t::newseg: // default DS is equal to Base Address (va_arg(va, segment_t *))->defsr[rVds-ph.regFirstSreg] = inf.baseaddr; break; case processor_t::newprc: extended = va_arg(va,int) != 0; if ( !extended ) ph.flag &= ~PR_SEGS; else ph.flag |= PR_SEGS; default: break; } va_end(va); return(1); }
//---------------------------------------------------------------------- // New method: symbol enumeration callback //lint -e{818} could be declared as pointing to const static BOOL CALLBACK EnumerateSymbolsProc( PSYMBOL_INFO psym, ULONG /*SymbolSize*/, PVOID delta) { symbols_found++; ea_t ea = (ea_t)(psym->Address + *(adiff_t*)delta); const char *name = psym->Name; int maybe_func = 0; // maybe switch ( psym->Tag ) { case SymTagFunction: case SymTagThunk: #ifndef PDBTOTIL auto_make_proc(ea); // certainly a func #endif maybe_func = 1; break; case SymTagNull: case SymTagExe: case SymTagCompiland: case SymTagCompilandDetails: case SymTagCompilandEnv: case SymTagData: case SymTagAnnotation: case SymTagUDT: case SymTagEnum: case SymTagFunctionType: case SymTagPointerType: case SymTagArrayType: case SymTagBaseType: case SymTagTypedef: case SymTagBaseClass: case SymTagFunctionArgType: case SymTagUsingNamespace: case SymTagVTableShape: case SymTagVTable: case SymTagCustom: case SymTagCustomType: case SymTagManagedType: case SymTagDimension: maybe_func = -1; break; case SymTagBlock: case SymTagLabel: case SymTagFuncDebugStart: case SymTagFuncDebugEnd: maybe_func = 2; break; case SymTagPublicSymbol: case SymTagFriend: default: break; } bool ok = apply_name(ea, name, maybe_func); // New dbghelp.dll/symsrv.dll files return names without the terminating zero. // So, as soon as we have a long name, shorter names will have garbage at the end. // Clean up the name to avoid problems. size_t len = strlen(name); memset((void*)name, '\0', len); return ok; }
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: inf.mf = 1; // MSB first default: break; case processor_t::newfile: { segment_t *sptr = get_first_seg(); if( sptr != NULL ) { if( sptr->startEA - get_segm_base( sptr ) == 0 ) { inf.beginEA = sptr->startEA + 0xC; inf.startIP = 0xC; for( int i = 0; i < qnumber(entries); i++ ) { ea_t ea = sptr->startEA + entries[i].off; if( isEnabled(ea) ) { doWord( ea, 2 ); // ig: set_op_type - внутренняя функция, ее нельзя использовать // set_op_type( ea, offflag(), 0 ); set_offset( ea, 0, sptr->startEA ); ea_t ea1 = sptr->startEA + get_word( ea ); auto_make_proc( ea1 ); set_name( ea, entries[i].name ); // ig: так получше будет? set_cmt( sptr->startEA+get_word(ea), entries[i].cmt, 1 ); } } } set_segm_class( sptr, "CODE" ); } segment_t s; ea_t bottom = toEA( inf.baseaddr, 0 ); intmem = s.startEA = freechunk( bottom, 256, 0xF ); s.endEA = s.startEA + 256; s.sel = allocate_selector( s.startEA >> 4 ); s.type = SEG_IMEM; // internal memory add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE); const predefined_t *ptr; for( ptr = iregs; ptr->name != NULL; ptr++ ) { ea_t ea = intmem + ptr->addr; ea_t oldea = get_name_ea( BADADDR, ptr->name ); if( oldea != ea ) { if( oldea != BADADDR ) set_name( oldea, NULL ); do_unknown( ea, DOUNK_EXPAND ); set_name( ea, ptr->name ); } if( ptr->cmt != NULL ) set_cmt( ea, ptr->cmt, 1 ); } } break; case processor_t::oldfile: sel_t sel; if( atos( "INTMEM", &sel) ) intmem = specialSeg(sel); break; case processor_t::newseg: { // default DS is equal to CS segment_t *sptr = va_arg(va, segment_t *); sptr->defsr[rVds-ph.regFirstSreg] = sptr->sel; } } va_end(va); return(1); }