一句话:首个系统研究成熟 Java 反编译器缺陷,并提出差分测试框架 JD-Tester,发现 62 个缺陷。
本文首次系统研究成熟且广泛使用的 Java 反编译器的缺陷特征与成因。作者分析三个流行 Java 反编译器中的 333 个唯一缺陷,发现 40.2% 有小型复现用例;超过 80% 表现为异常、语法或语义错误;57.7%、39.0% 和 41.1% 的缺陷分别归因于从字节码加载结构实体、优化这些实体以及生成源码三个阶段;类型推断缺陷最难修复;循环区域恢复、switch 等特殊结构语法糖及泛型或不可区分类型变量的类型推断是主要挑战。基于这些发现,作者提出差分测试框架 JD-Tester,通过程序生成器构造可执行 Java 测试,并比较原始测试与编译-反编译版本的编译执行行为来检测异常、语法和语义不一致。在三个反编译器上共发现 62 个缺陷,验证了框架的有效性以及测试和验证 Java 反编译器的重要性。
Java decompilers are programs that perform the reverse process of Java compilers, i.e., they translate Java bytecode to Java source code. They are essential for reverse engineering purposes and have become more sophisticated and reliable over the years. However, it remains challenging for modern Java decompilers to reliably perform correct decompilation on real-world programs. To shed light on the key challenges of Java decompilation, this paper provides the first systematic study on the characteristics and causes of bugs in mature, widely-used Java decompilers. We conduct the study by investigating 333 unique bugs from three popular Java decompilers. Our key findings and observations include: (1) Although most of the reported bugs were found when decompiling large, real-world code, 40.2% of them have small test cases for bug reproduction; (2) Over 80% of the bugs manifest as exceptions, syntactic errors, or semantic errors, and bugs with source code artifacts are very likely semantic errors; (3) 57.7%, 39.0%, and 41.1% of the bugs respectively are attributed to three stages of decompilers—loading structure entities from bytecode, optimizing these entities, and generating source code from these entities; (4) Bugs in decompilers’ type inference are the most complex to fix; and (5) Region restoration for structures like loop, sugaring for special structures like switch, and type inference of variables of generic types or indistinguishable types are the three most significant challenges in Java decompilation, which to some extent explains our findings in (3) and (4). Based on these findings, we present JD-Tester, a differential testing framework for Java decompilers, and our experience of using it in testing the three popular Java decompilers. JD-Testerutilizes different Java program generators to construct executable Java tests and finds exceptions, syntactic, and semantic inconsistencies (i.e. bugs) between a generated test and its compiled-decompiled version (through compilation and execution). In total, we have found 62 bugs in the three decompilers, demonstrating both the effectiveness of JD-Tester, and the importance of testing and validating Java decompilers.
@article{paperbot2540,
title = {Understanding and Finding Java Decompiler Bugs},
author = {Yifei Lu and Weidong Hou and Minxue Pan and Xuandong Li and Zhendong Su},
journal = {Proceedings of the ACM on Programming Languages},
volume = {8},
number = {OOPSLA1},
year = {2024},
doi = {10.1145/3649860}
}