sec*_*ask 2 java obfuscation decompiler
我有一个奇怪的jar文件,它包含一些类,当我使用JD Decompiler时,它显示一个这样的段:
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;
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么编译器/混淆器可以产生类似的类字节代码,我的意思是方法签名.有没有人知道混淆器可以做到这一点?
正如@Joachim Sauer正确指出的那样:JVM规范对字节码中方法重载的约束比JLS对Java程序的约束要少.
一个类文件中没有两个方法可能具有相同的名称和描述符(第4.3.3节).
方法描述符包括返回类型:(4.3.3方法描述符)
MethodDescriptor:
( ParameterDescriptor* ) ReturnDescriptor
你在问题中提到的方法都有不同的描述符,所以它们没问题:
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
Run Code Online (Sandbox Code Playgroud)
混淆器巧妙地利用了这一点.有效的字节码程序不再具有"直接对应"的Java程序.ProGuard就是这样做的.以下是他们手册中的一个片段:
-overloadaggressively
指定在混淆时应用积极的重载.然后,多个字段和方法可以获得相同的名称,只要它们的参数和返回类型不同(不仅仅是它们的参数).
还有其他类似的技术使用例如jsr字节码指令或使用Java语言中的保留字的变量标识符.这是一个列出一些技术的网页.
回答明显的后续问题:JVM如何知道在呼叫站点调用哪种方法?
invoke-instructions要求您指定对要调用的完整方法签名(包括方法的返回类型)的引用.
| 归档时间: |
|
| 查看次数: |
750 次 |
| 最近记录: |