Могу ли я всегда использовать Reflection API, если код будет запутан? - PullRequest
2 голосов
/ 17 апреля 2011

Я обнаружил, что есть 2 общих решения:

  1. не запутывайте то, на что ссылается API отражения [ Retroguard , Jobfuscate ]
  2. заменить строки в вызовах API отражения на запутанное имя.

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

В случае 2 он также работает только тогда, когда API Reflection используется со строками, известными во время компиляции (тестирование частных методов?). В этих случаях dp4j также предлагает решение, вводящее код отражения после запутывания.

Чтение FAQ по Proguard Интересно, всегда ли работает 2, когда написано:

ProGuard автоматически обрабатывает конструкции как Class.forName ("SomeClass") и SomeClass.class. Ссылка классы сохраняются в сокращении фаза, и строковые аргументы должным образом заменены в запутывание фаза.

С переменными строковыми аргументами, как правило, невозможно определить их возможные значения.

Q: что означает выделенное жирным шрифтом утверждение? Есть примеры?

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

Обфускатор Zelix KlassMaster Java может автоматически обрабатывать все вызовы API Reflection. Он имеет функцию AutoReflection, которая использует таблицу поиска «зашифрованное старое имя» для «запутанного имени».

Тем не менее, он снова может работать только для вызовов в пределах того же обфусцированного проекта.

См. http://www.zelix.com/klassmaster/docs/tutorials/autoReflectionTutorial.html.

2 голосов
/ 17 апреля 2011

С переменными строковыми аргументами, как правило, невозможно определить их возможные значения.

public Class loadIt(String clsName) throws ClassNotFoundException {
    return Class.forName(clsName);
}

в основном, если вы передаете неконстантную строку в Class.forName, proguard или какой-либо инструмент запутывания, как правило, не могут выяснить, о каком классе вы говорите, и, таким образом, не можете автоматически корректировать код для вас.

1 голос
/ 17 апреля 2011

Это означает, что это:

String className;
if (Math.random() <= 0.5) className = "ca.simpatico.Foo";
else className = "ca.simpatico.Bar";
Class cl = Class.forName(className);

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

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

...