Пример #1
0
//----------------------------------------------------------------------
//
//      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 );
}
Пример #2
0
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);
   }
}
Пример #3
0
//----------------------------------------------------------------------
//
//      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 );
}
Пример #4
0
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);
}
Пример #5
0
//----------------------------------------------------------------------
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);
        }
    }
}
Пример #6
0
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));
  }
}
Пример #7
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::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);
}
Пример #8
0
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");
}
Пример #9
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);
}
Пример #10
0
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");
}