小编典典

入侵java.lang.Object:调用自定义外部类会使JVM崩溃

java

我正在为Java运行时环境编辑java.lang.Object。我意识到可能有更好的方法来做我想做的事,但这不是我的问题。

基本上,我已经向java.lang.Object添加了一个构造函数,该构造函数在每次创建对象时都会调用。我正在等待某个类的加载,如下所示:

public Object() {
       if (hookEnabled) {
            hookEnabled = false;
        objectCount++;
        if (objectCount > objectStartCount) {
            if (this.getClass() != null) {
                String name = this.getClass().getName();
                if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
                    if (!hasHooked) {
                        hasHooked = true;

//startup beep
        java.awt.Toolkit.getDefaultToolkit().beep();

        //load interface
        javax.swing.JFrame frame = new javax.swing.JFrame("");
        frame.setBounds(0, 0, 400, 400);
        frame.setAlwaysOnTop(true);
        frame.setVisible(true);

                    }
                }
            }
        }
         hookEnabled = true;
        }
    }

这很好。它为JVM正在运行的任何应用程序添加了一个窗口。

但是,当通过将JFrame代码移到单独的类中进行简单更改并调用该调用时,JVM只会崩溃:

public Object() {
            if (hookEnabled) {
            hookEnabled = false;
        objectCount++;
        if (objectCount > objectStartCount) {
            if (this.getClass() != null) {
                String name = this.getClass().getName();
                if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
                    if (!hasHooked) {
                        hasHooked = true;
                        (new tvmh.DFVMH()).setup(); 
                    }
                }
            }
        }
           hookEnabled = true;
        }
    }

-

 package tvmh;

    public class DFVMH {
        public void setup() {
            //startup beep
            java.awt.Toolkit.getDefaultToolkit().beep();

            //load interface
            javax.swing.JFrame frame = new javax.swing.JFrame("");
            frame.setBounds(0, 0, 400, 400);
            frame.setAlwaysOnTop(true);
            frame.setVisible(true);
        }
    }

当我尝试创建java.util.Timer对象时,也会发生相同的情况。

有趣的是,如果我使DFVMH成为java.lang.Object本身的内联类(内部类),则上述方法确实有效。

谁能告诉我为什么会发生这种情况?有什么方法可以安全地调用此类自定义类吗?


阅读 250

收藏
2020-11-30

共1个答案

小编典典

像这样修补JVM的内部风险很大。在JVM的低层上存在各种可能会破坏的隐藏依赖项。JVM引导程序是一个非常微妙的过程。

例如,您看到崩溃而不是的最可能原因StackOverflowError是您的更改破坏了 所有 对象的构造……包括错误对象的构造。

而且我怀疑您的保护代码无效,因为它this.getClass().getName()可能导致创建String对象。因此,致命的递归发生在您警惕之前。

(顺便说一句,您的hasHooked旗帜介绍了比赛条件。)


我的建议是“不要这样做!”。

2020-11-30