From c70d810057243cfd3c8327a4c5117a1fc7a718ed Mon Sep 17 00:00:00 2001 From: Graham Date: Sun, 1 Mar 2020 16:28:08 +0000 Subject: [PATCH] Don't move static fields with to complex initializers Depending on the class loading order, moving them can result in arrays being empty, which breaks the client's functionality (e.g. it can't get past the JS5 CRC check). --- .../transform/StaticScramblingTransformer.kt | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/deob/src/main/java/dev/openrs2/deob/transform/StaticScramblingTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/StaticScramblingTransformer.kt index d3de2744..7c81875e 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/StaticScramblingTransformer.kt +++ b/deob/src/main/java/dev/openrs2/deob/transform/StaticScramblingTransformer.kt @@ -92,20 +92,24 @@ class StaticScramblingTransformer : Transformer() { return entry.plus(exit) } - private fun MethodNode.extractInitializers(owner: String): Map { - val initializers = mutableMapOf() + private fun MethodNode.extractInitializers(owner: String): Pair, Set> { + val entryExitBlocks = extractEntryExitBlocks() - val putstatics = extractEntryExitBlocks() + val simpleInitializers = mutableMapOf() + val complexInitializers = instructions.asSequence() + .filter { !entryExitBlocks.contains(it) } .filterIsInstance() - .filter { it.opcode == Opcodes.PUTSTATIC } + .filter { it.opcode == Opcodes.GETSTATIC && it.owner == owner && it.name !in TypedRemapper.EXCLUDED_FIELDS } + .map(::MemberDesc) + .toSet() - for (putstatic in putstatics) { - if (putstatic.owner != owner || putstatic.name in TypedRemapper.EXCLUDED_FIELDS) { - continue - } + val putstatics = entryExitBlocks + .filterIsInstance() + .filter { it.opcode == Opcodes.PUTSTATIC && it.owner == owner && it.name !in TypedRemapper.EXCLUDED_FIELDS } + for (putstatic in putstatics) { val desc = MemberDesc(putstatic) - if (initializers.containsKey(desc)) { + if (simpleInitializers.containsKey(desc) || complexInitializers.contains(desc)) { continue } @@ -120,10 +124,10 @@ class StaticScramblingTransformer : Transformer() { instructions.remove(putstatic) initializer.add(putstatic) - initializers[desc] = initializer + simpleInitializers[desc] = initializer } - return initializers + return Pair(simpleInitializers, complexInitializers) } private fun spliceInitializers() { @@ -139,7 +143,8 @@ class StaticScramblingTransformer : Transformer() { } for (dependency in field.dependencies) { - spliceInitializers(done, dependency, fields[dependency]!!) + val dependencyField = fields[dependency] ?: continue + spliceInitializers(done, dependency, dependencyField) } val (clazz, clinit) = nextClass() @@ -171,7 +176,8 @@ class StaticScramblingTransformer : Transformer() { } val clinit = clazz.methods.find { it.name == "" } - val initializers = clinit?.extractInitializers(clazz.name) ?: emptyMap() + val (simpleInitializers, complexInitializers) = clinit?.extractInitializers(clazz.name) + ?: Pair(emptyMap(), emptySet()) clazz.fields.removeIf { field -> if (field.access and Opcodes.ACC_STATIC == 0) { @@ -181,7 +187,11 @@ class StaticScramblingTransformer : Transformer() { } val desc = MemberDesc(field) - val initializer = initializers[desc] ?: InsnList() + if (complexInitializers.contains(desc)) { + return@removeIf false + } + + val initializer = simpleInitializers[desc] ?: InsnList() val maxStack = clinit?.maxStack ?: 0 val ref = MemberRef(clazz, field)