2

我发现似乎有两种通用解决方案:

  1. 不要混淆通过反射 API 引用的内容 [ Retroguard , Jobfuscate ]
  2. 用混淆名称替换反射 API 调用中的字符串。

这些解决方案仅适用于同一项目中的调用——客户端代码(在另一个项目中)可能不使用反射 API 来访问非公共 API 方法。

在 2 的情况下,它也仅在反射 API 与编译时已知的字符串一起使用时才有效(私有方法测试?)。在这些情况下,dp4j还提供了一种在混淆后注入反射代码的解决方案。

阅读Proguard 常见问题解答时,我想知道 2 是否总是有效,当它说:

ProGuard 会自动处理 Class.forName("SomeClass") 和 SomeClass.class 等结构。引用的类在收缩阶段被保留,字符串参数在混淆阶段被正确替换。

使用可变字符串参数,通常无法确定它们的可能值。

问:粗体字是什么意思?有什么例子吗?

4

3 回答 3

2

使用可变字符串参数,通常无法确定它们的可能值。

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

基本上,如果您将非常量字符串传递给 Class.forName,则 proguard 或任何混淆工具通常无法确定您正在谈论的类,因此无法自动为您调整代码。

于 2011-04-17T07:29:43.737 回答
2

Zelix KlassMaster Java 混淆器可以自动处理所有反射 API 调用。它有一个名为 AutoReflection 的功能,它使用“加密旧名称”到“混淆名称”查找表。

但是,它再次只能用于同一个混淆项目中的调用。

请参阅http://www.zelix.com/klassmaster/docs/tutorials/autoReflectionTutorial.html

于 2012-03-05T20:53:15.123 回答
1

这意味着:

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

混淆后不起作用。ProGuard 没有进行足够深入的数据流分析来查看加载的类名来自这两个字符串文字。

实际上,您唯一可行的选择是决定哪些类、接口和方法应该可以通过反射访问,然后不要混淆它们。您有效地为客户端定义了一种奇怪的 API - 一种只能以反射方式访问的 API。

于 2011-04-17T08:12:28.903 回答