Вопрос

У меня есть странный файл JAR, он содержит какой-то класс, который, когда я использую JD Decompiler, он показывает такой сегмент:

public final void a(ak aa) {
    this.jdField_a_of_type_Ak = aa;
}

public final void a(cn ccn) {
  this.jdField_a_of_type_Cn = ccn;
}

public final cN a() {
  return this.jdField_a_of_type_CN;
}

public final void a() {
  super.b();
}

public final boolean a() {
    return this.jdField_a_of_type_Boolean;
}

Мне просто удивляются, почему Compiler / OBFUSCATOR может продукт получить код байта класса, я имею в виду подпись метода. Кто-нибудь узнал, что Obfuscator может сделать это?

Это было полезно?

Решение

В виде @Jogei Sauer правильно указывает: Спецификация JVM ставит менее ограничения на перегрузку метода в базовом коде, чем JLS на программах Java.

От Спецификация JVM (раздел 4.6, методы):

Ни одно количество методов в одном классе не может иметь то же имя и дескриптор (§4.3.3).

И дескриптор метода включает в себя тип возврата :(4.3.3 Дескрипторы метода)

MethodDescriptor:
    ( ParameterDescriptor* ) ReturnDescriptor

Методы, которые вы упомянули в вашем вопросе, все имеют разные дескрипторы, поэтому они в порядке:

public final void a(ak aa)     ->     (Lsomepkg1/ak;)V
public final void a(cn ccn)    ->     (Lsomepkg2/ccn;)V
public final cN a()            ->     ()Lsomepkg3/cN;
public final void a()          ->     ()V
public final boolean a()       ->     ()Z

Это ловко эксплуатируется обфускателями. Допустимая программа Bytecode больше не имеет «непосредственно соответствующей» программе Java. Прогуистка делает это, например. Вот фрагмент из их руководства:

-overloadaggressively

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

Есть другие аналогичные методы, использующие, например, jsr Инструкция к байтекоде или использование переменных идентификаторов, которые являются зарезервированными словами на языке Java. Здесь Это веб-страница в списке нескольких методов.


Чтобы ответить на очевидный последующий вопрос: как JVM знает, какой метод звонить на сайт Call?

Инструкции Invoke требуют, чтобы вы указать ссылку на полную подпись метода (включая тип возврата метода), который должен быть вызван.

Другие советы

Java Bytecode поддерживает конструкции, которые не действительны в исходном коде Java. Обитаторы используют этот факт путем изменения Bytecode для использования этих конструкций (при этом при этом при этом тот же результат, что и у неблагозванного Bytecode Bytecode).

... Obfuscator производит имена методов / подписи, подобные этому, потому что это его работа. Любой обфускатор должен работать для этой цели.

Класс был составлен без отладки информации (по крайней мере локальная информация отсутствует) и запутана позже.

Одной из основных запутанных стратегии является замена (почти) всеми пакетами, классоми и методиками новыми, бессмысленными именами, так что нельзя понять декомпилированного кода.

Дополнительные стратегии - это запутанные строки и добавление конструкций байт-кода, которые не могут быть обесформлены в код Java.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top