Exemple #1
0
static int refput(ushort index)
{
  if(!LoadOpis(index, CONSTANT_Utf8, NULL)) return(0);

  qfprintf(myFile, rfmt, index);
  return(utfstr(index, NULL));
}
Exemple #2
0
//----------------------------------------------------------------------
int32 gen_map_file(FILE *fp)
{
  static const char frm[] =
                      "Map format\n\n"
                      "<~W~idth:D:3:::> [72-%D], 0 - unlimited \n"
                      " Printing\n"
                      "<~A~ll:R>       Included constant types\n"
                      "<~U~nused  :R>>    <Utf~8~:C>\n"
                      " Sorting by<~C~lass:C>\n"
                      "<~T~ype:R><~R~eferences:C>\n"
                      "<U~n~sorted:R>><Na~m~eAndType :C>\n"
                      " Number in pool<Num~b~ers:C>\n"
                      "<~D~ecimal :R><~S~tring:C>>\n"
                      "<~H~ex:R>>\n\n"
                      "<~O~ut Utf8 string without encoding :C>\n"
                      "<~I~nclude loader problem messages  :C>>\n\n";

  static const struct {
    ushort  mask;
    ushort  skip;
    char    name[8];
    int     (*proc)(ushort index, const ConstOpis *);
    ushort  arg;
  }defr[MAX_CONSTANT_TYPE] = {
                     {0x01, 0, "Utf8   ", utfstr, 0},
                     {0x00, 0, "",        NULL, 0}, // unicode
                     {0x10, 4, "Integer", outnum, 3 + dt_dword},
                     {0x10, 4, "Float  ", outnum, 3 + dt_float},
                     {0x10, 8, "Long   ", outnum, 3 + dt_qword},
                     {0x10, 8, "Double ", outnum, 3 + dt_double},
                     {0x02, 2, "Class  ", outref, 1},
                     {0x20, 2, "String ", outref, 1},
                     {0x04, 4, "Fld_ref", outref, 3},
                     {0x04, 4, "Met_ref", outref, 3},
                     {0x04, 4, "Int_ref", outref, 3},
                     {0x08, 4, "nam&typ", outref, 2}
                   };

#define STR_MIN_RESERVED     32
  char   str[MAXSTR];
  uchar  tflag;
  int32  width, pos, numstr = 0;
  uint32 save_flags = idpflags;
  ushort curbit = 1;
  short  unus = 1, unsort = 1, hexnum = 0, typemask = 0x3F, encinc = 2;
  ConstOpis opis;
  register ushort i, j;
  static char lft_fmt[] = "%08lX %5u%c %s ";

  if(!(idpflags & IDF_ENCODING)) ++encinc;  // |= 1
  uFlag = decflag();  // Decimal OutValue
  width = 80;
  bufsize = pos = sizeof(str)-32;
  if(!AskUsingForm_c(frm, &width, &pos, &unus, &unsort,
                     &typemask, &hexnum, &encinc)) return(0);
  if(encinc & 2) unus = 0; // from error - all
  idpflags &= ~IDF_ENCODING;
  if(!(encinc & 1)) idpflags |= IDF_ENCODING;
#if (MAXSTR-STR_MIN_RESERVED) <= 72
#error
#endif
  no_prompt = 0;
  if(width < 72) {
    if(width) width = 72;
    else {
      no_prompt = 0;
set_max:
      width = sizeof(str)-STR_MIN_RESERVED;
    }
  } else if(width > (MAXSTR-STR_MIN_RESERVED)) goto set_max;
  if(!typemask) typemask = 0x3F;

  if(hexnum) {
    lft_fmt[7] = ind_fmt[5] = rfmt[17] = '4';
    lft_fmt[8] = ind_fmt[6] = rfmt[18] = 'X';
    curpos = 8 + 1 + 4 + 1 + 1 + 0 + 1;
  } else {
    lft_fmt[7] = ind_fmt[5] = rfmt[17] = '5';
    lft_fmt[8] = ind_fmt[6] = rfmt[18] = 'u';
    curpos = 8 + 1 + 5 + 1 + 1 + 0 + 1;
  }
  if(unsort) {
    curpos += 7;
    curbit = typemask;
  }
  maxpos  = width;
  bufbeg  = str;
  myFile  = fp;

  do {
    while(!(typemask & curbit)) curbit <<= 1;

    for(tflag = (uchar)unsort, pos = 10, i = 1; i <= curClass.maxCPindex; i++) {
      if(!LoadOpis(i, 0, &opis) || opis.type == CONSTANT_Unicode)
                                                        DESTROYED("map::CP");
      j = opis.type - 1;
DEB_ASSERT((j >= MAX_CONSTANT_TYPE), "map:type");
      if((!unus || !(opis.flag & _REF)) && (curbit & defr[j].mask)) {
        if(!numstr) {
          static const char fmh[]= "This file generated by IDA";

          for(int k = (maxpos - sizeof(fmh)) / 2; k; k--) qfputc(' ', fp);
          char dname[MAXSTR];
          if(ConstantNode.supstr(CNS_SOURCE, dname, sizeof(dname)) < 0)
            DESTROYED("map:srcname");
          qfprintf(fp, "%s\n\n"
                       "   Constant Pool for \"%s\"\n\n"
                       " offset  #(%s)\n",
                   fmh, dname, hexnum ? "hex" : "dec");
          numstr =  5;
        }
        if(!tflag) {
          qfprintf(fp, "\n-----CONSTANT-%s-----\n",
                   (defr[j].arg < 3) ? defr[j].name :
                                       ((defr[j].arg == 3) ?
                                          "(program references)" :
                                          "(numeric values)"));
          ++tflag;
          numstr += 2;
        }
        qfprintf(fp, lft_fmt, pos, i, (opis.flag & _REF) ? ' ' : '*',
                       (unsort || defr[j].arg >= 3) ? defr[j].name : "");
        {
          register int n = defr[j].proc(defr[j].arg ? defr[j].arg : i, &opis);
          if(n <= 0) goto do_eof;
          numstr += n;
        }
        if(unus && unsort && opis.type >= CONSTANT_Class) {
          numstr += refput(opis._name);
          if(opis.type > CONSTANT_String) {
            if(opis.type == CONSTANT_NameAndType)
              numstr += refput(opis._class);
            else {
              numstr += refput(opis._subnam);
              numstr += refput(opis._dscr);
            }
          }
        }
        if(feof(fp) || ferror(fp)) goto do_eof;
      }

      ++pos;
      switch(j = defr[j].skip) {
        case 0: // Utf8 / Unicode
          pos += opis._Ssize + 2;
          break;
        case 8: // Long / Double
DEB_ASSERT((i == curClass.maxCPindex), "map:CPend");
          ++i;
        default:
          pos += j;
          break;
      }
    }
  }while((typemask ^= curbit) != 0);

  if(numstr) {  // if error print before - header problems!
    qfprintf(fp, "\nEnd of map\n");
    numstr += 2;

    if((encinc & 2) && curClass.msgNode) {
      qfprintf(fp, "\nLoader problem messages\n\n");
      int32 slen = print_loader_messages(str, NULL);
      if(slen == -1) goto do_eof;
      numstr += slen + 5;
      qfprintf(fp, "\nEnd of messages\n");
    }
    if(feof(fp) || ferror(fp)) {
do_eof:
      numstr = EOF;
    }
  }
  myFile = NULL;
  idpflags = save_flags;
  return(numstr);
}
Exemple #3
0
static int ConstLoad(CIC_param ctype)
{
  ConstOpis cntopis;
  uchar     i;

  cmd.Op1.type = o_cpool;
//  cmd.Op1.ref = 0;

  if ( !cmd.Op1.cp_ind ) goto dmpchk;  //NULL Ptr

  if ( !LoadOpis(cmd.Op1.cp_ind, 0, &cntopis) ) goto dmpchk;

#ifdef __BORLANDC__
#if ( offsetof(ConstOpis,flag) != (offsetof(ConstOpis,type) + sizeof(uchar) ) \
     || (sizeof(cntopis.type) != sizeof(uchar))      \
     || (sizeof(cntopis.flag) != sizeof(uchar))      \
     || (sizeof(cmd.Op1.cp_type) < (2*sizeof(uchar))) \
     || (sizeof(ushort) != sizeof(cmd.Op1.cp_type)))
