首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:反编译后出现奇怪的结果

Java:反编译后出现奇怪的结果
EN

Stack Overflow用户
提问于 2010-12-14 16:22:30
回答 4查看 851关注 0票数 2

我有一个奇怪的jar文件,它包含一些类,当我使用JD Decompiler时,它会显示如下片段:

代码语言:javascript
复制
public final void a(ak aa) {
    this.jdField_a_of_type_Ak = aa;
}

public final void a(cn ccn) {
  this.jdField_a_of_type_Cn = ccn;
}

public final cN a() {
  return this.jdField_a_of_type_CN;
}

public final void a() {
  super.b();
}

public final boolean a() {
    return this.jdField_a_of_type_Boolean;
}

我只是想知道为什么a/an编译器/obfuscator可以产生这样的类字节码,我指的是方法签名。有人知道混淆器可以做到这一点吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-14 16:38:37

@Joachim Sauer correctly points out相比,JVM规范对字节码中的方法重载的约束更少。

JVM Specification (Section 4.6, Methods)

一个类文件中的两个方法不能具有相同的名称和描述符 (§4.3.3)。

方法描述符包括返回类型:(4.3.3 Method Descriptors)

MethodDescriptor:

( ParameterDescriptor* ) ReturnDescriptor

你在问题中提到的方法都有不同的描述符,所以它们是可以的:

代码语言:javascript
复制
public final void a(ak aa)     ->     (Lsomepkg1/ak;)V
public final void a(cn ccn)    ->     (Lsomepkg2/ccn;)V
public final cN a()            ->     ()Lsomepkg3/cN;
public final void a()          ->     ()V
public final boolean a()       ->     ()Z

这被混淆者巧妙地利用了。有效的字节码程序不再有“直接对应”的Java程序。例如,ProGuard就是这样做的。以下是他们手册中的一段代码:

-overloadaggressively指定在模糊处理时应用主动重载。然后,多个字段和方法可以获得相同的名称,只要它们的参数和返回类型不同(而不仅仅是它们的参数)。

还有其他类似的技术,例如使用jsr字节码指令或使用Java语言中的保留字的变量标识符。Here是一个列出了一些技术的网页。

要回答一个显而易见的后续问题: JVM如何知道在调用点调用哪个方法?

invoke-instructions要求您指定对要调用的完整方法签名(包括方法的返回类型)的引用。

票数 5
EN

Stack Overflow用户

发布于 2010-12-14 16:28:03

Java字节码支持在Java源代码中无效的构造。混淆器通过修改字节码来使用这些构造来利用这一事实(同时仍然给出与未混淆字节码相同的结果)。

票数 6
EN

Stack Overflow用户

发布于 2010-12-14 16:25:10

..。混淆器产生这样的方法名/签名,因为这是它的工作。任何混淆器都应该能达到这个目的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4437179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档