From 4bc11159d8c9f058c0b58dfb3bc7d6f2721d8d56 Mon Sep 17 00:00:00 2001 From: Graham Date: Wed, 5 Aug 2020 22:44:05 +0100 Subject: [PATCH] Add NotTransformer It's fairly similar to the ComplementTransformer, and translates expressions like: !a == !b => a == b !a == b => a != b Signed-off-by: Graham --- .../openrs2/deob/ast/AstDeobfuscatorModule.kt | 2 + .../deob/ast/transform/NotTransformer.kt | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 deob-ast/src/main/java/dev/openrs2/deob/ast/transform/NotTransformer.kt diff --git a/deob-ast/src/main/java/dev/openrs2/deob/ast/AstDeobfuscatorModule.kt b/deob-ast/src/main/java/dev/openrs2/deob/ast/AstDeobfuscatorModule.kt index 062a09f50b..c00311d9c6 100644 --- a/deob-ast/src/main/java/dev/openrs2/deob/ast/AstDeobfuscatorModule.kt +++ b/deob-ast/src/main/java/dev/openrs2/deob/ast/AstDeobfuscatorModule.kt @@ -19,6 +19,7 @@ import dev.openrs2.deob.ast.transform.IfElseTransformer import dev.openrs2.deob.ast.transform.IncrementTransformer import dev.openrs2.deob.ast.transform.NegativeLiteralTransformer import dev.openrs2.deob.ast.transform.NewInstanceTransformer +import dev.openrs2.deob.ast.transform.NotTransformer import dev.openrs2.deob.ast.transform.RedundantCastTransformer import dev.openrs2.deob.ast.transform.TernaryTransformer import dev.openrs2.deob.ast.transform.Transformer @@ -35,6 +36,7 @@ object AstDeobfuscatorModule : AbstractModule() { 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) diff --git a/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/NotTransformer.kt b/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/NotTransformer.kt new file mode 100644 index 0000000000..bdc5baf119 --- /dev/null +++ b/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/NotTransformer.kt @@ -0,0 +1,62 @@ +package dev.openrs2.deob.ast.transform + +import com.github.javaparser.ast.CompilationUnit +import com.github.javaparser.ast.expr.BinaryExpr +import com.github.javaparser.ast.expr.BinaryExpr.Operator.EQUALS +import com.github.javaparser.ast.expr.BinaryExpr.Operator.NOT_EQUALS +import com.github.javaparser.ast.expr.BooleanLiteralExpr +import com.github.javaparser.ast.expr.Expression +import com.github.javaparser.ast.expr.UnaryExpr +import com.github.javaparser.ast.expr.UnaryExpr.Operator.LOGICAL_COMPLEMENT +import dev.openrs2.deob.ast.Library +import dev.openrs2.deob.ast.LibraryGroup +import dev.openrs2.deob.ast.util.not +import dev.openrs2.deob.ast.util.walk +import javax.inject.Singleton + +@Singleton +class NotTransformer : Transformer() { + override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) { + unit.walk { expr: BinaryExpr -> + val op = expr.operator.flip() ?: return@walk + val left = expr.left + val right = expr.right + + val bothLiteral = left is BooleanLiteralExpr && right is BooleanLiteralExpr + if (bothLiteral) { + return@walk + } + + val leftNotOrLiteral = left.isNotOrLiteral() + val rightNotOrLiteral = right.isNotOrLiteral() + + if (leftNotOrLiteral && rightNotOrLiteral) { + expr.left = left.not() + expr.right = right.not() + return@walk + } else if (leftNotOrLiteral) { + expr.operator = op + expr.left = left.not() + } else if (rightNotOrLiteral) { + expr.operator = op + expr.right = right.not() + } + } + } + + private fun Expression.isNot(): Boolean { + return this is UnaryExpr && operator == LOGICAL_COMPLEMENT + } + + private fun Expression.isNotOrLiteral(): Boolean { + return isNot() || this is BooleanLiteralExpr + } + + private fun BinaryExpr.Operator.flip(): BinaryExpr.Operator? { + return when (this) { + EQUALS -> NOT_EQUALS + NOT_EQUALS -> EQUALS + else -> null + } + } +}