#error
#endif
#endif
  cmd.Op1.cp_type = *((ushort *)&cntopis.type);
  i = cntopis.type;

  switch ( ctype ) {
    case C_Class:
      if ( i != CONSTANT_Class ) break;
      //PASS THRU
    case C_4byte: // ldc/ldcw
      switch ( i ) {
        case CONSTANT_Class:
          if ( !(cntopis.flag & HAS_CLSNAME) ) goto wrnret;
          cmd.Op1.addr  = 0x10001ul * (ushort)fmt_fullname;
loadref1:
          cmd.xtrn_ip   = cntopis.ref_ip;
          //PASS THRU
        case CONSTANT_Integer:
        case CONSTANT_Float:
        case CONSTANT_String:
          cmd.Op1.value = cntopis.value;  // for string index to Utf8
          return(1);                      // or TWO index for other
        default:
          break;
      }
      break;

    case C_8byte:
      if ( i == CONSTANT_Long || i == CONSTANT_Double ) goto load2;
      break;

    case C_Field:
      if ( i != CONSTANT_Fieldref ) break;
      if ( (cntopis.flag & NORM_FIELD) != NORM_FIELD ) goto wrnret;
loadref2:
      cmd.xtrn_ip   = cntopis.ref_ip;
load2:
      cmd.Op1.addr  = cntopis.value2;
      cmd.Op1.value = cntopis.value;     // for string index to Utf8
#ifdef __EA64__
      cmd.Op1.value = make_ulonglong(int32(cmd.Op1.value), uint32(cmd.Op1.addr));
#endif
      return 1;

    case C_Interface:
      if ( i == CONSTANT_InterfaceMethodref ) goto methodchk;
      break;
    case C_Method:
      if ( i != CONSTANT_Methodref ) break;
methodchk:
      if ( (cntopis.flag & NORM_METOD) == NORM_METOD ) goto loadref2; //load 3 ind. & xtrn_ref
      goto wrnret;

    case C_Type:
      if ( i != CONSTANT_Class ) break;
      if ( !(cntopis.flag & HAS_TYPEDSCR) ) goto wrnret;
      cmd.Op1.addr = ((uint32)fmt_dscr << 16) | (ushort)fmt_classname;
      goto loadref1; //load 1 ind.

    case C_TypeName:
      if ( i != CONSTANT_Class ) break;
      if ( !(cntopis.flag & (HAS_TYPEDSCR | HAS_CLSNAME)) ) goto wrnret;
      cmd.Op1.addr = ((uint32)fmt_cast << 16) | (ushort)
                                            ((cntopis.flag & HAS_CLSNAME) ?
                                               fmt_fullname : fmt_classname);
      goto loadref1; //load 1 ind.

    default:
      warning("Illegal CIC call (%x)\n", ctype);
      return(0);
  }
