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 <gpe@openrs2.org>
pull/132/head
Graham 4 years ago
parent e08f355e6f
commit ac9b132937
  1. 61
      deob/src/main/kotlin/org/openrs2/deob/filter/BrowserControlFilter.kt
  2. 20
      deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassGenerator.kt
  3. 10
      deob/src/main/kotlin/org/openrs2/deob/remap/StaticClassMapping.kt
  4. 6
      deob/src/main/kotlin/org/openrs2/deob/remap/StaticFieldUnscrambler.kt
  5. 6
      deob/src/main/kotlin/org/openrs2/deob/remap/StaticMethodUnscrambler.kt
  6. 14
      deob/src/main/kotlin/org/openrs2/deob/remap/TypedRemapper.kt

@ -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
}
}
}

@ -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
}
}

@ -0,0 +1,10 @@
package org.openrs2.deob.remap
public class StaticClassMapping {
private val nameGenerator = NameGenerator()
private val mapping = mutableMapOf<String, String>()
public operator fun get(name: String): String {
return mapping.computeIfAbsent(name) { nameGenerator.generate("Static") }
}
}

@ -19,10 +19,8 @@ public class StaticFieldUnscrambler(
private val scrambledLibraries: Set<String>,
private val nameMap: NameMap,
private val inheritedFieldSets: DisjointSet<MemberRef>,
staticClassNameGenerator: NameGenerator
private val staticClassMapping: StaticClassMapping
) {
private val generator = StaticClassGenerator(staticClassNameGenerator, MAX_FIELDS_PER_CLASS)
public fun unscramble(): Map<DisjointSet.Partition<MemberRef>, StaticField> {
val fields = mutableMapOf<DisjointSet.Partition<MemberRef>, 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])
}
}

@ -13,10 +13,8 @@ public class StaticMethodUnscrambler(
private val scrambledLibraries: Set<String>,
private val nameMap: NameMap,
private val inheritedMethodSets: DisjointSet<MemberRef>,
staticClassNameGenerator: NameGenerator
private val staticClassMapping: StaticClassMapping
) {
private val generator = StaticClassGenerator(staticClassNameGenerator, MAX_METHODS_PER_CLASS)
public fun unscramble(): Map<DisjointSet.Partition<MemberRef>, String> {
val owners = mutableMapOf<DisjointSet.Partition<MemberRef>, 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"
}
}

@ -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(

Loading…
Cancel
Save