PSA: This trick will not work on newer JVM versions, see this OpenJDK bug report and this ASM issue report
See: https://twitter.com/LeeAtBenf/status/1136035843955732486
Just for fun: a crackme by Storyyeller which uses this trick.
Utilizes differences in the pre-Java 1 classfile format (major version 45, minor version 2 and below) and the modern Java classfile format.
Regularly, Java's Method Code Attribute obeys the following:
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
However, pre-Java 1 classfiles do not. In pre-Java 1, the max_stack, max_locals, and code_length use half size data types. This means pre-Java 1's classfiles follow this format:
Code_attribute {
u2 attribute_name_index;
u2 attribute_length;
u1 max_stack; // uint8_t vs. uint16_t
u1 max_locals; // uint8_t vs. uint16_t
u2 code_length; // uint16_t vs. uint32_t
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
This either crashes or corrupts almost all Java reverse-engineering tools due to the tool's classfile parser not taking this edge case into account.
JD parses the code attribute incorrectly leading to a decompile fail.
N/A
Procyon parses the code attribute incorrectly leading to a decompile fail.
N/A
FernFlower parses the code attribute incorrectly leading to a decompile fail.
N/A
ASM parses and writes the code attribute incorrectly leading to a disassembly fail and an incorrectly written class.
N/A
Javassist parses and writes the code attribute incorrectly leading to a disassembly fail and an incorrectly written class.
N/A
BCEL parses and writes the code attribute incorrectly leading to a disassembly fail and an incorrectly written class.
N/A
BCV will either represent the class incorrectly or crash due to its reliance on ASM.
2019-06-14
JBE will either represent the class incorrectly or crash due to its reliance on ASM.
N/A
JBEB will either represent the class incorrectly or crash due to its reliance on ASM.
N/A
Helios will either represent the class incorrectly or crash due to its reliance on ASM.
N/A
java-deobfuscator will either represent the class incorrectly or crash due to its reliance on ASM.
N/A
Recaf will either represent the class incorrectly or crash due to its reliance on ASM.
2020-07-24
DirtyJOE parses and writes the code attribute incorrectly leading to a disassembly fail and an incorrectly written class.
N/A
radare2 parses the code attribute incorrectly leading to a disassembly fail.
N/A
Ghidra parses the code attribute incorrectly leading to a disassembly fail.
N/A
Javap parses code attribute incorrectly leading to a disassembly fail.
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8232598
N/A