Actions

OpenRS2 Deobfuscator: Difference between revisions

From RuneWiki

(Created page with "Install Java 11 & kotlinc <code>git clone <nowiki>https://git.openrs2.org/openrs2/openrs2.git</nowiki></code> === 2004 - 2006 RS2 Client === This is by no means a comprehens...")
 
No edit summary
Line 3: Line 3:
<code>git clone <nowiki>https://git.openrs2.org/openrs2/openrs2.git</nowiki></code>
<code>git clone <nowiki>https://git.openrs2.org/openrs2/openrs2.git</nowiki></code>


=== 2004 - 2006 RS2 Client ===
===2004 - 2006 RS2 Client===
This is by no means a comprehensive guide, just some steps I took when deobfuscating 194 and 225. Some transformers had to be disabled to get it working properly, expect to play around with the transformers more for versions like 317 etc. The deobfuscator code was designed for 2009-2010 RS2 and has had some minor work to partially support 2004.
This is by no means a comprehensive guide, just some steps I took when deobfuscating 194 and 225. Some transformers had to be disabled to get it working properly, expect to play around with the transformers more for versions like 317 etc. The deobfuscator code was designed for 2009-2010 RS2 and has had some minor work to partially support 2004.


Line 15: Line 15:
3. Delete profile mappings from <code>share/deob/map/</code>.
3. Delete profile mappings from <code>share/deob/map/</code>.


4. Remove <code>GlRegistry</code>, <code>GlRegistryProvider</code>, and <code>GlTransformer</code> from <code>deob-ast</code>'s <code>AstDeobfuscatorModule.kt</code> (expect some linting errors to clean up from unused imports). See below.
4. Add signlink entries to <code>share/deob/profile.yaml</code>. See below.


5. Edit <code>deob-bytecode</code>'s <code>BytecodeDeobfuscator.kt</code>. Change client to load <code>runescape.jar</code> using <code>JarLibraryReader</code>, comment out <code>gl</code>, <code>loader</code>, <code>unpack</code>, <code>signlink</code>, and reduce remapping code to only the client remapper. See below.
5. Remove <code>GlRegistry</code>, <code>GlRegistryProvider</code>, and <code>GlTransformer</code> from <code>deob-ast</code>'s <code>AstDeobfuscatorModule.kt</code> (expect some linting errors to clean up from unused imports). See below.


6. Remove everything other than client from <code>deob-util</code>'s <code>Module.kt</code>. See below.
6. Edit <code>deob-bytecode</code>'s <code>BytecodeDeobfuscator.kt</code>. Change client to load <code>runescape.jar</code> using <code>JarLibraryReader</code>, comment out <code>gl</code>, <code>loader</code>, <code>unpack</code>, <code>signlink</code>, and reduce remapping code to only the client remapper. See below.


7. Remove <code>PatcherTransformer</code> and all <code>Unused_____Transformer</code>s from <code>deob-bytecode</code>'s <code>BytecodeDeobfuscatorModule.kt</code>. See below.
7. Remove everything other than client from <code>deob-util</code>'s <code>Module.kt</code>. See below.
 
8. Remove <code>PatcherTransformer</code> and all <code>Unused_____Transformer</code>s from <code>deob-bytecode</code>'s <code>BytecodeDeobfuscatorModule.kt</code>. See below.


9. Build and run:
9. Build and run:
Line 32: Line 34:
You should have some new java files in <code>nonfree/client/src/main/java</code> now. Compile them with deob-annotations in your javac classpath.
You should have some new java files in <code>nonfree/client/src/main/java</code> now. Compile them with deob-annotations in your javac classpath.


I've encountered two minor errors when compiling, either find the problematic transformer or just edit the code to address it. For these ones I just removed the lines:<syntaxhighlight lang="shell">
I've encountered one minor error when compiling, either find the problematic transformer or just edit the code to address it. For this specific one I just removed the referenced line:<syntaxhighlight lang="shell">
Static13.java:1387: error: unreachable statement
Static15.java:1452: error: unreachable statement
                         return;
                         return;
                        ^
