如果代码将被混淆,我可以始终使用 Reflection API 吗?

发布于 2024-11-02 07:39:59 字数 839 浏览 5 评论 0原文

我发现似乎有 2 个通用解决方案:

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

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

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

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

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

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

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

I found that there seem to be 2 general solutions:

  1. don't obfuscate what is referred to through the reflection API [Retroguard, Jobfuscate]
  2. replace Strings in reflection API invocations with the obfuscated name.

Those solutions work only for calls within the same project - client code (in another project) may not use the reflection API to access non-public API methods.

In the case of 2 it also only works when the Reflection API is used with Strings known at compile-time (private methods testing?). In those cases dp4j also offers a solution injecting the reflection code after obfuscation.

Reading Proguard FAQ I wondered if 2 otherwise always worked when it says:

ProGuard automatically handles
constructs like
Class.forName("SomeClass") and
SomeClass.class. The referenced
classes are preserved in the shrinking
phase, and the string arguments are
properly replaced in the obfuscation
phase.

With variable string arguments, it's generally not possible to determine
their possible values.

Q: what does the statement in bold mean? Any examples?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

呆° 2024-11-09 07:39:59

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

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

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

With variable string arguments, it's generally not possible to determine their possible values.

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

basically if you pass a non-constant string to Class.forName, there's generally no way for proguard or any obfuscation tool to figure out what class you are talking about, and thus can't automatically adjust the code for you.

微凉徒眸意 2024-11-09 07:39:59

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

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

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

The Zelix KlassMaster Java obfuscator can automatically handle all Reflection API calls. It has a function called AutoReflection which uses an "encrypted old name" to "obfuscated name" lookup table.

However, it again can only work for calls within the same obfuscated project.

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

江湖正好 2024-11-09 07:39:59

这意味着:

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

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

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

It means that this:

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

Won't work after obfuscation. ProGuard doesn't do a deep enough dataflow analysis to see that the class name which gets loaded came from those two string literals.

Really, your only plausible option is to decide which classes, interfaces, and methods should be accessible through reflection, and then not obfuscate those. You're effectively defining a strange kind of API to clients - one which will only be accessed reflectively.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文