dmpchk:
  if ( !debugmode) return(0 );
  ++cmd.Op1.ref;
wrnret:
  ++cmd.Op1.ref;
  cmd.Op1.addr_shorts.low = cmd.Op1.cp_ind;    // for dmp out
  return(1);
}
Exemple #4
0
//----------------------------------------------------------------------
int upgrade_db_format(int ver, netnode constnode)
{
  if(askyn_c(1, "AUTOHIDE REGISTRY\nHIDECANCEL\n"
                "The database has an old java data format.\n"
                "Do you want to upgrade it?") <= 0) qexit(1);

  switch ( ver ) {
    default:
      INTERNAL("upgrade::ver");
    case IDP_JDK12:
      break;
  }

  // change format: jdk-version
  if ( curClass.MinVers > 0x8000u ) {
badbase:
    return(0);
  }

  curClass.MajVers = JDK_MIN_MAJOR;
  if ( curClass.MinVers >= 0x8000 ) {
    curClass.MinVers &= ~0;
    ++curClass.MajVers;
    curClass.JDKsubver = 2;
  } else if ( curClass.MinVers >= JDK_1_1_MINOR ) ++curClass.JDKsubver;

// change format: This
#ifdef __BORLANDC__
#if offsetof(ClassInfo, This.Ref)  != offsetof(ClassInfo, This.Name) || \
    offsetof(ClassInfo, This.Dscr) != offsetof(ClassInfo, This.Name) + 2
#error
#endif
#endif
   curClass.This.Ref = (curClass.This.Ref << 16) | curClass.This.Dscr;
   if ( !curClass.This.Name ) goto badbase;

// change format: Super
#ifdef __BORLANDC__
#if offsetof(ClassInfo, super.Ref)  != offsetof(ClassInfo, super.Name) || \
    offsetof(ClassInfo, super.Dscr) != offsetof(ClassInfo, super.Name) + 2
#error
#endif
#endif
  switch ( curClass.super.Name ) {
    case 0:       // absent
      curClass.super.Ref &= 0;
      break;
    case 0xFFFF:  // bad index
      ++curClass.super.Name;
      break;
    default:      // reverse order
      curClass.super.Ref = (curClass.super.Ref << 16) | curClass.super.Dscr;
      break;
  }

// validate: impNode
  if ( curClass.impNode && !netnode(curClass.impNode).altval(0) ) goto badbase;

// change variable 'errload' in previous version
  if ( curClass.maxSMsize ) {
    curClass.extflg |= XFL_C_ERRLOAD;
    curClass.maxSMsize &= 0;
  }

// set segments type type for special segments
  segment_t *S;
  if ( (S = getseg(curClass.startEA)) == NULL ) goto badbase;
  S->set_hidden_segtype(true);
  S->update();
  if ( curClass.xtrnCnt ) {
    if ( (S = getseg(curClass.xtrnEA)) == NULL ) goto badbase;
    S->set_hidden_segtype(true);
    S->update();
  }

  curClass.extflg |= XFL_C_DONE;  // do not repeat datalabel destroyer :)
// change: method/fields format
#define SGEXPSZ (sizeof(SegInfo) - offsetof(SegInfo, varNode))
#define FMEXPSZ (sizeof(_FMid_) - offsetof(_FMid_, _UNUSED_ALING))
#define FLEXPSZ (sizeof(FieldInfo) - offsetof(FieldInfo, annNodes))
  uval_t  oldsize = sizeof(SegInfo) - FMEXPSZ - SGEXPSZ;

  for(int pos=-(int)curClass.MethodCnt; pos<=(int)curClass.FieldCnt; pos++) {
    union {
      SegInfo   s;
      FieldInfo f;
      _FMid_    id;
      uchar     _space[qmax(sizeof(SegInfo), sizeof(FieldInfo)) + 1];
    }u;

    if ( !pos ) {  // class node
      oldsize += (sizeof(FieldInfo) - FLEXPSZ) - (sizeof(SegInfo) - SGEXPSZ);
      continue;
    }

    if ( ClassNode.supval(pos, &u, sizeof(u)) != oldsize ) goto badbase;

    memmove((uchar *)&u.id + sizeof(u.id), &u.id._UNUSED_ALING,
            (size_t)oldsize - offsetof(_FMid_, _UNUSED_ALING));
    u.id._UNUSED_ALING = 0;
    u.id.utsign        = 0;

    if ( u.id.extflg & ~EFL__MASK ) goto badbase;
    u.id.extflg &= (EFL_NAMETYPE);

    if ( pos > 0 ) { // fields
      memset(&u.f.annNodes, 0, sizeof(u.f)-offsetof(FieldInfo, annNodes));
      ClassNode.supset(pos, &u.f, sizeof(u.f));
      continue;
    }

    // segments
    memset(&u.s.varNode, 0, sizeof(u.s) - offsetof(SegInfo, varNode));
    if ( u.s.thrNode && !netnode(u.s.thrNode).altval(0) ) {
      netnode(u.s.thrNode).kill();  // empty node (old format)
      u.s.thrNode = 0;
    }

    // have locvars?
    if ( u.s.DataSize ) {
      if ( (S = getseg(u.s.DataBase)) == NULL ) goto badbase;
      S->type = SEG_BSS;
      S->set_hidden_segtype(true);
      S->update();
    }

    // change: Exception format
    if ( u.s.excNode ) {
      register ushort i, j;
      netnode         enode(u.s.excNode);

      if ( (j = (ushort)enode.altval(0)) == 0 ) goto badbase;
      ea_t ea = u.s.startEA + u.s.CodeSize;
      i = 1;
      do {
        Exception exc;

        if ( enode.supval(i, &exc, sizeof(exc)) != sizeof(exc) ) goto badbase;

#ifdef __BORLANDC__
#if offsetof(Exception, filter.Ref)  != offsetof(Exception, filter.Name) || \
    offsetof(Exception, filter.Dscr) != offsetof(Exception, filter.Name) + 2
#error
#endif
#endif
        if ( !exc.filter.Name != !exc.filter.Dscr ) goto badbase;
        exc.filter.Ref = (exc.filter.Ref << 16) | exc.filter.Dscr; // was reverse order
        if ( exc.filter.Name == 0xFFFF ) ++exc.filter.Name;
        enode.supset(i, &exc, sizeof(exc));
        set_exception_xref(&u.s, exc, ea);
      }while ( ++i <= j );
    }
    ClassNode.supset(pos, &u.s, sizeof(u.s));
    //rename local variables (for references)
    if ( u.s.DataSize ) {
      int   i = u.s.DataSize;
      ea_t  ea = u.s.DataBase + i;
      do {
        char  str[MAXNAMELEN];
        qsnprintf(str, sizeof(str), "met%03u_slot%03u", u.s.id.Number, --i);
        --ea;
        if ( do_name_anyway(ea, str)) make_name_auto(ea );
        else hide_name(ea);
      }while ( i );
      coagulate_unused_data(&u.s);
    }
  } // for

//change format of string presentation in constant pool
  for(int pos = 0; (ushort)pos <= curClass.maxCPindex; pos++) {
    ConstOpis co;

    if ( constnode.supval(pos, &co, sizeof(co)) != sizeof(co) ) goto badbase;
    switch ( co.type ) {
      default:
        continue;

      case CONSTANT_Unicode:
        error("Base contain CONSTANT_Unicode, but it is removed from "
              "the standard in 1996 year and never normal loaded in IDA");

      case CONSTANT_Utf8:
        break;
    }
    uint32 v, n, i = pos << 16;
    if(   ((n = (uint32)constnode.altval(i)) & UPG12_BADMASK)
       || (v = n & ~UPG12_CLRMASK) == 0) goto badbase;
    if ( n & UPG12_EXTMASK ) v |= UPG12_EXTSET;
    if ( (n = (ushort)v) != 0 ) {
      register uchar *po = (uchar*)append_tmp_buffer(v);
      n *= sizeof(ushort);
      uint32 pos = 0;
      do {
        uint32 sz = n - pos;
        if ( sz > MAXSPECSIZE ) sz = MAXSPECSIZE;
        if ( constnode.supval(++i, &po[pos], sz) != sz ) goto badbase;
        constnode.supdel(i);
        pos += sz;
      }while ( pos < n );
      constnode.setblob(po, n, i & ~0xFFFF, BLOB_TAG);
      if ( !(v & UPG12_EXTSET) ) do {
#ifdef __BORLANDC__
#if ( sizeof(ushort) % 2) || (MAXSPECSIZE % 2 )
#error
#endif
#endif
        ushort cw = *(ushort *)&po[pos];
        if ( cw >= CHP_MAX ) {
          if ( !javaIdent(cw) ) goto extchar;
        } else if ( (uchar)cw <= CHP_MIN ) {
extchar:
          v |= UPG12_EXTSET;
          break;
        }
      }while ( (pos -= sizeof(ushort)) != 0 );
      v = upgrade_ResW(v);
    }
    constnode.altset(i, v);
    co._Sopstr = v; // my be not needed? (next also)
    constnode.supset(pos, &co, sizeof(co));
  }

// rename 'import' variables for refernces
  for(unsigned ip = 1; (ushort)ip <= curClass.xtrnCnt; ip++) {
    ConstOpis co;
    {
      register unsigned j;
      if(   (j = (unsigned)XtrnNode.altval(ip)) == 0
         || !LoadOpis((ushort)j, 0, &co)) goto badbase;
    }
    switch ( co.type ) {
      default:
        goto badbase;

      case CONSTANT_Class:
        if ( !(co.flag & HAS_CLSNAME) ) continue;
        break;
      case CONSTANT_InterfaceMethodref:
      case CONSTANT_Methodref:
        if ( (co.flag & NORM_METOD) != NORM_METOD ) continue;
        break;
      case CONSTANT_Fieldref:
        if ( (co.flag & NORM_FIELD) != NORM_FIELD ) continue;
        break;
    }
    make_new_name(co._name, co._subnam, co.type != CONSTANT_Class, ip);
  }

  if ( curClass.This.Dscr )
    make_new_name(curClass.This.Name, 0, (uchar)-1, (unsigned)curClass.startEA);

  return(_TO_VERSION);
}