Static8.java:26: error: cannot find symbol
                aBoolean58 = true;
</syntaxhighlight>
</syntaxhighlight>


==== AstDeobfuscatorModule.kt ====
==== profile.yaml ====
<syntaxhighlight lang="yaml">
---
excluded_classes:
  - "*!client"
  - "*!sign/signlink"
excluded_methods:
  - "*!**.<clinit> *"
  - "*!**.<init> *"
  - "*!**.main *"
  - "*!**.quit *"
  - "*!sign/signlink.* *"
excluded_fields:
  - "*!sign/signlink.* *"
entry_points:
  - "*!**.<clinit> *"
  - "*!**.main *"
  - "*!client.<init> *"
  - "*!sign/signlink.* *"
scrambled_libraries:
  - client
max_obfuscated_name_len: 2
</syntaxhighlight>
 
====AstDeobfuscatorModule.kt====
Removed: <code>GlTransformer</code>, <code>GlRegistry</code>, <code>GlRegistryProvider</code>
Removed: <code>GlTransformer</code>, <code>GlRegistry</code>, <code>GlRegistryProvider</code>


Add/remove transformers as necessary as different versions may have conflicts. e.g. in 186 I had to disable <code>CharLiteralTransformer</code>, <code>BinaryExprOrderTransformer</code>, and <code>AddSubTransformer</code>.<syntaxhighlight lang="kotlin">
Add/remove transformers as necessary as different versions may have conflicts.<syntaxhighlight lang="kotlin">
package org.openrs2.deob.ast
package org.openrs2.deob.ast


import com.google.inject.AbstractModule
import com.google.inject.AbstractModule
import com.google.inject.multibindings.Multibinder
import com.google.inject.multibindings.Multibinder
import org.openrs2.deob.ast.transform.AddSubTransformer
import org.openrs2.deob.ast.transform.BinaryExprOrderTransformer
import org.openrs2.deob.ast.transform.BitMaskTransformer
import org.openrs2.deob.ast.transform.BitMaskTransformer
import org.openrs2.deob.ast.transform.CharLiteralTransformer
import org.openrs2.deob.ast.transform.ComplementTransformer
import org.openrs2.deob.ast.transform.ComplementTransformer
import org.openrs2.deob.ast.transform.EncloseTransformer
import org.openrs2.deob.ast.transform.EncloseTransformer
import org.openrs2.deob.ast.transform.ForLoopConditionTransformer
import org.openrs2.deob.ast.transform.ForLoopConditionTransformer
import org.openrs2.deob.ast.transform.HexLiteralTransformer
import org.openrs2.deob.ast.transform.HexLiteralTransformer
import org.openrs2.deob.ast.transform.IdentityTransformer
import org.openrs2.deob.ast.transform.IfElseTransformer
import org.openrs2.deob.ast.transform.IfElseTransformer
import org.openrs2.deob.ast.transform.IncrementTransformer
import org.openrs2.deob.ast.transform.IncrementTransformer
Line 67: Line 92:
public object AstDeobfuscatorModule : AbstractModule() {
public object AstDeobfuscatorModule : AbstractModule() {
     override fun configure() {
     override fun configure() {
        // bind(GlRegistry::class.java)
        //    .toProvider(GlRegistryProvider::class.java)
        //    .`in`(Scopes.SINGLETON)
         val binder = Multibinder.newSetBinder(binder(), Transformer::class.java)
         val binder = Multibinder.newSetBinder(binder(), Transformer::class.java)
         binder.addBinding().to(UnencloseTransformer::class.java)
         binder.addBinding().to(UnencloseTransformer::class.java)
Line 72: Line 101:
         binder.addBinding().to(ComplementTransformer::class.java)
         binder.addBinding().to(ComplementTransformer::class.java)
         binder.addBinding().to(NotTransformer::class.java)
         binder.addBinding().to(NotTransformer::class.java)
        binder.addBinding().to(CharLiteralTransformer::class.java)
         binder.addBinding().to(IfElseTransformer::class.java)
         binder.addBinding().to(IfElseTransformer::class.java)
         binder.addBinding().to(TernaryTransformer::class.java)
         binder.addBinding().to(TernaryTransformer::class.java)
         binder.addBinding().to(IdentityTransformer::class.java)
         binder.addBinding().to(BinaryExprOrderTransformer::class.java)
        binder.addBinding().to(AddSubTransformer::class.java)
        // binder.addBinding().to(IdentityTransformer::class.java)
         binder.addBinding().to(BitMaskTransformer::class.java)
         binder.addBinding().to(BitMaskTransformer::class.java)
         binder.addBinding().to(HexLiteralTransformer::class.java)
         binder.addBinding().to(HexLiteralTransformer::class.java)
Line 82: Line 114:
         binder.addBinding().to(ForLoopConditionTransformer::class.java)
         binder.addBinding().to(ForLoopConditionTransformer::class.java)
         binder.addBinding().to(RedundantCastTransformer::class.java)
         binder.addBinding().to(RedundantCastTransformer::class.java)
        // binder.addBinding().to(GlTransformer::class.java)
         binder.addBinding().to(EncloseTransformer::class.java)
         binder.addBinding().to(EncloseTransformer::class.java)
     }
     }
Line 87: Line 120:
</syntaxhighlight>
</syntaxhighlight>


==== BytecodeDeobfuscator.kt ====
====BytecodeDeobfuscator.kt====
Removed: all but client<syntaxhighlight lang="kotlin">
Removed: all but client processing code<syntaxhighlight lang="kotlin">
package org.openrs2.deob.bytecode
package org.openrs2.deob.bytecode


Line 113: Line 146:
         val client = Library.read("client", input.resolve("runescape.jar"), JarLibraryReader)
         val client = Library.read("client", input.resolve("runescape.jar"), JarLibraryReader)


