From ac9b132937af019ea495c6a1a6e1c1e1efdc4eea Mon Sep 17 00:00:00 2001 From: Graham Date: Sun, 25 Oct 2020 16:40:27 +0000 Subject: [PATCH] Maintain static member grouping during deobfuscation Some static members are not scrambled in the client. Maintaining a one-to-one mapping between instanced and static classes makes refactoring easier in these cases. The browser control filter is removed as we now get the same functionality for free. Signed-off-by: Graham --- .../deob/filter/BrowserControlFilter.kt | 61 ------------------- .../deob/remap/StaticClassGenerator.kt | 20 ------ .../openrs2/deob/remap/StaticClassMapping.kt | 10 +++ .../deob/remap/StaticFieldUnscrambler.kt | 6 +- .../deob/remap/StaticMethodUnscrambler.kt | 6 +- .../org/openrs2/deob/remap/TypedRemapper.kt | 14 ++--- 6 files changed, 19 insertions(+), 98 deletions(-) delete mode 100644 deob/src/main/kotlin/org/openrs2/deob/filter/BrowserControlFilter.kt delete mode 100644 deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassGenerator.kt create mode 100644 deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassMapping.kt diff --git a/deob/src/main/kotlin/org/openrs2/deob/filter/BrowserControlFilter.kt b/deob/src/main/kotlin/org/openrs2/deob/filter/BrowserControlFilter.kt deleted file mode 100644 index ef098cdd70..0000000000 --- a/deob/src/main/kotlin/org/openrs2/deob/filter/BrowserControlFilter.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.openrs2.deob.filter - -import com.github.michaelbull.logging.InlineLogger -import org.objectweb.asm.tree.ClassNode -import org.objectweb.asm.tree.MethodInsnNode -import org.openrs2.asm.classpath.ClassPath -import org.openrs2.asm.filter.AnyMemberFilter -import org.openrs2.asm.filter.MemberFilter -import org.openrs2.asm.hasCode - -public class BrowserControlFilter private constructor(private val clazz: String) : MemberFilter { - override fun matches(owner: String, name: String, desc: String): Boolean { - return clazz == owner - } - - public companion object { - private val logger = InlineLogger() - - public fun create(classPath: ClassPath): MemberFilter { - val browserControlClass = findBrowserControlClass(classPath) - - return if (browserControlClass != null) { - logger.info { "Identified browser control class $browserControlClass" } - BrowserControlFilter(browserControlClass) - } else { - logger.warn { "Failed to identify browser control class" } - AnyMemberFilter - } - } - - private fun findBrowserControlClass(classPath: ClassPath): String? { - for (library in classPath.libraries) { - for (clazz in library) { - if (isBrowserControlClass(clazz)) { - return clazz.name - } - } - } - - return null - } - - private fun isBrowserControlClass(clazz: ClassNode): Boolean { - for (method in clazz.methods) { - if (!method.hasCode) { - continue - } - - for (insn in method.instructions) { - if (insn !is MethodInsnNode) { - continue - } else if (insn.owner == "netscape/javascript/JSObject") { - return true - } - } - } - - return false - } - } -} diff --git a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassGenerator.kt b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassGenerator.kt deleted file mode 100644 index c75570e77b..0000000000 --- a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassGenerator.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.openrs2.deob.remap - -public class StaticClassGenerator(private val generator: NameGenerator, private val maxMembers: Int) { - private var lastClass: String? = null - private var members = 0 - - public fun generate(): String { - var clazz = lastClass - - if (clazz == null || members >= maxMembers) { - clazz = generator.generate("Static") - lastClass = clazz - members = 1 - } else { - members++ - } - - return clazz - } -} diff --git a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassMapping.kt b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassMapping.kt new file mode 100644 index 0000000000..d564839507 --- /dev/null +++ b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassMapping.kt @@ -0,0 +1,10 @@ +package org.openrs2.deob.remap + +public class StaticClassMapping { + private val nameGenerator = NameGenerator() + private val mapping = mutableMapOf() + + public operator fun get(name: String): String { + return mapping.computeIfAbsent(name) { nameGenerator.generate("Static") } + } +} diff --git a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticFieldUnscrambler.kt b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticFieldUnscrambler.kt index fc6c81d4d1..4212171f65 100644 --- a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticFieldUnscrambler.kt +++ b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticFieldUnscrambler.kt @@ -19,10 +19,8 @@ public class StaticFieldUnscrambler( private val scrambledLibraries: Set, private val nameMap: NameMap, private val inheritedFieldSets: DisjointSet, - staticClassNameGenerator: NameGenerator + private val staticClassMapping: StaticClassMapping ) { - private val generator = StaticClassGenerator(staticClassNameGenerator, MAX_FIELDS_PER_CLASS) - public fun unscramble(): Map, StaticField> { val fields = mutableMapOf, StaticField>() @@ -50,7 +48,7 @@ public class StaticFieldUnscrambler( val member = MemberRef(clazz, field) val partition = inheritedFieldSets[member]!! - val owner = nameMap.mapFieldOwner(partition, generator.generate()) + val owner = nameMap.mapFieldOwner(partition, staticClassMapping[clazz.name]) fields[partition] = StaticField("${library.name}!$owner", simpleInitializers[desc]) } } diff --git a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticMethodUnscrambler.kt b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticMethodUnscrambler.kt index 4c9846ccc2..5b9ffd192e 100644 --- a/deob/src/main/kotlin/org/openrs2/deob/remap/StaticMethodUnscrambler.kt +++ b/deob/src/main/kotlin/org/openrs2/deob/remap/StaticMethodUnscrambler.kt @@ -13,10 +13,8 @@ public class StaticMethodUnscrambler( private val scrambledLibraries: Set, private val nameMap: NameMap, private val inheritedMethodSets: DisjointSet, - staticClassNameGenerator: NameGenerator + private val staticClassMapping: StaticClassMapping ) { - private val generator = StaticClassGenerator(staticClassNameGenerator, MAX_METHODS_PER_CLASS) - public fun unscramble(): Map, String> { val owners = mutableMapOf, String>() @@ -37,7 +35,7 @@ public class StaticMethodUnscrambler( val member = MemberRef(clazz, method) val partition = inheritedMethodSets[member]!! - val owner = nameMap.mapMethodOwner(partition, generator.generate()) + val owner = nameMap.mapMethodOwner(partition, staticClassMapping[clazz.name]) owners[partition] = "${library.name}!$owner" } } diff --git a/deob/src/main/kotlin/org/openrs2/deob/remap/TypedRemapper.kt b/deob/src/main/kotlin/org/openrs2/deob/remap/TypedRemapper.kt index 27b0fb7890..724e797f55 100644 --- a/deob/src/main/kotlin/org/openrs2/deob/remap/TypedRemapper.kt +++ b/deob/src/main/kotlin/org/openrs2/deob/remap/TypedRemapper.kt @@ -5,10 +5,8 @@ import org.objectweb.asm.tree.AbstractInsnNode import org.openrs2.asm.MemberRef import org.openrs2.asm.classpath.ClassPath import org.openrs2.asm.classpath.ExtendedRemapper -import org.openrs2.asm.filter.UnionMemberFilter import org.openrs2.deob.ArgRef import org.openrs2.deob.Profile -import org.openrs2.deob.filter.BrowserControlFilter import org.openrs2.deob.util.map.NameMap import org.openrs2.util.collect.DisjointSet @@ -98,24 +96,22 @@ public class TypedRemapper private constructor( verifyMemberMapping(fields, profile.maxObfuscatedNameLen) verifyMemberMapping(methods, profile.maxObfuscatedNameLen) - val browserControlFilter = BrowserControlFilter.create(classPath) - - val staticClassNameGenerator = NameGenerator() + val staticClassMapping = StaticClassMapping() val staticFields = StaticFieldUnscrambler( classPath, - UnionMemberFilter(profile.excludedFields, browserControlFilter), + profile.excludedFields, profile.scrambledLibraries, nameMap, inheritedFieldSets, - staticClassNameGenerator + staticClassMapping ).unscramble() val staticMethods = StaticMethodUnscrambler( classPath, - UnionMemberFilter(profile.excludedMethods, browserControlFilter), + profile.excludedMethods, profile.scrambledLibraries, nameMap, inheritedMethodSets, - staticClassNameGenerator + staticClassMapping ).unscramble() return TypedRemapper(