黑客入侵java.lang.Object:调用自定义外部类会导致JVM崩溃

时间:2011-02-21 22:07:02

标签: jvm java

我正在为Java Runtime Environment编辑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本身的内联类(内部类),上面的工作就可以了。

有谁能告诉我为什么会发生这种行为?有没有办法安全地调用这样的自定义类?

3 个答案:

答案 0 :(得分:3)

像这样摆弄JVM的内部是非常危险的。 JVM的低级别存在各种隐藏的依赖关系,可能会破坏。 JVM引导程序是一个非常精细的过程。

例如,您发现崩溃而非StackOverflowError的最可能原因是您的更改已破坏所有对象构造...包括构造错误对象。

我怀疑你的守卫代码是无效的,因为this.getClass().getName()可能导致创建一个String对象。因此致命的递归发生在你接近警卫之前。

(顺便提一下,你的hasHooked标志会引入竞争条件。)


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

答案 1 :(得分:1)

'崩溃'是什么意思?

不是StackOverflowException吗?你的new tvmh.DFVMH()实际上也是一个构造函数。所以它贯穿你的'overriden'Object构造函数。

如果你已经这样玩了,那么如何添加tvmh.DFVMH来停止包/类列表呢?

答案 2 :(得分:1)

快速思考:new tvmh.DFVHM()成为一个新对象,派生自java.lang.Object,这意味着您的自定义构造函数代码将在第一个完成之前再次运行。我猜测“hasHooked”应该防范这一点,但该变量是如何定义的?如果那个守卫不起作用,这个序列将无限地递归。

如果你把DFVMH作为一个内联类,那么它的名字可能会以“java.lang [...]”开头(毕竟它在java.lang.Object中),因此不会通过所有的long if语句name.startsWith