        /*
        * Prefix class names with the name of the library the class
        * came from (e.g. `a` => `client!a`).
        *
        * Using ! as the separator was chosen because it is not valid in Java
        * source code, so we won't expect to see it in the obfuscator's input.
        * Furthermore, if any prefixes accidentally remain unstripped, the
        * problem will be detected quickly as the deobfuscator's output will
        * not compile. It also mirrors the syntax used in JarURLConnection,
        * which has a similar purpose.
        *
        * In the early parts of the deobfuscation pipeline, this allows us to
        * disambiguate a small number of classes in the signlink which clash
        * with classes in the client.
        *
        * After name mapping has been performed, it allows us to disambiguate
        * classes across separate libraries that have been refactored and
        * given the same name.
        *
        * For example, the client and unpackclass both contain many common
        * classes (e.g. the exception wrapper, linked list/node classes,
        * bzip2/gzip decompression classes, and so on). Giving these the same
        * names across both the client and unpackclass is desirable.
        *
        * (Unfortunately we can't deduplicate the classes, as they both expose
        * different sets of fields/methods, presumably as a result of the
        * obfuscator removing unused code.)
        */
         val clientRemapper = ClassNamePrefixRemapper(client)
         val clientRemapper = ClassNamePrefixRemapper(client)


Line 177: Line 182:
</syntaxhighlight>
</syntaxhighlight>


==== Module.kt ====
====Module.kt====
Removed: all but client<syntaxhighlight lang="kotlin">
Removed: all but client<syntaxhighlight lang="kotlin">
package org.openrs2.deob.util
package org.openrs2.deob.util
Line 197: Line 202:
</syntaxhighlight>
</syntaxhighlight>


==== BytecodeDeobfuscatorModule.kt ====
====BytecodeDeobfuscatorModule.kt====
Removed: <code>UnusedLocalTransformer</code>, <code>UnusedMethodTransformer</code>, <code>UnusedArgTransformer</code>, <code>PatcherTransformer</code>
Removed: <code>UnusedLocalTransformer</code>, <code>UnusedMethodTransformer</code>, <code>UnusedArgTransformer</code>, <code>PatcherTransformer</code>


Some of them may be optional and are done as a precaution. <code>PatcherTransformer</code> is useful, but since it's intended for 550 the changes in <code>PatcherModule.kt</code> can be overreaching or irrelevant. Play around with adding/removing transformers or patches if you want to.<syntaxhighlight lang="kotlin">
These are optional really. I do it as a precaution because I've had the Unused* transformers remove code I wanted to keep. Patcher transformer is a good one, but has some changes specific to OpenRS2 / 2009 RS.<syntaxhighlight lang="kotlin">
package org.openrs2.deob.bytecode
package org.openrs2.deob.bytecode


Line 219: Line 224:
import org.openrs2.deob.bytecode.transform.FieldOrderTransformer
import org.openrs2.deob.bytecode.transform.FieldOrderTransformer
import org.openrs2.deob.bytecode.transform.FinalClassTransformer
import org.openrs2.deob.bytecode.transform.FinalClassTransformer
import org.openrs2.deob.bytecode.transform.FinalFieldTransformer
import org.openrs2.deob.bytecode.transform.FinalMethodTransformer
import org.openrs2.deob.bytecode.transform.FinalMethodTransformer
import org.openrs2.deob.bytecode.transform.InvokeSpecialTransformer
import org.openrs2.deob.bytecode.transform.InvokeSpecialTransformer
Line 251: Line 257:
         binder.addBinding().to(InvokeSpecialTransformer::class.java)
         binder.addBinding().to(InvokeSpecialTransformer::class.java)
         binder.addBinding().to(RemapTransformer::class.java)
         binder.addBinding().to(RemapTransformer::class.java)
        // binder.addBinding().to(PatcherTransformer::class.java)
         binder.addBinding().to(ResourceTransformer::class.java)
         binder.addBinding().to(ResourceTransformer::class.java)
         binder.addBinding().to(OpaquePredicateTransformer::class.java)
         binder.addBinding().to(OpaquePredicateTransformer::class.java)
Line 261: Line 268:
         binder.addBinding().to(ConstantArgTransformer::class.java)
         binder.addBinding().to(ConstantArgTransformer::class.java)
         binder.addBinding().to(CopyPropagationTransformer::class.java)
         binder.addBinding().to(CopyPropagationTransformer::class.java)
        // binder.addBinding().to(UnusedLocalTransformer::class.java)
        // binder.addBinding().to(UnusedMethodTransformer::class.java)
        // binder.addBinding().to(UnusedArgTransformer::class.java)
         binder.addBinding().to(CounterTransformer::class.java)
         binder.addBinding().to(CounterTransformer::class.java)
         binder.addBinding().to(ResetTransformer::class.java)
         binder.addBinding().to(ResetTransformer::class.java)
Line 268: Line 278:
         binder.addBinding().to(FinalClassTransformer::class.java)
         binder.addBinding().to(FinalClassTransformer::class.java)
         binder.addBinding().to(FinalMethodTransformer::class.java)
         binder.addBinding().to(FinalMethodTransformer::class.java)
        binder.addBinding().to(FinalFieldTransformer::class.java)
         binder.addBinding().to(OverrideTransformer::class.java)
         binder.addBinding().to(OverrideTransformer::class.java)
         binder.addBinding().to(RedundantGotoTransformer::class.java)
         binder.addBinding().to(RedundantGotoTransformer::class.java)

Revision as of 07:35, 14 November 2022

Install Java 11 & kotlinc

git clone https://git.openrs2.org/openrs2/openrs2.git

2004 - 2006 RS2 Client

This is by no means a comprehensive guide, just some steps I took when deobfuscating 194 and 225. Some transformers had to be disabled to get it working properly, expect to play around with the transformers more for versions like 317 etc. The deobfuscator code was designed for 2009-2010 RS2 and has had some minor work to partially support 2004.

NOTE: If any mistakes are made the nonfree folder needs to be cleared out before re-running the build. You can leave lib alone. Check for share/deob/map/client.yaml if you re-run gradle build after deob, it will process whatever the last output was.


1. Create nonfree/lib/ directory

2. Place obfuscated runescape.jar in nonfree/lib/

3. Delete profile mappings from share/deob/map/.

4. Add signlink entries to share/deob/profile.yaml. See below.

5. Remove GlRegistry, GlRegistryProvider, and GlTransformer from deob-ast's AstDeobfuscatorModule.kt (expect some linting errors to clean up from unused imports). See below.

6. Edit deob-bytecode's BytecodeDeobfuscator.kt. Change client to load runescape.jar using JarLibraryReader, comment out gl, loader, unpack, signlink, and reduce remapping code to only the client remapper. See below.

7. Remove everything other than client from deob-util's Module.kt. See below.

8. Remove PatcherTransformer and all Unused_____Transformers from deob-bytecode's BytecodeDeobfuscatorModule.kt. See below.

9. Build and run:

gradlew build

java -jar all/build/libs/openrs2.jar deob


You should have some new java files in nonfree/client/src/main/java now. Compile them with deob-annotations in your javac classpath.

I've encountered one minor error when compiling, either find the problematic transformer or just edit the code to address it. For this specific one I just removed the referenced line:

Static15.java:1452: error: unreachable statement
                        return;

profile.yaml

---
excluded_classes:
  - "*!client"
  - "*!sign/signlink"
excluded_methods:
  - "*!**.<clinit> *"
  - "*!**.<init> *"
  - "*!**.main *"
  - "*!**.quit *"
  - "*!sign/signlink.* *"
excluded_fields:
  - "*!sign/signlink.* *"
entry_points:
  - "*!**.<clinit> *"
  - "*!**.main *"
  - "*!client.<init> *"
  - "*!sign/signlink.* *"
scrambled_libraries:
  - client
max_obfuscated_name_len: 2

AstDeobfuscatorModule.kt

Removed: GlTransformer, GlRegistry, GlRegistryProvider

Add/remove transformers as necessary as different versions may have conflicts.

package org.openrs2.deob.ast

import com.google.inject.AbstractModule
import com.google.inject.multibindings.Multibinder
import org.openrs2.deob.ast.transform.AddSubTransformer
import org.openrs2.deob.ast.transform.BinaryExprOrderTransformer
import org.openrs2.deob.ast.transform.BitMaskTransformer
import org.openrs2.deob.ast.transform.CharLiteralTransformer
import org.openrs2.deob.ast.transform.ComplementTransformer
import org.openrs2.deob.ast.transform.EncloseTransformer
import org.openrs2.deob.ast.transform.ForLoopConditionTransformer
import org.openrs2.deob.ast.transform.HexLiteralTransformer
import org.openrs2.deob.ast.transform.IfElseTransformer
import org.openrs2.deob.ast.transform.IncrementTransformer
import org.openrs2.deob.ast.transform.NegativeLiteralTransformer
import org.openrs2.deob.ast.transform.NewInstanceTransformer
import org.openrs2.deob.ast.transform.NotTransformer
import org.openrs2.deob.ast.transform.RedundantCastTransformer
import org.openrs2.deob.ast.transform.TernaryTransformer
import org.openrs2.deob.ast.transform.Transformer
import org.openrs2.deob.ast.transform.UnencloseTransformer
import org.openrs2.deob.ast.transform.ValueOfTransformer

public object AstDeobfuscatorModule : AbstractModule() {
    override fun configure() {
        // bind(GlRegistry::class.java)
        //     .toProvider(GlRegistryProvider::class.java)
        //     .`in`(Scopes.SINGLETON)

        val binder = Multibinder.newSetBinder(binder(), Transformer::class.java)
        binder.addBinding().to(UnencloseTransformer::class.java)
        binder.addBinding().to(NegativeLiteralTransformer::class.java)
        binder.addBinding().to(ComplementTransformer::class.java)
        binder.addBinding().to(NotTransformer::class.java)
        binder.addBinding().to(CharLiteralTransformer::class.java)
        binder.addBinding().to(IfElseTransformer::class.java)
        binder.addBinding().to(TernaryTransformer::class.java)
        binder.addBinding().to(BinaryExprOrderTransformer::class.java)
        binder.addBinding().to(AddSubTransformer::class.java)
        // binder.addBinding().to(IdentityTransformer::class.java)
        binder.addBinding().to(BitMaskTransformer::class.java)
        binder.addBinding().to(HexLiteralTransformer::class.java)
        binder.addBinding().to(ValueOfTransformer::class.java)
        binder.addBinding().to(NewInstanceTransformer::class.java)
        binder.addBinding().to(IncrementTransformer::class.java)
        binder.addBinding().to(ForLoopConditionTransformer::class.java)
        binder.addBinding().to(RedundantCastTransformer::class.java)
        // binder.addBinding().to(GlTransformer::class.java)
        binder.addBinding().to(EncloseTransformer::class.java)
    }
}

BytecodeDeobfuscator.kt

Removed: all but client processing code

package org.openrs2.deob.bytecode

import com.github.michaelbull.logging.InlineLogger
import org.openrs2.asm.classpath.ClassPath
import org.openrs2.asm.classpath.Library
import org.openrs2.asm.io.JarLibraryReader
import org.openrs2.asm.io.JarLibraryWriter
import org.openrs2.asm.transform.Transformer
import org.openrs2.deob.bytecode.remap.ClassNamePrefixRemapper
import org.openrs2.deob.bytecode.remap.StripClassNamePrefixRemapper
import java.nio.file.Files
import java.nio.file.Path
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
public class BytecodeDeobfuscator @Inject constructor(
    @DeobfuscatorQualifier private val transformers: Set<Transformer>
) {
    public fun run(input: Path, output: Path) {
        // read input jars/packs
        logger.info { "Reading input jars" }
        val client = Library.read("client", input.resolve("runescape.jar"), JarLibraryReader)

        val clientRemapper = ClassNamePrefixRemapper(client)

        client.remap(clientRemapper)

        // bundle libraries together into a common classpath
        val runtime = ClassLoader.getPlatformClassLoader()
        val classPath = ClassPath(
            runtime,
            dependencies = emptyList(),
            libraries = listOf(client)
        )

        // deobfuscate
        logger.info { "Transforming client" }
        for (transformer in transformers) {
            logger.info { "Running transformer ${transformer.javaClass.simpleName}" }
            transformer.transform(classPath)
        }

        // strip class name prefixes
        client.remap(StripClassNamePrefixRemapper)

        // write output jars
        logger.info { "Writing output jars" }

        Files.createDirectories(output)

        client.write(output.resolve("client.jar"), JarLibraryWriter, classPath)
    }

    private companion object {
        private val logger = InlineLogger()
    }
}

Module.kt

Removed: all but client

package org.openrs2.deob.util

import java.nio.file.Path

public class Module(public val name: String, public val dependencies: Set<Module> = emptySet()) {
    public val jar: Path = Path.of("nonfree/var/cache/deob").resolve("$name.jar")
    public val sources: Path = Path.of("nonfree").resolve(name).resolve("src/main/java")
    public val transitiveDependencies: Set<Module> =
        dependencies.plus(dependencies.flatMap { it.transitiveDependencies })

