diff --git a/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/BytecodeDeobfuscatorModule.kt b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/BytecodeDeobfuscatorModule.kt index 132c0f9a..2dc39ce7 100644 --- a/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/BytecodeDeobfuscatorModule.kt +++ b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/BytecodeDeobfuscatorModule.kt @@ -12,6 +12,7 @@ import org.openrs2.deob.bytecode.transform.ConstantArgTransformer import org.openrs2.deob.bytecode.transform.CopyPropagationTransformer import org.openrs2.deob.bytecode.transform.CounterTransformer import org.openrs2.deob.bytecode.transform.EmptyClassTransformer +import org.openrs2.deob.bytecode.transform.ExceptionObfuscationTransformer import org.openrs2.deob.bytecode.transform.ExceptionTracingTransformer import org.openrs2.deob.bytecode.transform.FernflowerExceptionTransformer import org.openrs2.deob.bytecode.transform.FieldOrderTransformer @@ -56,6 +57,7 @@ public object BytecodeDeobfuscatorModule : AbstractModule() { binder.addBinding().to(PatcherTransformer::class.java) binder.addBinding().to(ResourceTransformer::class.java) binder.addBinding().to(OpaquePredicateTransformer::class.java) + binder.addBinding().to(ExceptionObfuscationTransformer::class.java) binder.addBinding().to(ExceptionTracingTransformer::class.java) binder.addBinding().to(MonitorTransformer::class.java) binder.addBinding().to(BitShiftTransformer::class.java) diff --git a/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionObfuscationTransformer.kt b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionObfuscationTransformer.kt new file mode 100644 index 00000000..98d0c75b --- /dev/null +++ b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionObfuscationTransformer.kt @@ -0,0 +1,54 @@ +package org.openrs2.deob.bytecode.transform + +import com.github.michaelbull.logging.InlineLogger +import jakarta.inject.Singleton +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodNode +import org.openrs2.asm.classpath.ClassPath +import org.openrs2.asm.classpath.Library +import org.openrs2.asm.nextReal +import org.openrs2.asm.transform.Transformer + +/** + * A [Transformer] responsible for removing [ZKM](http://www.zelix.com/klassmaster/)'s + * [exception obfuscation](https://www.zelix.com/klassmaster/featuresExceptionObfuscation.html), + * which inserts exception handlers that catch any type of exception and + * immediately re-throw them. The exception handlers are inserted in locations + * where there is no Java source code equivalent, confusing decompilers. + */ +@Singleton +public class ExceptionObfuscationTransformer : Transformer() { + private var handlers = 0 + + override fun preTransform(classPath: ClassPath) { + handlers = 0 + } + + override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean { + for (insn in method.instructions) { + if (insn.opcode != Opcodes.ATHROW) { + continue + } + + val foundTryCatch = method.tryCatchBlocks.removeIf { tryCatch -> + tryCatch.handler.nextReal === insn + } + + if (foundTryCatch) { + method.instructions.remove(insn) + handlers++ + } + } + + return false + } + + override fun postTransform(classPath: ClassPath) { + logger.info { "Removed $handlers exception obfuscation handlers" } + } + + private companion object { + private val logger = InlineLogger() + } +} diff --git a/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionTracingTransformer.kt b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionTracingTransformer.kt index edf340fb..b47c02e1 100644 --- a/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionTracingTransformer.kt +++ b/deob-bytecode/src/main/kotlin/org/openrs2/deob/bytecode/transform/ExceptionTracingTransformer.kt @@ -11,22 +11,13 @@ import org.openrs2.asm.nextReal import org.openrs2.asm.transform.Transformer /** - * A [Transformer] responsible for removing two kinds of redundant exception - * handler. - * - * - [ZKM](http://www.zelix.com/klassmaster/)'s - * [exception obfuscation](https://www.zelix.com/klassmaster/featuresExceptionObfuscation.html), - * which inserts exception handlers that catch [RuntimeException]s and - * immediately re-throw them. The exception handlers are inserted in - * locations where there is no Java source code equivalent, confusing - * decompilers. - * - * - Jagex inserts a try/catch block around every method that catches - * [RuntimeException]s, wraps them with a custom [RuntimeException] - * implementation and re-throws them. The wrapped exception's message - * contains the values of the method's arguments. While this is for debugging - * and not obfuscation, it is clearly automatically-generated and thus we - * remove these exception handlers too. + * A [Transformer] responsible for removing Jagex's exception tracing. Jagex + * inserts a try/catch block around every method that catches + * [RuntimeException]s, wraps them with a custom [RuntimeException] + * implementation and re-throws them. The wrapped exception's message contains + * the values of the method's arguments. While this is for debugging and not + * obfuscation, it is clearly automatically-generated and thus we remove these + * exception handlers too. */ @Singleton public class ExceptionTracingTransformer : Transformer() { @@ -42,8 +33,6 @@ public class ExceptionTracingTransformer : Transformer() { clazz: ClassNode, method: MethodNode ): Boolean { - var changed = false - for (match in CATCH_MATCHER.match(method)) { val foundTryCatch = method.tryCatchBlocks.removeIf { tryCatch -> tryCatch.type == "java/lang/RuntimeException" && tryCatch.handler.nextReal === match[0] @@ -52,11 +41,10 @@ public class ExceptionTracingTransformer : Transformer() { if (foundTryCatch) { match.forEach(method.instructions::remove) tracingTryCatches++ - changed = true } } - return changed + return false } override fun postTransform(classPath: ClassPath) {