如果要对代码进行模糊处理,我是否可以始终使用Reflection API?

时间:2011-04-17 07:24:56

标签: java reflection obfuscation proguard

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

  1. 不要混淆反思API [RetroguardJobfuscate]
  2. 所指的内容
  3. 使用模糊名称替换反射API调用中的字符串。
  4. 这些解决方案仅适用于同一项目中的调用 - 客户端代码(在另一个项目中)可能不使用反射API来访问非公共API方法。

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

    阅读Proguard FAQ我想知道2,否则它总是有效:

      

    ProGuard会自动处理   像。这样的结构   Class.forName(“SomeClass”)和   SomeClass.class。引用   课程在萎缩中得以保留   阶段,字符串参数是   在混淆中正确替换   相。

         

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

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

3 个答案:

答案 0 :(得分:2)

  

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

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

基本上如果你将非常量字符串传递给Class.forName,通常没有办法让proguard或任何混淆工具弄清楚你在说什么类,因此不能自动为你调整代码。 / p>

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

这意味着:

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

混淆后无效。 ProGuard没有进行足够深入的数据流分析,无法看到加载的类名来自这两个字符串文字。

真的,你唯一合理的选择是决定哪些类,接口和方法应该通过反射访问,然后不要混淆那些。您正在为客户端有效地定义一种奇怪的API - 只能以反射方式访问它。