    public companion object {
        private val CLIENT = Module("client")

        public val ALL: Set<Module> = setOf(CLIENT)
    }
}

BytecodeDeobfuscatorModule.kt

Removed: UnusedLocalTransformer, UnusedMethodTransformer, UnusedArgTransformer, PatcherTransformer

These are optional really. I do it as a precaution because I've had the Unused* transformers remove code I wanted to keep. Patcher transformer is a good one, but has some changes specific to OpenRS2 / 2009 RS.

package org.openrs2.deob.bytecode

import com.google.inject.AbstractModule
import com.google.inject.Scopes
import com.google.inject.multibindings.Multibinder
import org.openrs2.asm.transform.Transformer
import org.openrs2.deob.bytecode.transform.BitShiftTransformer
import org.openrs2.deob.bytecode.transform.BitwiseOpTransformer
import org.openrs2.deob.bytecode.transform.CanvasTransformer
import org.openrs2.deob.bytecode.transform.ClassLiteralTransformer
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.ExceptionTracingTransformer
import org.openrs2.deob.bytecode.transform.FernflowerExceptionTransformer
import org.openrs2.deob.bytecode.transform.FieldOrderTransformer
import org.openrs2.deob.bytecode.transform.FinalClassTransformer
import org.openrs2.deob.bytecode.transform.FinalFieldTransformer
import org.openrs2.deob.bytecode.transform.FinalMethodTransformer
import org.openrs2.deob.bytecode.transform.InvokeSpecialTransformer
import org.openrs2.deob.bytecode.transform.MethodOrderTransformer
import org.openrs2.deob.bytecode.transform.MonitorTransformer
import org.openrs2.deob.bytecode.transform.OpaquePredicateTransformer
import org.openrs2.deob.bytecode.transform.OriginalNameTransformer
import org.openrs2.deob.bytecode.transform.OriginalPcRestoreTransformer
import org.openrs2.deob.bytecode.transform.OriginalPcSaveTransformer
import org.openrs2.deob.bytecode.transform.OverrideTransformer
import org.openrs2.deob.bytecode.transform.RedundantGotoTransformer
import org.openrs2.deob.bytecode.transform.RemapTransformer
import org.openrs2.deob.bytecode.transform.ResetTransformer
import org.openrs2.deob.bytecode.transform.VisibilityTransformer
import org.openrs2.deob.util.DeobfuscatorUtilModule
import org.openrs2.patcher.PatcherModule
import org.openrs2.patcher.transform.ResourceTransformer

public object BytecodeDeobfuscatorModule : AbstractModule() {
    override fun configure() {
        install(PatcherModule)
        install(DeobfuscatorUtilModule)

        bind(Profile::class.java)
            .toProvider(ProfileProvider::class.java)
            .`in`(Scopes.SINGLETON)

        val binder = Multibinder.newSetBinder(binder(), Transformer::class.java, DeobfuscatorQualifier::class.java)
        binder.addBinding().to(OriginalPcSaveTransformer::class.java)
        binder.addBinding().to(OriginalNameTransformer::class.java)
        binder.addBinding().to(ClassLiteralTransformer::class.java)
        binder.addBinding().to(InvokeSpecialTransformer::class.java)
        binder.addBinding().to(RemapTransformer::class.java)
        // binder.addBinding().to(PatcherTransformer::class.java)
        binder.addBinding().to(ResourceTransformer::class.java)
        binder.addBinding().to(OpaquePredicateTransformer::class.java)
        binder.addBinding().to(ExceptionTracingTransformer::class.java)
        binder.addBinding().to(MonitorTransformer::class.java)
        binder.addBinding().to(BitShiftTransformer::class.java)
        binder.addBinding().to(CanvasTransformer::class.java)
        binder.addBinding().to(FieldOrderTransformer::class.java)
        binder.addBinding().to(BitwiseOpTransformer::class.java)
        binder.addBinding().to(ConstantArgTransformer::class.java)
        binder.addBinding().to(CopyPropagationTransformer::class.java)
        // binder.addBinding().to(UnusedLocalTransformer::class.java)
        // binder.addBinding().to(UnusedMethodTransformer::class.java)
        // binder.addBinding().to(UnusedArgTransformer::class.java)
        binder.addBinding().to(CounterTransformer::class.java)
        binder.addBinding().to(ResetTransformer::class.java)
        binder.addBinding().to(EmptyClassTransformer::class.java)
        binder.addBinding().to(MethodOrderTransformer::class.java)
        binder.addBinding().to(VisibilityTransformer::class.java)
        binder.addBinding().to(FinalClassTransformer::class.java)
        binder.addBinding().to(FinalMethodTransformer::class.java)
        binder.addBinding().to(FinalFieldTransformer::class.java)
        binder.addBinding().to(OverrideTransformer::class.java)
        binder.addBinding().to(RedundantGotoTransformer::class.java)
        binder.addBinding().to(OriginalPcRestoreTransformer::class.java)
        binder.addBinding().to(FernflowerExceptionTransformer::class.java)
    }
}