2015-01-13 2 views
2

Редактировать: кажется, что-то другое, сначала прочитайте Edit2.Java Classloader: Как загрузить класс с двоичным именем, отличным от имени поиска?

Как загрузить класс с двоичным именем, отличным от имени поиска?

Я знаю, что Java Spec не позволяет этого, но у меня есть приложение передо мной, которое делает это как-то.

У меня есть собственный сервер (Windows exe, который запускает JVM), компания, которая его создала, больше не существует. Поскольку я, наконец, попал в ошибку, я начал извлекать классы, чтобы исправить это и переместить его в Linux одновременно. Занятия запутаны, но это меня не беспокоит.

Я манипулировал их загрузчиком Classloader верхнего уровня, чтобы сбрасывать каждый файл класса после вызова defineClass (он загружает классы из зашифрованного архива). Там я вижу, что он ищет и определяет класс P.x, но файл класса dumped содержит класс с двоичным именем P.X (несоответствие случая) (есть также внутренние классы с именем P.X $ Y, поэтому они соответствуют двоичному имени). Несовпадение корпуса должно выдавать NoClassDefFoundError в defineClass(), но, поскольку я выгружаю класс непосредственно после defineClass(), это явно не так.

Я немного боюсь продолжить, прежде чем я это понимаю. Потому что, возможно, они включали некоторые ловушки, такие как классы, которые не должны загружаться и проверять их позже. Поэтому, возможно, сервер вернет неправильные результаты, если я просто продолжу, не понимая подробно, как это работает.

От того, как они упаковали JVM, я предполагаю, что они не манипулировали JVM. От взгляда на код OpenJDK такие вещи находятся в части C++, поэтому они не могут просто заменить некоторый файл класса для достижения этого.

я могу думать только 3 способами без взлома JVM:

  1. Я надеялся, что, может быть, есть какой-то секрет VM Arg, но я ничего не нашел до сих пор: https://web.archive.org/web/20100130070337/http://www.md.pp.ru/~eu/jdk6options.html
  2. Заменить java.lang.ClassLoader и установить принятый в name to null , так что имеет значение только двоичное имя. Но будет ли это работать?
  3. Использование ClassFileTransformer как-то. Но будет ли это работать?

Я не нашел подсказки, что они делают 2) или 3). И я не вижу, как это будет работать, потому что код ищет P.x, поэтому даже если PX будет загружен, так что не уверен, что это поможет.

Есть ли у кого-нибудь идеи, как это можно сделать? Они используют 32-битный JRE Hotspot 1.6.0_01-b06, смешанный режим в Windows.

Юридическое примечание. В моей стране мне разрешено ремонтировать программное обеспечение, за которое я заплатил много денег и который больше не поддерживается.

Редактировать 1:
Теперь я ввел свой маленький образец, который делает то же самое в коде. Он не работает с NoClassDefFoundError, поэтому они не манипулируют JVM или java.lang.ClassLoader, так что этот тест не выполняется глобально.

Редактировать2:
Это, вероятно, файловая система, но наоборот, как предложено в комментариях (я перезаписываю файлы).
Так как теперь я могу приложить отладчик, я увидел что-то странное: byte[], который входит в defineClass(), содержит правильное двоичное имя.
Если P/x и P/X существуют, я бы переопределил их, потому что Windows FS нечувствительна к регистру. Doh. Вернусь, если я уверен, что это так.

+0

Просто интересно. В какой стране это? – tbodt

+0

Обратите внимание, что всевозможные вещи возможны через интерфейс отладчика. –

+1

На самом деле, нормальный загрузчик классов также ведет себя в файловой системе без учета регистра (иногда вызывает проблемы на компьютерах Mac). Может быть, этот «зашифрованный архив» не чувствителен к регистру? – Thilo

ответ

0

Проблема заключалась в том, что файловая система Windows не чувствительна к регистру (но не из-за загрузки классов, как предложено в комментариях, но для меня я пишу файлы дампов).

Я написал классы с их именами, но поскольку существуют P.x и P.X, я перезаписал P.x с помощью P.X.

Так что он только искал меня, как если бы он загружал P.X из файла P.x, потому что в моем сбрасываемом файле P.x был классом P.X из-за этой ошибки.

Спасибо всем и извините.

0

Возможно, они обходят обычную реализацию Classloader # defineClass и вместо этого используют sun.misc.Unsafe#defineClass?

+0

Они напрямую расширяют java.lang.ClassLoader и называют его defineClass, поэтому я так не думаю. Но спасибо за намек на то, что он существует. – stackunderflow