From 57800cb03e69e5d13ab815595adba632f822fbd8 Mon Sep 17 00:00:00 2001 From: Graham Date: Sun, 7 Jun 2020 15:53:13 +0100 Subject: [PATCH] Exclude browser control class from static scrambling I suspect it is excluded on Jagex's end so the client deals correctly with any class loading failures caused by the absence of the netscape.javascript.JSObject class. Signed-off-by: Graham --- .../deob/filter/BrowserControlFilter.kt | 61 +++++++++++++++++++ .../deob/remap/StaticFieldUnscrambler.kt | 2 - .../deob/remap/StaticMethodUnscrambler.kt | 2 - .../dev/openrs2/deob/remap/TypedRemapper.kt | 8 ++- 4 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 deob/src/main/java/dev/openrs2/deob/filter/BrowserControlFilter.kt diff --git a/deob/src/main/java/dev/openrs2/deob/filter/BrowserControlFilter.kt b/deob/src/main/java/dev/openrs2/deob/filter/BrowserControlFilter.kt new file mode 100644 index 0000000000..90349a03da --- /dev/null +++ b/deob/src/main/java/dev/openrs2/deob/filter/BrowserControlFilter.kt @@ -0,0 +1,61 @@ +package dev.openrs2.deob.filter + +import com.github.michaelbull.logging.InlineLogger +import dev.openrs2.asm.classpath.ClassPath +import dev.openrs2.asm.filter.AnyMemberFilter +import dev.openrs2.asm.filter.MemberFilter +import dev.openrs2.asm.hasCode +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.MethodInsnNode + +class BrowserControlFilter private constructor(private val clazz: String) : MemberFilter { + override fun matches(owner: String, name: String, desc: String): Boolean { + return clazz == owner + } + + companion object { + private val logger = InlineLogger() + + 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/java/dev/openrs2/deob/remap/StaticFieldUnscrambler.kt b/deob/src/main/java/dev/openrs2/deob/remap/StaticFieldUnscrambler.kt index 9ef452f5cc..eaf47fa8ab 100644 --- a/deob/src/main/java/dev/openrs2/deob/remap/StaticFieldUnscrambler.kt +++ b/deob/src/main/java/dev/openrs2/deob/remap/StaticFieldUnscrambler.kt @@ -32,8 +32,6 @@ class StaticFieldUnscrambler( } for (clazz in library) { - // TODO(gpe): exclude the JSObject class - val clinit = clazz.methods.find { it.name == "" } val (simpleInitializers, complexInitializers) = clinit?.extractInitializers(clazz.name) ?: Pair(emptyMap(), emptySet()) diff --git a/deob/src/main/java/dev/openrs2/deob/remap/StaticMethodUnscrambler.kt b/deob/src/main/java/dev/openrs2/deob/remap/StaticMethodUnscrambler.kt index b8ff6e4dc2..c2af9c4066 100644 --- a/deob/src/main/java/dev/openrs2/deob/remap/StaticMethodUnscrambler.kt +++ b/deob/src/main/java/dev/openrs2/deob/remap/StaticMethodUnscrambler.kt @@ -26,8 +26,6 @@ class StaticMethodUnscrambler( } for (clazz in library) { - // TODO(gpe): exclude the JSObject class - for (method in clazz.methods) { if (method.access and Opcodes.ACC_STATIC == 0) { continue diff --git a/deob/src/main/java/dev/openrs2/deob/remap/TypedRemapper.kt b/deob/src/main/java/dev/openrs2/deob/remap/TypedRemapper.kt index 3630a03f1f..479b2573df 100644 --- a/deob/src/main/java/dev/openrs2/deob/remap/TypedRemapper.kt +++ b/deob/src/main/java/dev/openrs2/deob/remap/TypedRemapper.kt @@ -4,7 +4,9 @@ import com.github.michaelbull.logging.InlineLogger import dev.openrs2.asm.MemberRef import dev.openrs2.asm.classpath.ClassPath import dev.openrs2.asm.classpath.ExtendedRemapper +import dev.openrs2.asm.filter.UnionMemberFilter import dev.openrs2.deob.Profile +import dev.openrs2.deob.filter.BrowserControlFilter import dev.openrs2.deob.map.NameMap import dev.openrs2.util.collect.DisjointSet import org.objectweb.asm.tree.AbstractInsnNode @@ -84,10 +86,12 @@ class TypedRemapper private constructor( verifyMemberMapping(fields, profile.maxObfuscatedNameLen) verifyMemberMapping(methods, profile.maxObfuscatedNameLen) + val browserControlFilter = BrowserControlFilter.create(classPath) + val staticClassNameGenerator = NameGenerator() val staticFields = StaticFieldUnscrambler( classPath, - profile.excludedFields, + UnionMemberFilter(profile.excludedFields, browserControlFilter), profile.scrambledLibraries, nameMap, inheritedFieldSets, @@ -95,7 +99,7 @@ class TypedRemapper private constructor( ).unscramble() val staticMethods = StaticMethodUnscrambler( classPath, - profile.excludedMethods, + UnionMemberFilter(profile.excludedMethods, browserControlFilter), profile.scrambledLibraries, nameMap, inheritedMethodSets,