-The evilness of this challenge comes from the fact that this challenge exploits the fact that the JVM caches instances of primitive values. In Java, you can represent bytes either by using the primitive `byte` type, or using the `java.lang.Byte`class. Naturally, objects of classes are much more memory intensive than primitives. Therefore, to avoid a lot of duplicated `Byte` instances of the same value on the heap, the JVM maintains a cache of instances of `Byte`instead. The`Byte.valueOf(byte)`method uses this cache rather than creating new instances every time. If you manage to change the internal values stored in these `Byte` object instances, a call such as`Byte.valueOf(1)`might result in a`Byte`object that does not contain the value`1` at all. This is exactly what this binary does. This is exactly what the native loader does. Prior to actually calling this Java code, the native loader hacks into the JVM just before loading and running the embedded class file. `FUN_001016a4` and `FUN_00101478` patch the values of the cached`java/lang/Byte`and`java/lang/Boolean`, resulting in the fact that the compared values do not match with what is stored in the bytecode, effectively slightly changing the behaviour of the implemented verification code. These functions are somewhat hidden to the reverser, as strings in these functions are encrypted, and calls to the JVM interface are virtual, and therefore hidden behind a vtable instead of referenced by imports directories of the binary.
0 commit comments