如果代码将被混淆,我可以一直使用反射API吗?



我发现似乎有两种一般的解决方案:

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

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

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

阅读Proguard FAQ我想知道如果2总是工作,当它说:

ProGuard自动处理结构如forname("SomeClass")SomeClass.class。被引用的类在收缩中得以保存阶段,字符串参数为在混淆中正确替换阶段。

对于可变字符串参数,通常无法确定

问:黑体部分是什么意思?任何的例子吗?

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

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

基本上如果你传递一个非常量字符串给Class。对于name, proguard或任何混淆工具通常没有办法弄清楚您在谈论的是什么类,因此不能自动为您调整代码。

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

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

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

这意味着:

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

在混淆后不能工作。ProGuard没有做足够深入的数据流分析,以查看被加载的类名来自这两个字符串字量。

实际上,您唯一合理的选择是决定哪些类、接口和方法应该通过反射访问,然后不要混淆它们。你实际上是在为客户端定义一种奇怪的API——一种只能通过反射方式访问的API。

相关内容

  • 没有找到相关文章

最新更新