Add BitShiftTransformer

bzip2
Graham 5 years ago
parent 82d359ad4d
commit 2cde631fca
  1. 61
      asm/src/main/java/dev/openrs2/asm/InsnNodeUtils.java
  2. 2
      deob/src/main/java/dev/openrs2/deob/Deobfuscator.java
  3. 48
      deob/src/main/java/dev/openrs2/deob/transform/BitShiftTransformer.java

@ -1,6 +1,10 @@
package dev.openrs2.asm; package dev.openrs2.asm;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
public final class InsnNodeUtils { public final class InsnNodeUtils {
public static AbstractInsnNode nextReal(AbstractInsnNode insn) { public static AbstractInsnNode nextReal(AbstractInsnNode insn) {
@ -31,6 +35,63 @@ public final class InsnNodeUtils {
return insn; return insn;
} }
public static int getIntConstant(AbstractInsnNode insn) {
switch (insn.getOpcode()) {
case Opcodes.ICONST_M1:
return -1;
case Opcodes.ICONST_0:
return 0;
case Opcodes.ICONST_1:
return 1;
case Opcodes.ICONST_2:
return 2;
case Opcodes.ICONST_3:
return 3;
case Opcodes.ICONST_4:
return 4;
case Opcodes.ICONST_5:
return 5;
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
var intInsn = (IntInsnNode) insn;
return intInsn.operand;
case Opcodes.LDC:
var ldc = (LdcInsnNode) insn;
if (ldc.cst instanceof Integer) {
return (Integer) ldc.cst;
}
}
throw new IllegalArgumentException();
}
public static AbstractInsnNode createIntConstant(int value) {
switch (value) {
case -1:
return new InsnNode(Opcodes.ICONST_M1);
case 0:
return new InsnNode(Opcodes.ICONST_0);
case 1:
return new InsnNode(Opcodes.ICONST_1);
case 2:
return new InsnNode(Opcodes.ICONST_2);
case 3:
return new InsnNode(Opcodes.ICONST_3);
case 4:
return new InsnNode(Opcodes.ICONST_4);
case 5:
return new InsnNode(Opcodes.ICONST_5);
}
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
return new IntInsnNode(Opcodes.BIPUSH, value);
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return new IntInsnNode(Opcodes.SIPUSH, value);
} else {
return new LdcInsnNode(value);
}
}
private InsnNodeUtils() { private InsnNodeUtils() {
/* empty */ /* empty */
} }

@ -11,6 +11,7 @@ import dev.openrs2.asm.Library;
import dev.openrs2.asm.Transformer; import dev.openrs2.asm.Transformer;
import dev.openrs2.deob.classpath.ClassPath; import dev.openrs2.deob.classpath.ClassPath;
import dev.openrs2.deob.classpath.TypedRemapper; import dev.openrs2.deob.classpath.TypedRemapper;
import dev.openrs2.deob.transform.BitShiftTransformer;
import dev.openrs2.deob.transform.CanvasTransformer; import dev.openrs2.deob.transform.CanvasTransformer;
import dev.openrs2.deob.transform.ClassForNameTransformer; import dev.openrs2.deob.transform.ClassForNameTransformer;
import dev.openrs2.deob.transform.CounterTransformer; import dev.openrs2.deob.transform.CounterTransformer;
@ -27,6 +28,7 @@ public final class Deobfuscator {
private static final List<Transformer> TRANSFORMERS = List.of( private static final List<Transformer> TRANSFORMERS = List.of(
new OpaquePredicateTransformer(), new OpaquePredicateTransformer(),
new ExceptionTracingTransformer(), new ExceptionTracingTransformer(),
new BitShiftTransformer(),
new CounterTransformer(), new CounterTransformer(),
new CanvasTransformer(), new CanvasTransformer(),
new FieldOrderTransformer() new FieldOrderTransformer()

@ -0,0 +1,48 @@
package dev.openrs2.deob.transform;
import java.util.Set;
import dev.openrs2.asm.InsnMatcher;
import dev.openrs2.asm.InsnNodeUtils;
import dev.openrs2.asm.Library;
import dev.openrs2.asm.Transformer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class BitShiftTransformer extends Transformer {
private static final Logger logger = LoggerFactory.getLogger(BitShiftTransformer.class);
private static final InsnMatcher CONST_SHIFT_MATCHER = InsnMatcher.compile("(ICONST | BIPUSH | SIPUSH | LDC) (ISHL | ISHR | IUSHR | LSHL | LSHR | LUSHR)");
private static final Set<Integer> LONG_SHIFTS = Set.of(Opcodes.LSHL, Opcodes.LSHR, Opcodes.LUSHR);
private int simplified;
@Override
public void preTransform(Library library) {
simplified = 0;
}
@Override
public void transformCode(ClassNode clazz, MethodNode method) {
CONST_SHIFT_MATCHER.match(method).forEach(match -> {
var push = match.get(0);
var bits = InsnNodeUtils.getIntConstant(push);
var opcode = match.get(1).getOpcode();
var simplifiedBits = bits & (LONG_SHIFTS.contains(opcode) ? 63 : 31);
if (bits != simplifiedBits) {
method.instructions.set(push, InsnNodeUtils.createIntConstant(simplifiedBits));
simplified++;
}
});
}
@Override
public void postTransform(Library library) {
logger.info("Simplified {} bit shifts", simplified);
}
}
Loading…
Cancel
Save