void createSegment(unsigned int start, unsigned int size, unsigned char *content, unsigned int clen, const char *name) { segment_t s; //create ida segment to hold headers memset(&s, 0, sizeof(s)); s.startEA = start; s.endEA = start + size; s.align = saRelPara; s.comb = scPub; s.perm = SEGPERM_WRITE | SEGPERM_READ; s.bitness = 1; s.type = SEG_DATA; s.color = DEFCOLOR; if (add_segm_ex(&s, name, "DATA", ADDSEG_QUIET | ADDSEG_NOSREG)) { //zero out the newly created segment for (ea_t ea = s.startEA; ea < s.endEA; ea++) { patch_byte(ea, 0); } if (content) { patch_many_bytes(s.startEA, content, clen ? clen : size); } #ifdef DEBUG msg("segment created %x-%x\n", s.startEA, s.endEA); #endif } else { #ifdef DEBUG msg("seg create failed\n"); #endif } }
//---------------------------------------------------------------------- static ea_t AdditionalSegment(size_t size, ea_t offset, const char *name) { segment_t s; s.startEA = freechunk(0, size, -0xF); s.endEA = s.startEA + size; s.sel = allocate_selector((s.startEA-offset) >> 4); s.type = SEG_IMEM; add_segm_ex(&s, name, NULL, ADDSEG_NOSREG|ADDSEG_OR_DIE); return s.startEA - offset; }
//---------------------------------------------------------------------- static ea_t AdditionalSegment(size_t size, size_t offset, const char *name) { segment_t s; s.startEA = (ptype > prc_51) ? (inf.maxEA + 0xF) & ~0xF : freechunk(0, size, 0xF); s.endEA = s.startEA + size; s.sel = allocate_selector((s.startEA-offset) >> 4); s.type = SEG_IMEM; // internal memory add_segm_ex(&s, name, NULL, ADDSEG_NOSREG|ADDSEG_OR_DIE); return s.startEA - offset; }
//---------------------------------------------------------------------- static ea_t AddSegment(ea_t start, size_t size, ea_t base, const char *name, uchar type) { segment_t s; s.startEA = start; s.endEA = start + size; s.sel = allocate_selector(base >> 4); s.type = type; s.align = saRelByte; s.comb = scPub; add_segm_ex(&s, name, NULL, ADDSEG_NOSREG|ADDSEG_OR_DIE); return s.startEA; }
//-------------------------------------------------------------------------- static int create_seg( ea_t base, ea_t start, ea_t end, const char *name, const char *sclass) { if ( start != BADADDR && end < start ) return 0; segment_t s; s.sel = setup_selector(base); s.startEA= start; s.endEA = end; s.align = saRelByte; s.comb = (sclass != NULL && strcmp(sclass,"STACK") == 0) ? scStack : scPub; s.bitness = 0; return add_segm_ex(&s,name,sclass,ADDSEG_NOSREG); }
//-------------------------------------------------------------------------- static bool create_idata_segm(const area_t &impdir) { segment_t ns; segment_t *s = getseg(impdir.startEA); if ( s != NULL ) ns = *s; else ns.sel = setup_selector(0); ns.startEA = impdir.startEA; ns.endEA = impdir.endEA; ns.type = SEG_XTRN; ns.set_loader_segm(true); bool ok = add_segm_ex(&ns, ".idata", "XTRN", ADDSEG_NOSREG) != 0; if ( !ok ) ok = askyn_c(0, "HIDECANCEL\nCan not create the import segment. Continue anyway?") == 1; 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::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); }
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); }