forked from openrs2/openrs2
parent
fef902c176
commit
bf55b0d901
@ -0,0 +1,30 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
|
||||||
|
<parent> |
||||||
|
<groupId>dev.openrs2</groupId> |
||||||
|
<artifactId>openrs2</artifactId> |
||||||
|
<version>1.0.0-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
|
||||||
|
<artifactId>openrs2-deob-ast</artifactId> |
||||||
|
<packaging>jar</packaging> |
||||||
|
|
||||||
|
<name>OpenRS2 AST Deobfuscator</name> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<openrs2.root>${project.parent.basedir}</openrs2.root> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>ch.qos.logback</groupId> |
||||||
|
<artifactId>logback-classic</artifactId> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.github.javaparser</groupId> |
||||||
|
<artifactId>javaparser-symbol-solver-core</artifactId> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -0,0 +1,80 @@ |
|||||||
|
package dev.openrs2.deob.ast; |
||||||
|
|
||||||
|
import java.nio.file.Path; |
||||||
|
import java.nio.file.Paths; |
||||||
|
|
||||||
|
import com.github.javaparser.ParserConfiguration; |
||||||
|
import com.github.javaparser.printer.PrettyPrinter; |
||||||
|
import com.github.javaparser.printer.PrettyPrinterConfiguration; |
||||||
|
import com.github.javaparser.symbolsolver.JavaSymbolSolver; |
||||||
|
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; |
||||||
|
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver; |
||||||
|
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; |
||||||
|
import com.github.javaparser.utils.SourceRoot; |
||||||
|
import com.google.common.collect.ImmutableList; |
||||||
|
import dev.openrs2.deob.ast.transform.AddSubTransformer; |
||||||
|
import dev.openrs2.deob.ast.transform.ComplementTransformer; |
||||||
|
import dev.openrs2.deob.ast.transform.Transformer; |
||||||
|
|
||||||
|
public final class AstDeobfuscator { |
||||||
|
private static final ImmutableList<Transformer> TRANSFORMERS = ImmutableList.of( |
||||||
|
new AddSubTransformer(), |
||||||
|
new ComplementTransformer() |
||||||
|
); |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
var deobfuscator = new AstDeobfuscator(ImmutableList.of( |
||||||
|
Paths.get("nonfree/client/src/main/java"), |
||||||
|
Paths.get("nonfree/gl/src/main/java"), |
||||||
|
Paths.get("nonfree/gl-dri/src/main/java"), |
||||||
|
Paths.get("nonfree/loader/src/main/java"), |
||||||
|
Paths.get("nonfree/signlink/src/main/java"), |
||||||
|
Paths.get("nonfree/unpack/src/main/java"), |
||||||
|
Paths.get("nonfree/unpacker/src/main/java") |
||||||
|
)); |
||||||
|
deobfuscator.run(); |
||||||
|
} |
||||||
|
|
||||||
|
private final ImmutableList<Path> modules; |
||||||
|
|
||||||
|
public AstDeobfuscator(ImmutableList<Path> modules) { |
||||||
|
this.modules = modules; |
||||||
|
} |
||||||
|
|
||||||
|
public void run() { |
||||||
|
var solver = new CombinedTypeSolver(new ReflectionTypeSolver(true)); |
||||||
|
for (var module : modules) { |
||||||
|
solver.add(new JavaParserTypeSolver(module)); |
||||||
|
} |
||||||
|
|
||||||
|
var config = new ParserConfiguration() |
||||||
|
.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8) |
||||||
|
.setSymbolResolver(new JavaSymbolSolver(solver)); |
||||||
|
|
||||||
|
var printerConfig = new PrettyPrinterConfiguration() |
||||||
|
.setIndentType(PrettyPrinterConfiguration.IndentType.TABS_WITH_SPACE_ALIGN) |
||||||
|
.setIndentSize(1); |
||||||
|
|
||||||
|
var printer = new PrettyPrinter(printerConfig); |
||||||
|
|
||||||
|
for (var module : modules) { |
||||||
|
var root = new SourceRoot(module, config); |
||||||
|
|
||||||
|
var results = root.tryToParseParallelized(); |
||||||
|
for (var result : results) { |
||||||
|
if (!result.isSuccessful()) { |
||||||
|
throw new IllegalArgumentException(result.toString()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
root.getCompilationUnits().forEach(unit -> { |
||||||
|
TRANSFORMERS.forEach(transformer -> { |
||||||
|
transformer.transform(unit); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
root.setPrinter(printer::print); |
||||||
|
root.saveAll(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit; |
||||||
|
import com.github.javaparser.ast.expr.Expression; |
||||||
|
import com.github.javaparser.ast.expr.IntegerLiteralExpr; |
||||||
|
import com.github.javaparser.ast.expr.UnaryExpr; |
||||||
|
import dev.openrs2.deob.ast.util.ExprUtils; |
||||||
|
|
||||||
|
public final class AddSubTransformer extends Transformer { |
||||||
|
private static Expression negate(Expression expr) { |
||||||
|
if (expr.isIntegerLiteralExpr()) { |
||||||
|
return new IntegerLiteralExpr(-expr.asIntegerLiteralExpr().asInt()); |
||||||
|
} else if (expr.isLongLiteralExpr()) { |
||||||
|
return ExprUtils.createLong(-expr.asLongLiteralExpr().asLong()); |
||||||
|
} else { |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void transform(CompilationUnit unit) { |
||||||
|
unit.findAll(UnaryExpr.class).forEach(expr -> { |
||||||
|
var operand = expr.getExpression(); |
||||||
|
if (!ExprUtils.isIntegerOrLongLiteral(operand)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
var op = expr.getOperator(); |
||||||
|
if (op == UnaryExpr.Operator.PLUS) { |
||||||
|
expr.replace(operand); |
||||||
|
} else if (op == UnaryExpr.Operator.MINUS) { |
||||||
|
expr.replace(negate(operand)); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform; |
||||||
|
|
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit; |
||||||
|
import com.github.javaparser.ast.expr.BinaryExpr; |
||||||
|
import com.github.javaparser.ast.expr.Expression; |
||||||
|
import com.github.javaparser.ast.expr.IntegerLiteralExpr; |
||||||
|
import com.github.javaparser.ast.expr.UnaryExpr; |
||||||
|
import dev.openrs2.deob.ast.util.ExprUtils; |
||||||
|
|
||||||
|
public final class ComplementTransformer extends Transformer { |
||||||
|
private static boolean isComplement(Expression expr) { |
||||||
|
return expr.isUnaryExpr() && expr.asUnaryExpr().getOperator() == UnaryExpr.Operator.BITWISE_COMPLEMENT; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isComplementOrLiteral(Expression expr) { |
||||||
|
return isComplement(expr) || ExprUtils.isIntegerOrLongLiteral(expr); |
||||||
|
} |
||||||
|
|
||||||
|
private static Optional<BinaryExpr.Operator> complement(BinaryExpr.Operator op) { |
||||||
|
switch (op) { |
||||||
|
case EQUALS: |
||||||
|
case NOT_EQUALS: |
||||||
|
return Optional.of(op); |
||||||
|
case GREATER: |
||||||
|
return Optional.of(BinaryExpr.Operator.LESS); |
||||||
|
case GREATER_EQUALS: |
||||||
|
return Optional.of(BinaryExpr.Operator.LESS_EQUALS); |
||||||
|
case LESS: |
||||||
|
return Optional.of(BinaryExpr.Operator.GREATER); |
||||||
|
case LESS_EQUALS: |
||||||
|
return Optional.of(BinaryExpr.Operator.GREATER_EQUALS); |
||||||
|
default: |
||||||
|
return Optional.empty(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static Expression complement(Expression expr) { |
||||||
|
if (expr.isUnaryExpr()) { |
||||||
|
return expr.asUnaryExpr().getExpression(); |
||||||
|
} else if (expr.isIntegerLiteralExpr()) { |
||||||
|
return new IntegerLiteralExpr(~expr.asIntegerLiteralExpr().asInt()); |
||||||
|
} else if (expr.isLongLiteralExpr()) { |
||||||
|
return ExprUtils.createLong(~expr.asLongLiteralExpr().asLong()); |
||||||
|
} else { |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void transform(CompilationUnit unit) { |
||||||
|
unit.findAll(BinaryExpr.class).forEach(expr -> { |
||||||
|
complement(expr.getOperator()).ifPresent(op -> { |
||||||
|
var left = expr.getLeft(); |
||||||
|
var right = expr.getRight(); |
||||||
|
|
||||||
|
if (isComplementOrLiteral(left) && isComplementOrLiteral(right) && !(ExprUtils.isIntegerOrLongLiteral(left) && ExprUtils.isIntegerOrLongLiteral(right))) { |
||||||
|
expr.setOperator(op); |
||||||
|
expr.setLeft(complement(left)); |
||||||
|
expr.setRight(complement(right)); |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit; |
||||||
|
|
||||||
|
public abstract class Transformer { |
||||||
|
public abstract void transform(CompilationUnit unit); |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package dev.openrs2.deob.ast.util; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.expr.Expression; |
||||||
|
import com.github.javaparser.ast.expr.LongLiteralExpr; |
||||||
|
|
||||||
|
public final class ExprUtils { |
||||||
|
public static boolean isIntegerOrLongLiteral(Expression expr) { |
||||||
|
return expr.isIntegerLiteralExpr() || expr.isLongLiteralExpr(); |
||||||
|
} |
||||||
|
|
||||||
|
public static LongLiteralExpr createLong(long value) { |
||||||
|
return new LongLiteralExpr(Long.toString(value).concat("L")); |
||||||
|
} |
||||||
|
|
||||||
|
private ExprUtils() { |
||||||
|
/* empty */ |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue