1、是否是Java程序?
是。十六进制文本编辑器打开,前四个字节为0xCAFEBABE,这是Java文件的标志
2、是否可执行?
不可执行。
测试环境:
Sun j2sdk1.4.2_08
执行:
java CheckFileB
执行结果如下:出现异常ClassFormatError
分析原因:
1、 类加载时class文件格式不正确等原因导致类不可加载
2、 程序执行过程中自身抛出此异常,故意抛出异常,或调用别的类时出现异常。
如果为原因1,此程序尚未执行,没有进一步危害。
如果为原因2,程序可能已经执行,可能会有其它危害。
进一步分析
修改j2sdk1.4.2_08中的ClassLoader部分源码,对类装载过程进行跟踪,修改如下:
protected final Class defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError {
System.out.println(""); System.out.println("================== Define Class " + name + " ====================");
Class c = null;
check(); if ( (name != null) && name.startsWith("java.")) { System.out.println("### Exception : Class name is start with java"); throw new SecurityException("Prohibited package name: " + name.substring(0, name.lastIndexOf('.'))); } if (protectionDomain == null) { protectionDomain = getDefaultDomain(); }
if (name != null) { checkCerts(name, protectionDomain.getCodeSource()); }
try { if (!checkName(name, false)) { System.out.println("### Error : No Class Def Found, Illegal name " + name); throw new NoClassDefFoundError("Illegal name: " + name); }
c = defineClass0(name, b, off, len, protectionDomain); System.out.println("### Get class define!! "); } catch (ClassFormatError cfe) { // Class format error - try to transform the bytecode and // define the class again // System.out.println("### Catch ClassFormatError, Try other transformers"); Object[] transformers = ClassFileTransformer.getTransformers();
if (transformers == null || transformers.length == 0) System.out.println("### No other transformers!");
for (int i = 0; transformers != null && i < transformers.length; i++) { try { // Transform byte code using transformer byte[] tb = ( (ClassFileTransformer) transformers[i]).transform(b, off, len); c = defineClass0(name, tb, 0, tb.length, protectionDomain); break; } catch (ClassFormatError cfe2) { // If ClassFormatError occurs, try next transformer System.out.println("### Total " + transformers.length + " Transformers, the " + i + " failed to transform."); if (i == transformers.length) System.out.println( "### After all transformer , still cannot get this Class");
} }
// Rethrow original ClassFormatError if unable to transform // bytecode to well-formed // if (c == null) { System.out.println("### Error : Class Format Error! ###"); throw cfe; } else System.out.println("### Get Class :" + c.getName() + " " + c.toString()); }
if (protectionDomain.getCodeSource() != null) { java.security.cert.Certificate certs[] = protectionDomain.getCodeSource().getCertificates(); if (certs != null) setSigners(c, certs); }
System.out.println("### return from defineClass() value: " + c.toString());
return c; } |
protected final Class findSystemClass(String name) throws ClassNotFoundException { System.out.println(""); System.out.println("================== Find System Class " + name + " ===================="); check(); ClassLoader system = getSystemClassLoader(); if (system == null) { if (!checkName(name, true)){ System.out.println("### Exception : Class Not Found!"); throw new ClassNotFoundException(name); } System.out.println("### find bootstrap class ..."); return findBootstrapClass(name); } System.out.println("### load class ..."); return system.loadClass(name); } |
protected final void resolveClass(Class c) { System.out.println("==> ==> resolveClass() begin"); check(); resolveClass0(c); System.out.println("==> ==> resolveClass() end"); } |
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded System.out.println(""); System.out.println("================== Load Class " + name + " ===================="); Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { System.out.println("### Catch Exception : Class Not Found Exception"); // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { System.out.println("### Resolve Class"); resolveClass(c); } if(c == null) System.out.println("### Load null class, Return NULL!!!"); else System.out.println("### Loaded class, Return from LoadClass()"); return c; } |
重新编译后打包,替换原rt.jar文件,再次执行,结果如下:
结果分析:
CheckFileB类在装载时发生错误,抛出ClassFormatError异常,也即CheckFileB并没有加载成功,所以并未执行。
测试
1、查看机器jdk中%JAVA_HOME%/lib/rt.jar是否被修改过。