//---------------------------------------------------------------------- // // define location as word (2 byte), convert it to an offset, rename it // and comment it with the file offset // static void name_vector( ushort address, const char *name ) { do_unknown( address, true ); do_data_ex( address, wordflag(), 2, BADNODE ); set_offset( address, 0, 0 ); set_name( address, name ); }
void applyPEHeaderTemplates(unsigned int mz_addr) { #if (IDA_SDK_VERSION < 520) tid_t idh = til2idb(-1, "IMAGE_DOS_HEADER"); tid_t inth = til2idb(-1, "IMAGE_NT_HEADERS"); tid_t ish = til2idb(-1, "IMAGE_SECTION_HEADER"); #else tid_t idh = import_type(ti, -1, "IMAGE_DOS_HEADER"); tid_t inth = import_type(ti, -1, "IMAGE_NT_HEADERS"); tid_t ish = import_type(ti, -1, "IMAGE_SECTION_HEADER"); #endif doStruct(mz_addr, sizeof(_IMAGE_DOS_HEADER), idh); unsigned short e_lfanew = get_word(mz_addr + 0x3C); mz_addr += e_lfanew; if (doStruct(mz_addr, sizeof(_IMAGE_NT_HEADERS), inth) == 0) { do_unknown(mz_addr, 0); set_cmt(mz_addr - e_lfanew, "!!Warning, MZ Header overlaps PE header!!", 0); doStruct(mz_addr, sizeof(_IMAGE_NT_HEADERS), inth); } unsigned short num_sects = get_word(mz_addr + 6); mz_addr += sizeof(_IMAGE_NT_HEADERS); for (unsigned short i = 0; i < num_sects; i++) { doStruct(mz_addr + i * sizeof(_IMAGE_SECTION_HEADER), sizeof(_IMAGE_SECTION_HEADER), ish); } }
//---------------------------------------------------------------------- // // defines, names and comments an item // static void define_item( ushort address, asize_t size, char *shortdesc, char *comment ) { do_unknown( address, true ); do_data_ex( address, (size == IOREG_16 ? wordflag() : byteflag() ), size, BADNODE ); set_name( address, shortdesc ); set_cmt( address, comment, true ); }
int process_switchB(ea_t curr, ea_t start, ea_t func_end) { ea_t diff = start - curr, min = func_end, ptr; unsigned long i; if ( diff && diff < 4 ) { do_unknown_range(curr, diff, true); } #ifdef PIC_DEBUG RP_TRACE2("start %X, to %X\n", start, func_end); #endif ptr = get_next_code(start); if ( NULL == ptr ) do_unknown(start,false); else { if ( isTail(getFlags(start)) ) { do_unknown(prev_not_tail(start),false); } else do_unknown_range(start, ptr-start, true); } for ( i = 0; start+i < min; i += 4 ) { ptr = got_addr - get_long(start + i); #ifdef PIC_DEBUG RP_TRACE3("min is %X, ptr %X, i %d\n", min, ptr, i); #endif if ( ptr < func_end ) { if ( ptr < min ) min = ptr; #ifdef PIC_DEBUG RP_TRACE2("one_switch_entry %X, ptr %X\n", start+i, ptr ); #endif one_switch_entry(start+i, ptr); } else break; /* end ? */ } return (i>>2); }
//---------------------------------------------------------------------- static void destroy_if_unnamed_array(ea_t ea) { flags_t F = get_flags_novalue(ea); if ( isTail(F) && segtype(ea) == SEG_IMEM ) { ea_t head = prev_not_tail(ea); if ( !has_user_name(get_flags_novalue(head)) ) { do_unknown(head, DOUNK_SIMPLE); doByte(head, ea-head); ea_t end = nextthat(ea, inf.maxEA, f_isHead, NULL); if ( end == BADADDR ) end = getseg(ea)->endEA; doByte(ea+1, end-ea-1); } } }
void process_switchA(ea_t curr, ea_t start, unsigned int N) { ea_t diff = start - curr; unsigned long i; if ( diff && diff < 4 ) { do_unknown_range(curr, diff, true); } if ( isTail(getFlags(start)) ) do_unknown(prev_not_tail(start),false); else do_unknown_range(start, N << 2, true); for ( i = 0; i <= N; i++ ) { diff = start + (i<<2); one_switch_entry(diff, got_addr - get_long(diff)); } }
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); }
void do_file_entry(const u8* base, const char* dir, const char* path, const char* name, int namelen, const struct cramfs_inode* inode) { int dirlen=strlen(dir); int pathlen=strlen(path); char pname[dirlen+pathlen+namelen+3]; const char* basename; if (dirlen) { strncpy(pname, dir, dirlen); } if (pathlen) { if (dirlen) { pname[dirlen]='/'; ++dirlen; } strncpy(pname+dirlen, path, pathlen); } if (namelen) { if (pathlen+dirlen) { pname[dirlen+pathlen]='/'; ++pathlen; } strncpy(pname+dirlen+pathlen, name, namelen); } pname[pathlen+dirlen+namelen]=0; basename=namelen ? pname+dirlen+pathlen : "/"; // Create things here printmode(inode); printuidgid(inode); if (S_ISREG(inode->mode)) { do_file(base, inode->offset<<2, inode->size, pname, basename, inode->mode); } else if (S_ISDIR(inode->mode)) { do_directory(base, inode->offset<<2, inode->size, pname, basename, inode->mode); } else if (S_ISLNK(inode->mode)) { do_symlink(base, inode->offset<<2, inode->size, pname, basename, inode->mode); } else if (S_ISFIFO(inode->mode)) { do_fifo(base, inode->offset<<2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else if (S_ISSOCK(inode->mode)) { do_socket(base, inode->offset<<2, inode->size, pname, basename, inode->mode); } else if (S_ISCHR(inode->mode)) { do_chrdev(base, inode->offset<<2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else if (S_ISBLK(inode->mode)) { do_blkdev(base, inode->offset<<2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else { do_unknown(base, inode->offset<<2, inode->size, pname, basename, inode->mode); } if (geteuid() == 0) { if (lchown(pname, inode->uid, inode->gid) == -1) perror("cannot change owner or group"); } else if(opt_idsfile && path && path[0]) { char dfp[1024]; char *p; FILE *f; strcpy(dfp,pname); p = strrchr(dfp,'/'); if (!p) { fprintf(stderr,"could not find path in '%s'\n",pname); return; } strcpy(p+1,opt_idsfile); f = fopen(dfp,"at"); if (!f) { perror(dfp); return; } fprintf(f,"%s,%u,%u,%08x\n",basename,inode->uid,inode->gid,inode->mode); fclose(f); } if (geteuid() == 0 || !opt_idsfile) { if (inode->mode & (S_ISGID|S_ISUID|S_ISVTX)) { if (0 != chmod(pname, inode->mode)){ perror("chmod"); return; } } } printf("\n"); }
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); }
void do_file_entry(const u8 * base, const char *dir, const char *path, const char *name, int namelen, const struct cramfs_inode *inode) { int dirlen = strlen(dir); int pathlen = strlen(path); char pname[dirlen + pathlen + namelen + 3]; const char *basename; u32 gid = inode->gid; if (dirlen) { strncpy(pname, dir, dirlen); } if (pathlen) { if (dirlen) { pname[dirlen] = '/'; ++dirlen; } strncpy(pname + dirlen, path, pathlen); } if (namelen) { if (pathlen + dirlen) { pname[dirlen + pathlen] = '/'; ++pathlen; } strncpy(pname + dirlen + pathlen, name, namelen); } pname[pathlen + dirlen + namelen] = 0; basename = namelen ? pname + dirlen + pathlen : "/"; // Create things here //printmode(inode); //printuidgid(inode); if (S_ISREG(inode->mode)) { u32 size = inode->size; if (gid > DIR_GID) { // sirius: this is a special LG encoding of the size. // misusing gid field to encode the most significant byte of the size int lg = gid - DIR_GID; gid -= lg; lg = lg * 0x1000000; size += (lg); } do_file(base, inode->offset << 2, size, pname, basename, inode->mode); } else if (S_ISDIR(inode->mode)) { if (DIR_GID == 0) { DIR_GID = gid; } do_directory(base, inode->offset << 2, inode->size, pname, basename, inode->mode); } else if (S_ISLNK(inode->mode)) { do_symlink(base, inode->offset << 2, inode->size, pname, basename, inode->mode); } else if (S_ISFIFO(inode->mode)) { do_fifo(base, inode->offset << 2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else if (S_ISSOCK(inode->mode)) { do_socket(base, inode->offset << 2, inode->size, pname, basename, inode->mode); } else if (S_ISCHR(inode->mode)) { do_chrdev(base, inode->offset << 2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else if (S_ISBLK(inode->mode)) { do_blkdev(base, inode->offset << 2, inode->size, pname, basename, inode->mode, inode->uid, inode->gid); } else { do_unknown(base, inode->offset << 2, inode->size, pname, basename, inode->mode); } if (geteuid() == 0) { if (lchown(pname, inode->uid, gid) == -1) perror("cannot change owner or group"); } else if (opt_idsfile && path && path[0]) { char dfp[1024]; char *p; FILE *f; strcpy(dfp, pname); p = strrchr(dfp, '/'); if (!p) { fprintf(stderr, "could not find path in '%s'\n", pname); return; } strcpy(p + 1, opt_idsfile); f = fopen(dfp, "at"); if (!f) { perror(dfp); return; } fprintf(f, "%s,%u,%u,%08x\n", basename, inode->uid, inode->gid, inode->mode); fclose(f); } if (geteuid() == 0 || !opt_idsfile) { if (inode->mode & (S_ISGID | S_ISUID | S_ISVTX)) { if (0 != chmod(pname, inode->mode)) { perror("chmod"); return; } } } //printf("\n"); }