Взлом на java.lang.Object: вызов пользовательского внешнего класса приводит к сбою JVM - PullRequest
0 голосов
/ 22 февраля 2011

Я играю с редактированием java.lang.Object для Java Runtime Environment.Я понимаю, что, возможно, есть лучшие способы сделать то, что я хочу, но это не то, о чем мой вопрос.

По сути, я добавил конструктор в 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. Сам объект.

Может кто-нибудь сказать мне, почему такое поведение происходит?И есть ли способ безопасно вызвать такой пользовательский класс?

Ответы [ 3 ]

3 голосов
/ 22 февраля 2011

Работать с внутренностями JVM, как это, очень рискованно.На нижних уровнях JVM могут быть разного рода скрытые зависимости.Начальная загрузка JVM - очень деликатный процесс.

Например, наиболее вероятная причина, по которой вы видите сбой, а не StackOverflowError, заключается в том, что ваше изменение нарушило все конструкцию объекта ... включаяПостроение объекта ошибки.

И я подозреваю, что ваш защитный код неэффективен, поскольку this.getClass().getName() может вызывать создание объекта String.Так что фатальная рекурсия произойдет до того, как вы доберетесь до своей охраны.

(Кстати, ваш флаг hasHooked вводит состояние гонки.)


Мой совет: «Не делай этого»!».

1 голос
/ 22 февраля 2011

Просто короткая мысль: new tvmh.DFVHM() становится новым объектом, который также является производным от java.lang.Object, что означает, что ваш пользовательский код конструктора будет запущен снова до завершения первого. Я предполагаю, что "hasHooked" должен остерегаться этого, но как определяется эта переменная? Если этот охранник не работает, эта последовательность будет повторяться бесконечно.

Если вы сделаете DFVMH встроенным классом, его имя, вероятно, будет начинаться с "java.lang [...]" (в конце концов, это java.lang.Object) и, таким образом, не будет проходить через длинный оператор if со всеми name.startsWith.

1 голос
/ 22 февраля 2011

Что вы имеете в виду под "он падает"?

Не правда ли StackOverflowException? Ваш new tvmh.DFVMH() на самом деле тоже конструктор. Таким образом, он проходит через ваш переопределенный конструктор объектов.

Если вы уже играете так, как насчет добавления tvmh.DFVMH для остановки списка пакетов / классов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...