static int out_equ(ea_t ea) { char buf[MAXSTR]; char *const end = buf + sizeof(buf); segment_t *s = getseg(ea); if ( s != NULL && s->type == SEG_IMEM && ash.a_equ != NULL) { char nbuf[MAXSTR]; char *name = get_name(BADADDR, ea, nbuf, sizeof(nbuf)); if ( name != NULL && ((ash.uflag & UAS_PBYTNODEF) == 0 || !IsPredefined(name)) ) { get_colored_name(BADADDR, ea, buf, sizeof(buf)); uchar off = uchar(ea - get_segm_base(s)); do_out_equ(buf, ash.a_equ, off); if ( (ash.uflag & UAS_AUBIT) == 0 && (off & 0xF8) == off ) { char *ptr = tag_on(tail(buf), end, COLOR_SYMBOL); APPCHAR(ptr, end, ash.uflag & UAS_NOBIT ? '_' : '.'); APPCHAR(ptr, end, '0'); tag_off(ptr, end, COLOR_SYMBOL); for ( int i=0; i < 8; i++ ) { const ioport_bit_t *b = find_bit(off, i); char *p2 = ptr; if ( b == NULL || b->name == NULL ) ptr[-1] = '0' + i; else p2 = tag_addstr(ptr-1, end, COLOR_HIDNAME, b->name); tag_off(p2, end, COLOR_SYMBOL); do_out_equ(buf, ash.a_equ, off+i); } MakeNull(); } } else { gl_name = 0; MakeLine(""); } return 1; } if ( ash.uflag & UAS_NODS ) { if ( !isLoaded(ea) && s->type == SEG_CODE ) { adiff_t org = ea - get_segm_base(s) + get_item_size(ea); btoa(buf, sizeof(buf), org); printf_line(inf.indent, COLSTR("%s %s", SCOLOR_ASMDIR), ash.origin, buf); return 1; } } return 0; }
//-------------------------------------------------------------------------- // начало сегмента void N78K_segstart(ea_t ea) { segment_t *Sarea = getseg(ea); const char *SegType= (Sarea->type==SEG_CODE)?"CSEG": ((Sarea->type==SEG_DATA)?"DSEG": "RSEG" ); // Выведем строку вида RSEG <NAME> #if IDP_INTERFACE_VERSION > 37 char sn[MAXNAMELEN]; get_segm_name(Sarea,sn,sizeof(sn)); printf_line(-1,"%s %s ",SegType, sn); #else printf_line(-1,"%s %s ",SegType, get_segm_name(Sarea)); #endif // если смещение не ноль - выведем и его (ORG XXXX) if ( inf.s_org ) { ulong org = ea - get_segm_base(Sarea); if( org != 0 ){ #if IDP_INTERFACE_VERSION > 37 char bufn[MAX_NUMBUF]; btoa(bufn, sizeof(bufn), org); printf_line(-1, "%s %s", ash.origin, bufn); #else printf_line(-1, "%s %s", ash.origin, btoa(org)); #endif } } }
//---------------------------------------------------------------------- // функция оповещения static int notify(int msgnum,void *arg,...) { // Various messages: qnotused(arg); switch ( msgnum ) { // новый файл case IDP_NEWFILE: inf.mf = 0; // MSB last inf.nametype = NM_SHORT; segment_t *sptr = get_first_seg(); if ( sptr != NULL ) { if ( sptr->startEA-get_segm_base(sptr) == 0 ) { inf.beginEA = sptr->startEA; inf.startIP = 0; } } // основной сегмент - кодовый set_segm_class(get_first_seg(), "CODE"); break; // создание нового сегмента case IDP_NEWSEG: { segment_t *seg; seg=((segment_t *)arg); // установим регистры по умолчанию seg->defsr[rVds-ph.regFirstSreg] = 0; break; } } return 1; }
//---------------------------------------------------------------------- static void fixup(uint32 ea, uint32 delta, int extdef) { fixup_data_t fd; fd.type = FIXUP_OFF32; if ( extdef ) fd.type |= FIXUP_EXTDEF; segment_t *s = getseg(delta); fd.displacement = get_long(ea); if ( s == NULL ) { fd.sel = 0; fd.off = delta; } else { fd.sel = (ushort)s->sel; fd.off = delta - get_segm_base(s); } set_fixup(ea, &fd); uint32 target = get_long(ea) + delta; put_long(ea, target); set_offset(ea, 0, 0); cmd.ea = ea; ua_add_dref(0, target, dr_O); cmd.ea = BADADDR; if ( target != toc_ea && !has_name(get_flags_novalue(ea)) && has_name(get_flags_novalue(target)) ) { char buf[MAXSTR]; if ( get_true_name(BADADDR, target, &buf[3], sizeof(buf)-3) != NULL ) { buf[0] = 'T'; buf[1] = 'C'; buf[2] = '_'; do_name_anyway(ea, buf); make_name_auto(ea); } } // toc.charset(ea,XMC_TC+1,1); }
//---------------------------------------------------------------------- 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); } }
//-------------------------------------------------------------------------- void segstart(ea_t ea) { segment_t *Sarea = getseg(ea); if ( is_spec_segm(Sarea->type) ) return; char sname[MAXNAMELEN]; char sclas[MAXNAMELEN]; get_true_segm_name(Sarea, sname, sizeof(sname)); get_segm_class(Sarea, sclas, sizeof(sclas)); if ( ash.uflag & UAS_GNU ) { const char *const predefined[] = { ".text", // Text section ".data", // Data sections ".rdata", ".comm", }; int i; for ( i=0; i < qnumber(predefined); i++ ) if ( strcmp(sname, predefined[i]) == 0 ) break; if ( i != qnumber(predefined) ) printf_line(inf.indent, COLSTR("%s", SCOLOR_ASMDIR), sname); else printf_line(inf.indent, COLSTR(".section %s", SCOLOR_ASMDIR) " " COLSTR("%s %s", SCOLOR_AUTOCMT), sname, ash.cmnt, sclas); } else { if ( strcmp(sname, "XMEM") == 0 ) { char buf[MAX_NUMBUF]; btoa(buf, sizeof(buf), ea-get_segm_base(Sarea)); printf_line(inf.indent, COLSTR("%s %c:%s", SCOLOR_ASMDIR), ash.origin, tolower(sname[0]), buf); } else { printf_line(inf.indent, COLSTR("section %s", SCOLOR_ASMDIR) " " COLSTR("%s %s", SCOLOR_AUTOCMT), sname, ash.cmnt, sclas); } } }
//-------------------------------------------------------------------------- void idaapi z8_data(ea_t ea) { segment_t *s = getseg(ea); if ( s != NULL && s->type == SEG_IMEM ) { char nbuf[MAXSTR]; char *name = get_name(BADADDR, ea, nbuf, sizeof(nbuf)); if ( name != NULL ) out_equ(name, ash.a_equ, uint16(ea - get_segm_base(s))); } else intel_data(ea); }
void segstart( ea_t ea ) { segment_t *Sarea = getseg( ea ); char name[MAXNAMELEN]; get_segm_name(Sarea, name, sizeof(name)); gen_cmt_line( COLSTR("segment %s", SCOLOR_AUTOCMT), name ); ea_t org = ea - get_segm_base( Sarea ); if ( org != 0 ) { char buf[MAX_NUMBUF]; btoa(buf, sizeof(buf), org); gen_cmt_line("%s %s", ash.origin, buf); } }
// -------------------------------------------------------------------------- // generate start of segment void idaapi segstart(ea_t ea) { // generate ORG directive if necessary if (inf.s_org) { // get segment data segment_t *Sarea = getseg(ea); size_t org = size_t(ea - get_segm_base(Sarea)); // generate line if ( org != 0 ) { char buf[MAX_NUMBUF]; btoa(buf, sizeof(buf), org); printf_line(inf.indent, COLSTR("%s %s", SCOLOR_ASMDIR), ash.origin, buf); } } }
void segstart(ea_t ea) { char buf[MAXSTR]; segment_t *Sarea = getseg(ea); char name[MAXNAMELEN]; get_segm_name(Sarea, name, sizeof(name)); if ( ash.uflag & UAS_SECT ) { if ( Sarea->type == SEG_IMEM ) { MakeLine(".RSECT", inf.indent); } else { printf_line(0, COLSTR("%s: .section", SCOLOR_ASMDIR), name); } } else { if(ash.uflag & UAS_NOSEG) printf_line(inf.indent, COLSTR("%s.segment %s", SCOLOR_AUTOCMT), ash.cmnt, name); else printf_line(inf.indent, COLSTR("segment %s",SCOLOR_ASMDIR), name); if(ash.uflag & UAS_SELSG) MakeLine(name, inf.indent); if(ash.uflag & UAS_CDSEG) MakeLine(Sarea->type == SEG_IMEM ? COLSTR("DSEG", SCOLOR_ASMDIR) : COLSTR("CSEG", SCOLOR_ASMDIR), inf.indent); // XSEG - eXternal memory } if ( inf.s_org ) { adiff_t org = ea - get_segm_base(Sarea); if ( org != 0 ) { btoa(buf, sizeof(buf), org); gen_cmt_line("%s %s", ash.origin, buf); } } }
//-------------------------------------------------------------------------- void segstart(ea_t ea) { char buf[MAXSTR]; char *const end = buf + sizeof(buf); segment_t *Sarea = getseg(ea); if ( is_spec_segm(Sarea->type) ) return; const char *align; switch ( Sarea->align ) { case saAbs: align = "at: "; break; case saRelByte: align = "byte"; break; case saRelWord: align = "word"; break; case saRelPara: align = "para"; break; case saRelPage: align = "page"; break; case saRel4K: align = "4k"; break; case saRel64Bytes: align = "64"; break; default: align = NULL; break; } if ( align == NULL ) { gen_cmt_line("Segment alignment '%s' can not be represented in assembly", get_segment_alignment(Sarea->align)); align = ""; } char sname[MAXNAMELEN]; char sclas[MAXNAMELEN]; get_true_segm_name(Sarea, sname, sizeof(sname)); get_segm_class(Sarea, sclas, sizeof(sclas)); char *ptr = buf + qsnprintf(buf, sizeof(buf), SCOLOR_ON SCOLOR_ASMDIR "%-*s segment %s ", inf.indent-1, sname, align); if ( Sarea->align == saAbs ) { ea_t absbase = get_segm_base(Sarea); ptr += btoa(ptr, end-ptr, absbase); APPCHAR(ptr, end, ' '); } const char *comb; switch ( Sarea->comb ) { case scPub: case scPub2: case scPub3: comb = ""; break; case scCommon: comb = "common"; break; default: comb = NULL; break; } if ( comb == NULL ) { gen_cmt_line("Segment combination '%s' can not be represented in assembly", get_segment_combination(Sarea->comb)); comb = ""; } ptr += qsnprintf(ptr, end-ptr, "%s '%s'", comb, sclas); tag_off(ptr, end, COLOR_ASMDIR); MakeLine(buf, 0); }
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); }
static int notify(processor_t::idp_notify msgid, ...) { static int first_time = 1; 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("$ intel 8051"); inf.mf = 1; // Set a big endian mode of the IDA kernel default: break; case processor_t::term: free_ioports(ports, numports); 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; inf.startIP = 0; for ( int i=0; i < qnumber(entries); i++ ) { if ( entries[i].proc > ptype ) continue; ea_t ea = inf.beginEA+entries[i].off; if ( isEnabled(ea) && get_byte(ea) != 0xFF ) { add_entry(ea, ea, entries[i].name, 1); set_cmt(ea, entries[i].cmt, 1); } } } } segment_t *scode = get_first_seg(); set_segm_class(scode, "CODE"); if ( ptype > prc_51 ) { AdditionalSegment(0x10000-256-128, 256+128, "RAM"); if ( scode != NULL ) { ea_t align = (scode->endEA + 0xFFF) & ~0xFFF; if ( getseg(align-7) == scode ) // the code segment size is { // multiple of 4K or near it uchar b0 = get_byte(align-8); // 251: // 0 : 1-source, 0-binary mode // 6,7: must be 1s // 82930: // 0 : 1-source, 0-binary mode // 7 : must be 1s // uchar b1 = get_byte(align-7); // 251 // 0: eprommap 0 - FE2000..FE4000 is mapped into 00E000..100000 // 1 - .............. is not mapped ............... // 1: must be 1 // 3: // 2: must be 1 // 4: intr 1 - upon interrupt PC,PSW are pushed into stack // 0 - upon interrupt only PC is pushed into stack // 5: must be 1 // 6: must be 1 // 7: must be 1 // 82930: // 3: must be 1 // 5: must be 1 // 6: must be 1 // 7: must be 1 // msg("b0=%x b1=%x\n", b0, b1); // if ( (b0 & 0x80) == 0x80 && (b1 & 0xEA) == 0xEA ) { // the init bits are correct char pname[sizeof(inf.procName)+1]; inf.get_proc_name(pname); char ntype = (b0 & 1) ? 's' : 'b'; char *ptr = tail(pname)-1; if ( ntype != *ptr && askyn_c(1, "HIDECANCEL\n" "The input file seems to be for the %s mode of the processor. " "Do you want to change the current processor type?", ntype == 's' ? "source" : "binary") > 0 ) { *ptr = ntype; first_time = 1; set_processor_type(pname, SETPROC_COMPAT); } } } } } // the default data segment will be INTMEM { segment_t *s = getseg(intmem); if ( s != NULL ) set_default_dataseg(s->sel); } if ( choose_ioport_device(cfgname, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); if ( get_segm_by_name("RAM") == NULL ) AdditionalSegment(256, 0, "RAM"); if ( get_segm_by_name("FSR") == NULL ) AdditionalSegment(128, 128, "FSR"); setup_data_segment_pointers(); } break; case processor_t::oldfile: setup_data_segment_pointers(); break; case processor_t::newseg: // make the default DS point to INTMEM // (8051 specific issue) { segment_t *newseg = va_arg(va, segment_t *); segment_t *intseg = getseg(intmem); if ( intseg != NULL ) newseg->defsr[rVds-ph.regFirstSreg] = intseg->sel; } break; case processor_t::newprc: { processor_subtype_t prcnum = processor_subtype_t(va_arg(va, int)); if ( !first_time && prcnum != ptype ) { warning("Sorry, it is not possible to change" // (this is 8051 specific) " the processor mode on the fly." " Please reload the input file" " if you want to change the processor."); return 0; } first_time = 0; ptype = prcnum; } break; case processor_t::newasm: // new assembler type { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } 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 *); // Add commands to adjust your internal variables here // Most of the time this callback will be empty // // If you keep information in a netnode's altval array, you can use // node.altshift(from, s->startEA, s->endEA - s->startEA); // // If you have a variables pointing to somewhere in the disassembled program memory, // you can adjust it like this: // // asize_t size = s->endEA - s->startEA; // if ( var >= from && var < from+size ) // var += s->startEA - from; } break; case processor_t::is_sane_insn: // is the instruction sane for the current file type? // arg: int no_crefs // 1: the instruction has no code refs to it. // ida just tries to convert unexplored bytes // to an instruction (but there is no other // reason to convert them into an instruction) // 0: the instruction is created because // of some coderef, user request or another // weighty reason. // The instruction is in 'cmd' // returns: 1-ok, <=0-no, the instruction isn't // likely to appear in the program { int no_crefs = va_arg(va, int); return is_sane_insn(no_crefs); } } va_end(va); return(1); }