1 26 package net.sf.javaguard.classfile; 27 28 import java.io.*; 29 import java.util.*; 30 import net.sf.javaguard.Cl; 31 import net.sf.javaguard.KeyValue; 32 import net.sf.javaguard.ClassTree; 33 import net.sf.javaguard.log.FileLogger; 34 import net.sf.javaguard.Tools; 35 36 44 public class ClassFile implements ClassConstants { 45 private static final String [] DANGEROUS_CLASS_SIMPLENAME_DESCRIPTOR_ARRAY = { 47 "forName(Ljava/lang/String;)Ljava/lang/Class;", 48 "getDeclaredField(Ljava/lang/String;)Ljava/lang/reflect/Field;", 49 "getField(Ljava/lang/String;)Ljava/lang/reflect/Field;", 50 "getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", 51 "getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;" 52 }; 53 private static final String LOG_DANGER_CLASS_PRE = " Your class "; 54 private static final String LOG_DANGER_CLASS_MID = " calls the java/lang/Class method "; 55 private static final String [] DANGEROUS_CLASSLOADER_SIMPLENAME_DESCRIPTOR_ARRAY = { 56 "defineClass(Ljava/lang/String;[BII)Ljava/lang/Class;", 57 "findLoadedClass(Ljava/lang/String;)Ljava/lang/Class;", 58 "findSystemClass(Ljava/lang/String;)Ljava/lang/Class;", 59 "loadClass(Ljava/lang/String;)Ljava/lang/Class;", 60 "loadClass(Ljava/lang/String;Z)Ljava/lang/Class;" 61 }; 62 private static final String LOG_DANGER_CLASSLOADER_PRE = " Your class "; 63 private static final String LOG_DANGER_CLASSLOADER_MID = " calls the java/lang/ClassLoader method "; 64 65 66 67 private ClassTree classTree; 68 69 private int magic; 70 71 private int minorVersion; 72 73 private int majorVersion; 74 75 private ConstantPool constantPool; 76 77 private int accessFlags; 78 80 private int thisClassIndex; 81 83 private int superClassIndex; 84 85 86 private int interfacesCount; 87 88 private int interfaces[]; 89 90 private int fieldsCount; 91 92 private FieldInfo fieldInfo[]; 93 94 private int methodsCount; 95 96 private MethodInfo methodInfo[]; 97 98 private int attributesCount; 99 100 private AttrInfo attributesInfo[]; 101 102 103 104 105 112 public static ClassFile create(ClassTree classTree, DataInput din) 113 throws IOException { 114 if (null == din) throw new IOException("No input stream was provided."); 115 ClassFile cf = new ClassFile(classTree); 116 cf.read(din); 117 return cf; 118 } 119 120 121 122 123 126 private ClassFile(ClassTree classTree) { 127 this.classTree = classTree; 128 } 129 130 131 132 133 136 private ClassTree getClassTree() { 137 return classTree; 138 } 139 140 141 142 143 147 private void read(DataInput din) 148 throws IOException { 149 setMagic(din.readInt()); 151 setMinorVersion(din.readUnsignedShort()); 152 setMajorVersion(din.readUnsignedShort()); 153 154 if (getMagic() != MAGIC) { 156 throw new IOException("Invalid magic number in class file."); 157 } 158 if (getMajorVersion() > MAJOR_VERSION || 159 (MAJOR_VERSION == getMajorVersion() && getMinorVersion() > MINOR_VERSION_MAX)) { 160 throw new IOException("Incompatible version number for class file format: " 161 + getMajorVersion() + " / " + getMinorVersion()); 162 } 163 164 165 int u2constantPoolCount = din.readUnsignedShort(); 166 CpInfo[] cpInfo = new CpInfo[u2constantPoolCount]; 167 for (int i = 1; i < u2constantPoolCount; i++) { 170 cpInfo[i] = CpInfo.create(din); 171 if ((cpInfo[i] instanceof LongCpInfo) || 172 (cpInfo[i] instanceof DoubleCpInfo)) { 173 i++; 174 } 175 } 176 constantPool = new ConstantPool(this, cpInfo); 177 178 setAccessFlags(din.readUnsignedShort()); 179 setClassIndex(din.readUnsignedShort()); 180 setSuperClassIndex(din.readUnsignedShort()); 181 setInterfacesCount(din.readUnsignedShort()); 183 int[] u2interfaces = new int[getInterfacesCount()]; 184 for (int i = 0; i < getInterfacesCount(); i++) { 185 u2interfaces[i] = din.readUnsignedShort(); 186 } 187 setInterfaces(u2interfaces); 188 setFieldsCount(din.readUnsignedShort()); 190 FieldInfo[] fields = new FieldInfo[getFieldsCount()]; 191 for (int i = 0; i < getFieldsCount(); i++) { 192 fields[i] = FieldInfo.create(din, this); 193 } 194 setFieldInfo(fields); 195 setMethodsCount(din.readUnsignedShort()); 197 MethodInfo[] methods = new MethodInfo[getMethodsCount()]; 198 for (int i = 0; i < getMethodsCount(); i++) { 199 methods[i] = MethodInfo.create(din, this); 200 } 201 setMethodInfo(methods); 202 setAttributesCount(din.readUnsignedShort()); 204 AttrInfo[] attrs = new AttrInfo[getAttributesCount()]; 205 for (int i = 0; i < getAttributesCount(); i++) { 206 attrs[i] = AttrInfo.create(din, this); 207 } 208 setAttributeInfo(attrs); 209 } 210 211 212 213 214 218 private void setMagic(int num) { 219 this.magic = num; 220 } 221 222 223 227 private int getMagic() { 228 return magic; 229 } 230 231 232 233 234 238 private void setMajorVersion(int ver) { 239 majorVersion = ver; 240 } 241 242 243 247 private int getMajorVersion() { 248 return majorVersion; 249 } 250 251 252 253 254 258 private void setMinorVersion(int ver) { 259 minorVersion = ver; 260 } 261 262 263 267 private int getMinorVersion() { 268 return minorVersion; 269 } 270 271 272 273 274 278 private void setAccessFlags(int flags) { 279 accessFlags = flags; 280 } 281 282 283 287 private int getAccessFlags() { 288 return accessFlags; 289 } 290 291 292 293 294 299 private void setClassIndex(int index) { 300 thisClassIndex = index; 301 } 302 303 304 309 private int getClassIndex() { 310 return thisClassIndex; 311 } 312 313 314 315 316 321 private void setSuperClassIndex(int index) { 322 superClassIndex = index; 323 } 324 325 326 330 private int getSuperClassIndex() { 331 return superClassIndex; 332 } 333 334 335 336 337 341 private void setInterfacesCount(int num) { 342 interfacesCount = num; 343 } 344 345 346 350 private int getInterfacesCount() { 351 return interfacesCount; 352 } 353 354 355 356 357 361 private void setInterfaces(int[] interfaces) { 362 this.interfaces = interfaces; 363 } 364 365 366 371 private int[] getInterfaces() { 372 return interfaces; 373 } 374 375 376 381 private int getInterface(int pos) { 382 return interfaces[pos]; 383 } 384 385 386 389 public String [] getInterfaceNames() { 390 String [] names = new String [getInterfacesCount()]; 391 for (int i=0; i<getInterfacesCount(); i++) { 392 names[i] = toName(getInterface(i)); 393 } 394 return names; 395 } 396 397 398 399 400 404 private void setFieldsCount(int num) { 405 fieldsCount = num; 406 } 407 408 409 412 public int getFieldsCount() { 413 return fieldsCount; 414 } 415 416 417 418 419 423 private void setFieldInfo(FieldInfo[] fields) { 424 this.fieldInfo = fields; 425 } 426 427 428 432 private FieldInfo[] getFieldInfo() { 433 return fieldInfo; 434 } 435 436 437 442 public FieldInfo getFieldInfo(int pos) { 443 return fieldInfo[pos]; 444 } 445 446 447 448 449 453 private void setMethodsCount(int num) { 454 methodsCount = num; 455 } 456 457 458 461 public int getMethodsCount() { 462 return methodsCount; 463 } 464 465 466 467 468 472 private void setMethodInfo(MethodInfo[] methods) { 473 this.methodInfo = methods; 474 } 475 476 477 481 private MethodInfo[] getMethodInfo() { 482 return methodInfo; 483 } 484 485 486 491 public MethodInfo getMethodInfo(int pos) { 492 return methodInfo[pos]; 493 } 494 495 496 497 498 502 private void setAttributesCount(int num) { 503 attributesCount = num; 504 } 505 506 507 511 private int getAttributesCount() { 512 return attributesCount; 513 } 514 515 516 517 518 522 private void setAttributeInfo(AttrInfo[] attrs) { 523 this.attributesInfo = attrs; 524 } 525 526 527 531 private AttrInfo[] getAttributeInfo() { 532 return attributesInfo; 533 } 534 535 536 542 private AttrInfo getAttributeInfo(int pos) { 543 return attributesInfo[pos]; 544 } 545 546 547 553 private void setAttributeInfo(int pos, AttrInfo attrInfo) { 554 attributesInfo[pos] = attrInfo; 555 } 556 557 558 559 560 563 public String getName() { 564 return toName(getClassIndex()); 565 } 566 567 568 569 570 573 public String getSuper() { 574 return (0 == getSuperClassIndex()) ? null : toName(getSuperClassIndex()); 576 } 577 578 579 580 581 586 protected String toName(int index) 587 throws IllegalStateException { 588 CpInfo classEntry = getCpEntry(index); 589 if (classEntry instanceof ClassCpInfo) { 590 CpInfo nameEntry = getCpEntry( ((ClassCpInfo) classEntry).getClassNameIndex()); 591 if (nameEntry instanceof Utf8CpInfo) { 592 return ((Utf8CpInfo) nameEntry).getString(); 593 } 594 } 595 throw new IllegalStateException ("Inconsistent Constant Pool in class file."); 596 } 597 598 599 600 601 605 protected CpInfo getCpEntry(int index) { 606 return constantPool.getCpEntry(index); 607 } 608 609 610 611 612 616 public String [] dangerousMethods() { 617 Vector warningVec = new Vector(); 618 619 for (Iterator iter = constantPool.iterator(); iter.hasNext(); ) { 622 Object obj = iter.next(); 623 if (obj instanceof MethodrefCpInfo) { 624 MethodrefCpInfo entry = (MethodrefCpInfo) obj; 626 ClassCpInfo classEntry = (ClassCpInfo) getCpEntry(entry.getClassIndex()); 627 String className = ((Utf8CpInfo) getCpEntry(classEntry.getClassNameIndex())).getString(); 628 NameAndTypeCpInfo ntEntry = (NameAndTypeCpInfo) getCpEntry(entry.getNameAndTypeIndex()); 629 String name = ((Utf8CpInfo) getCpEntry(ntEntry.getNameIndex())).getString(); 630 String descriptor = ((Utf8CpInfo) getCpEntry(ntEntry.getDescriptorIndex())).getString(); 631 632 if (className.equals("java/lang/Class") && 634 Tools.isInArray(name + descriptor, DANGEROUS_CLASS_SIMPLENAME_DESCRIPTOR_ARRAY)) { 635 warningVec.addElement(LOG_DANGER_CLASS_PRE + getName() + LOG_DANGER_CLASS_MID + name + descriptor); 636 } 637 else if (Tools.isInArray(name + descriptor, DANGEROUS_CLASSLOADER_SIMPLENAME_DESCRIPTOR_ARRAY)) { 638 warningVec.addElement(LOG_DANGER_CLASSLOADER_PRE + getName() + LOG_DANGER_CLASSLOADER_MID + name + descriptor); 639 } 640 } 641 } 642 643 String [] warnings = new String [warningVec.size()]; 645 for (int i = 0; i < warnings.length; i++) { 646 warnings[i] = (String )warningVec.elementAt(i); 647 } 648 return warnings; 649 } 650 651 652 653 654 private static boolean hasHeader = false; 655 656 public static void resetDangerHeader() { 657 hasHeader = false; 658 } 659 660 public void logDangerousMethods() { 661 String [] warnings = dangerousMethods(); 663 if (warnings != null && warnings.length > 0) { 664 FileLogger logfile = FileLogger.getInstance(); 665 if (!hasHeader) { 666 logfile.addMethodWarning("#"); 667 logfile.addMethodWarning("# WARNING - Methods are called which may unavoidably break in obfuscated version at runtime."); 668 logfile.addMethodWarning("# Please review your source code to ensure that the dangerous methods are not intended"); 669 logfile.addMethodWarning("# to act on classes which are within the obfuscated Jar file."); 670 logfile.addMethodWarning("#"); 671 hasHeader = true; 672 } 673 for (int i = 0; i < warnings.length; i++) { 674 logfile.addMethodWarning("# " + warnings[i]); 675 } 676 } 677 } 678 679 680 684 public void markUtf8Refs(ConstantPool pool) 685 throws IllegalStateException { 686 try { 687 for (int i = 0; i < getFieldsCount(); i++) { 689 getFieldInfo(i).markUtf8Refs(pool); 690 } 691 for (int i = 0; i < getMethodsCount(); i++) { 692 getMethodInfo(i).markUtf8Refs(pool); } 694 for (int i = 0; i < getAttributesCount(); i++) { 695 getAttributeInfo(i).markUtf8Refs(pool); } 697 698 for (Iterator iter = pool.iterator(); iter.hasNext(); ) { 700 Object obj = iter.next(); 701 if (obj instanceof NameAndTypeCpInfo || 702 obj instanceof ClassCpInfo || 703 obj instanceof StringCpInfo) { 704 ((CpInfo) obj).markUtf8Refs(pool); 705 } 706 } 707 } catch (ArrayIndexOutOfBoundsException e) { 708 throw new IllegalStateException ("Inconsistent reference to constant pool."); 709 } 710 } 711 712 713 714 715 719 public void markNTRefs(ConstantPool pool) 720 throws IllegalStateException { 721 try { 722 for (Iterator iter = pool.iterator(); iter.hasNext(); ) { 724 Object obj = iter.next(); 725 if (obj instanceof RefCpInfo) { 726 ((CpInfo) obj).markNTRefs(pool); 727 } 728 } 729 } catch (ArrayIndexOutOfBoundsException e) { 730 throw new IllegalStateException ("Inconsistent reference to constant pool."); 731 } 732 } 733 734 735 736 737 741 public void trimAttrsExcept(String [] extraAttrs) { 742 String [] keepAttrs = REQUIRED_ATTRS; 744 if (extraAttrs != null && extraAttrs.length > 0) { 745 String [] tmp = new String [keepAttrs.length + extraAttrs.length]; 746 System.arraycopy(keepAttrs, 0, tmp, 0, keepAttrs.length); 747 System.arraycopy(extraAttrs, 0, tmp, keepAttrs.length, extraAttrs.length); 748 keepAttrs = tmp; 749 } 750 751 for (int i = 0; i < getFieldsCount(); i++) { 753 getFieldInfo(i).trimAttrsExcept(keepAttrs); 754 } 755 for (int i = 0; i < getMethodsCount(); i++) { 756 getMethodInfo(i).trimAttrsExcept(keepAttrs); 757 } 758 for (int i = 0; i < getAttributesCount(); i++) { 759 if (Tools.isInArray(getAttributeInfo(i).getAttrName(), keepAttrs)) { 760 getAttributeInfo(i).trimAttrsExcept(keepAttrs); 761 } else { 762 setAttributeInfo(i, null); 763 } 764 } 765 766 AttrInfo[] left = new AttrInfo[getAttributesCount()]; 768 int j = 0; 769 for (int i = 0; i < getAttributesCount(); i++) { 770 if (null != getAttributeInfo(i)) { 771 left[j++] = getAttributeInfo(i); 772 } 773 } 774 AttrInfo[] attributes = new AttrInfo[j]; 775 System.arraycopy(left, 0, attributes, 0, j); 776 setAttributesCount(j); 777 setAttributeInfo(attributes); 778 779 constantPool.updateRefCount(); 781 } 782 783 784 785 786 789 public void trimAttrs() { 790 trimAttrsExcept(null); 791 } 792 793 794 797 public void remap(NameMapper nm) { 798 String [] attrs = nm.getAttrsToKeep(); 800 if (attrs.length > 0) { 801 trimAttrsExcept(attrs); 802 } else { 803 trimAttrs(); 804 } 805 806 String thisClassName = ((Utf8CpInfo)getCpEntry(((ClassCpInfo)getCpEntry(getClassIndex())).getClassNameIndex())).getString(); 809 810 for (int i = 0; i < getAttributesCount(); i++) { 812 AttrInfo attrInfo = getAttributeInfo(i); 813 if (attrInfo instanceof InnerClassesAttrInfo) { 814 InnerClassesInfo[] info = ((InnerClassesAttrInfo) attrInfo).getInnerClasses(); 816 for (int j = 0; j < info.length; j++) { 817 CpInfo cpInfo = getCpEntry(info[j].getInnerNameIndex()); 819 if (cpInfo instanceof Utf8CpInfo) { 820 Utf8CpInfo utf = (Utf8CpInfo) cpInfo; 822 String origClass = utf.getString(); 823 824 if (!origClass.equals("")) { 826 ClassCpInfo innerClassInfo = (ClassCpInfo) getCpEntry(info[j].getInnerClassInfoIndex()); 828 String innerClassName = ((Utf8CpInfo) getCpEntry(innerClassInfo.getClassNameIndex())).getString(); 829 830 String remapClass = nm.mapClass(innerClassName); 832 remapClass = remapClass.substring(remapClass.lastIndexOf('$') + 1); 833 int remapIndex = constantPool.remapUtf8To(remapClass, info[j].getInnerNameIndex()); 834 info[j].setInnerNameIndex(remapIndex); 835 } 836 } 837 } 838 } 839 } 840 841 for (int i = 0; i < getMethodsCount(); i++) { 844 for (int j = 0; j < getMethodInfo(i).getAttributesLength(); j++) { 845 AttrInfo attrInfo = getMethodInfo(i).getAttribute(j); 846 if (attrInfo instanceof CodeAttrInfo) { 847 CodeAttrInfo codeAttrInfo = (CodeAttrInfo)attrInfo; 848 for (int k = 0; k < codeAttrInfo.getAttributesLength(); k++) { 849 AttrInfo innerAttrInfo = codeAttrInfo.getAttributes()[k]; 850 if (innerAttrInfo instanceof LocalVariableTableAttrInfo) { 851 LocalVariableTableAttrInfo lvtAttrInfo = (LocalVariableTableAttrInfo)innerAttrInfo; 852 LocalVariableInfo[] lvts = lvtAttrInfo.getLocalVariableTable(); 853 for (int m = 0; m < lvts.length; m++) { 854 Utf8CpInfo nameUtf = (Utf8CpInfo)getCpEntry(lvts[m].getNameIndex()); 856 String remapName = nm.mapField(thisClassName, nameUtf.getString()); 857 if (null == remapName) { 859 remapName = nameUtf.getString(); 860 } 861 lvts[m].setNameIndex(constantPool.remapUtf8To(remapName, lvts[m].getNameIndex())); 862 863 Utf8CpInfo descUtf = (Utf8CpInfo)getCpEntry(lvts[m].getDescriptorIndex()); 865 String remapDesc = nm.mapDescriptor(descUtf.getString()); 866 lvts[m].setDescriptorIndex(constantPool.remapUtf8To(remapDesc, lvts[m].getDescriptorIndex())); 867 } 868 } 869 } 870 } 871 } 872 } 873 874 for (int i = 0; i < getFieldsCount(); i++) { 876 FieldInfo field = getFieldInfo(i); 878 if (!field.isSynthetic()) { 879 Utf8CpInfo nameUtf = (Utf8CpInfo) getCpEntry(field.getNameIndex()); 880 String remapName = nm.mapField(thisClassName, nameUtf.getString()); 881 if (null == remapName) { 883 remapName = nameUtf.getString(); 884 } 885 field.setNameIndex(constantPool.remapUtf8To(remapName, field.getNameIndex())); 886 } 887 888 Utf8CpInfo descUtf = (Utf8CpInfo)getCpEntry(field.getDescriptorIndex()); 890 String remapDesc = nm.mapDescriptor(descUtf.getString()); 891 field.setDescriptorIndex(constantPool.remapUtf8To(remapDesc, field.getDescriptorIndex())); 892 } 893 for (int i = 0; i < getMethodsCount(); i++) { 894 MethodInfo method = getMethodInfo(i); 896 Utf8CpInfo descUtf = (Utf8CpInfo)getCpEntry(method.getDescriptorIndex()); 897 if (!method.isSynthetic()) { 898 Utf8CpInfo nameUtf = (Utf8CpInfo)getCpEntry(method.getNameIndex()); 899 String remapName = nm.mapMethod(thisClassName, nameUtf.getString(), descUtf.getString()); 900 if (null == remapName) { 902 remapName = nameUtf.getString(); 903 } 904 method.setNameIndex(constantPool.remapUtf8To(remapName, method.getNameIndex())); 905 } 906 907 String remapDesc = nm.mapDescriptor(descUtf.getString()); 909 method.setDescriptorIndex(constantPool.remapUtf8To(remapDesc, method.getDescriptorIndex())); 910 } 911 912 int currentCpLength = constantPool.length(); for (int i = 0; i < currentCpLength; i++) { 915 CpInfo cpInfo = getCpEntry(i); 916 if (null != cpInfo) { 917 if (cpInfo instanceof RefCpInfo) { 921 ClassCpInfo classInfo = (ClassCpInfo)getCpEntry(((RefCpInfo)cpInfo).getClassIndex()); 923 Utf8CpInfo classUtf = (Utf8CpInfo)getCpEntry(classInfo.getClassNameIndex()); 924 String className = classUtf.getString(); 925 926 int ntIndex = ((RefCpInfo)cpInfo).getNameAndTypeIndex(); 928 NameAndTypeCpInfo nameTypeInfo = (NameAndTypeCpInfo)getCpEntry(ntIndex); 929 Utf8CpInfo refUtf = (Utf8CpInfo)getCpEntry(nameTypeInfo.getNameIndex()); 930 Utf8CpInfo descUtf = (Utf8CpInfo)getCpEntry(nameTypeInfo.getDescriptorIndex()); 931 932 String remapRef; 934 if (cpInfo instanceof FieldrefCpInfo) { 935 remapRef = nm.mapField(className, refUtf.getString()); 936 if (null == remapRef) { 938 remapRef = refUtf.getString(); 939 } 940 941 if (refUtf.getString().startsWith("class$")) { 944 String realClassName = refUtf.getString().substring(6).replace('$', '.'); 945 if (!realClassName.startsWith("java.") && !realClassName.startsWith("javax.") 948 && !realClassName.startsWith("sun.") && !realClassName.startsWith("com.sun.")) { 949 Cl cl = getClassTree().findClass(realClassName); 952 if (null != cl) { 953 if (cl.isBeingObfuscated()) { 954 FileLogger.getInstance().addWarning("# WARNING: " + realClassName + 955 " shouldn't be obfuscated: it is referenced as " 956 + realClassName + ".class from " + thisClassName); 957 } 958 } 959 } 960 } 961 } else { 963 remapRef = nm.mapMethod(className, refUtf.getString(), descUtf.getString()); 965 if (null == remapRef) { 967 remapRef = refUtf.getString(); 968 } 969 } 970 String remapDesc = nm.mapDescriptor(descUtf.getString()); 971 972 if (!remapRef.equals(refUtf.getString()) || 976 !remapDesc.equals(descUtf.getString())) { 977 NameAndTypeCpInfo newNameTypeInfo; 979 if (nameTypeInfo.getRefCount() == 1) { 980 newNameTypeInfo = nameTypeInfo; 981 } 982 else { 983 newNameTypeInfo = (NameAndTypeCpInfo)nameTypeInfo.clone(); 985 986 ((CpInfo)getCpEntry(newNameTypeInfo.getNameIndex())).incRefCount(); 988 ((CpInfo)getCpEntry(newNameTypeInfo.getDescriptorIndex())).incRefCount(); 989 990 ((RefCpInfo)cpInfo).setNameAndTypeIndex( 993 constantPool.addEntry(newNameTypeInfo)); 994 995 newNameTypeInfo.incRefCount(); 997 nameTypeInfo.decRefCount(); 998 } 999 1000 newNameTypeInfo.setNameIndex(constantPool.remapUtf8To(remapRef, newNameTypeInfo.getNameIndex())); 1002 newNameTypeInfo.setDescriptorIndex(constantPool.remapUtf8To(remapDesc, newNameTypeInfo.getDescriptorIndex())); 1003 } 1004 } 1005 } 1006 } 1007 1008 for (int i = 0; i < constantPool.length(); i++) { 1010 CpInfo cpInfo = getCpEntry(i); 1011 if (cpInfo != null) { 1012 if (cpInfo instanceof ClassCpInfo) { 1014 ClassCpInfo classInfo = (ClassCpInfo)cpInfo; 1015 Utf8CpInfo utf = (Utf8CpInfo)getCpEntry(classInfo.getClassNameIndex()); 1016 String remapClass = nm.mapClass(utf.getString()); 1017 int remapIndex = constantPool.remapUtf8To(remapClass, classInfo.getClassNameIndex()); 1018 classInfo.setClassNameIndex(remapIndex); 1019 } 1020 } 1021 } 1022 } 1023 1024 1025 1026 1027 1031 public void write(DataOutput dout) 1032 throws IOException { 1033 if (dout == null) throw new IOException("No output stream was provided."); 1034 dout.writeInt(getMagic()); 1035 dout.writeShort(getMinorVersion()); 1036 dout.writeShort(getMajorVersion()); 1037 dout.writeShort(constantPool.length()); 1038 for (Iterator iter = constantPool.iterator(); iter.hasNext(); ) { 1039 CpInfo cpInfo = (CpInfo) iter.next(); 1040 if (cpInfo != null) { 1041 cpInfo.write(dout); 1042 } 1043 } 1044 dout.writeShort(getAccessFlags()); 1045 dout.writeShort(getClassIndex()); 1046 dout.writeShort(getSuperClassIndex()); 1047 dout.writeShort(getInterfacesCount()); 1048 for (int i = 0; i < getInterfacesCount(); i++) { 1049 dout.writeShort(getInterface(i)); 1050 } 1051 dout.writeShort(getFieldsCount()); 1052 for (int i = 0; i < getFieldsCount(); i++) { 1053 getFieldInfo(i).write(dout); 1054 } 1055 dout.writeShort(getMethodsCount()); 1056 for (int i = 0; i < getMethodsCount(); i++) { 1057 getMethodInfo(i).write(dout); 1058 } 1059 dout.writeShort(getAttributesCount()); 1060 for (int i = 0; i < getAttributesCount(); i++) { 1061 getAttributeInfo(i).write(dout); 1062 } 1063 } 1064 1065 1066 1067 1068 1072 public void dump(PrintWriter pw) { 1073 pw.println("_____________________________________________________________________"); 1074 pw.println("CLASS: " + getName()); 1075 pw.println("Magic: " + Integer.toHexString(getMagic()) + " (" + getMagic() + ")"); 1076 pw.println("Minor version: " + Integer.toHexString(getMinorVersion()) + " (" + getMinorVersion() + ")"); 1077 pw.println("Major version: " + Integer.toHexString(getMajorVersion()) + " (" + getMajorVersion() + ")"); 1078 pw.println(); 1079 pw.println("Access: " + getAccessFlags()); 1080 pw.println("This class: " + getClassIndex() + " / " + getName()); 1081 pw.println("Superclass: " + getSuperClassIndex() + " / " + getSuper()); 1082 pw.println(); 1083 pw.println("CP length: " + constantPool.length()); 1084 for (int i = 0; i < constantPool.length(); i++) { 1085 CpInfo cpInfo = (CpInfo) constantPool.getCpEntry(i); 1086 if (cpInfo != null) { 1087 cpInfo.dump(pw, this, i); 1088 } 1089 } 1090 pw.println("Attributes: " + getAttributesCount()); 1091 for (int i = 0; i < getAttributesCount(); i++) { 1092 pw.println(); 1093 pw.print("attribute[" + i + "]: "); 1094 getAttributeInfo(i).dump(pw, this); 1095 } 1096 pw.println(); 1097 pw.println("Direct implemented interfaces: " + getInterfacesCount()); 1098 for (int i = 0; i < getInterfacesCount(); i++) { 1099 CpInfo info = getCpEntry(getInterface(i)); 1100 pw.print(" interface[" + i + "]: "); 1101 if (null == info) { 1102 pw.println("(null)"); 1103 } else { 1104 pw.println( ((Utf8CpInfo) getCpEntry( ((ClassCpInfo) info).getClassNameIndex())).getString() ); 1105 } 1106 } 1107 pw.println(); 1108 pw.println("Declared fields: " + getFieldsCount()); 1109 for (int i = 0; i < getFieldsCount(); i++) { 1110 ClassItemInfo info = getFieldInfo(i); 1111 pw.print(" field[" + i + "]: "); 1112 if (null == info) { 1113 pw.println("(null)"); 1114 } else { 1115 pw.println(" name: " + ((Utf8CpInfo) getCpEntry(info.getNameIndex())).getString()); 1116 pw.println(" descriptor: " + ((Utf8CpInfo) getCpEntry(info.getDescriptorIndex())).getString()); 1117 } 1118 pw.println(" attributes: " + info.getAttributesLength()); 1119 for (int j = 0; j < info.getAttributesLength(); j++) { 1120 pw.print(" attribute[" + j + "]: "); 1121 info.getAttribute(j).dump(pw, this); 1122 pw.println(); 1123 } 1124 } 1125 pw.println(); 1126 pw.println("Declared methods: " + getMethodsCount()); 1127 for (int i = 0; i < getMethodsCount(); i++) { 1128 ClassItemInfo info = getMethodInfo(i); 1129 pw.print(" method[" + i + "]: "); 1130 if (info == null) { 1131 pw.println("(null)"); 1132 } else { 1133 pw.println(); 1134 pw.println(" name: " + ((Utf8CpInfo) getCpEntry(info.getNameIndex())).getString()); 1135 pw.println(" descriptor: " + ((Utf8CpInfo) getCpEntry(info.getDescriptorIndex())).getString()); 1136 pw.println(" access flags: " + info.getAccessFlags()); 1137 } 1138 pw.println(" attributes: " + info.getAttributesLength()); 1139 for (int j = 0; j < info.getAttributesLength(); j++) { 1140 pw.print(" attribute[" + j + "]: "); 1141 info.getAttribute(j).dump(pw, this); 1142 pw.println(); 1143 } 1144 } 1145 } 1146 1147 1148 1149 1153 public Set getHardcodedClassNames() { 1154 HashSet result = new HashSet(); 1155 1156 int currentCpLength = constantPool.length(); 1157 for (int i = 0; i < currentCpLength; i++) { 1158 CpInfo cpInfo = getCpEntry(i); 1159 if (cpInfo != null && cpInfo instanceof RefCpInfo) { 1160 int ntIndex = ((RefCpInfo) cpInfo).getNameAndTypeIndex(); 1162 NameAndTypeCpInfo nameTypeInfo = (NameAndTypeCpInfo) getCpEntry(ntIndex); 1163 Utf8CpInfo refUtf = (Utf8CpInfo) getCpEntry(nameTypeInfo.getNameIndex()); 1164 1165 if (cpInfo instanceof FieldrefCpInfo) { 1166 if (refUtf.getString().startsWith("class$")) { 1169 String realClassName = refUtf.getString().substring(6).replace('$', '.'); 1170 if (!realClassName.startsWith("java.") && !realClassName.startsWith("javax.") 1171 && !realClassName.startsWith("sun.") && !realClassName.startsWith("com.sun.")) { 1172 result.add(realClassName); 1173 } 1174 } 1175 } 1177 } 1178 } 1179 return result; 1180 } 1181} 1182 | Popular Tags |