diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java index fa2c5a310f..d250cfaf97 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfLe.java @@ -2,6 +2,8 @@ package net.runelite.deob.attributes.code.instructions; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; +import net.runelite.deob.deobfuscators.rename.ParallelExecutorMapping; +import net.runelite.deob.execution.InstructionContext; public class IfLe extends If0 { @@ -10,4 +12,30 @@ public class IfLe extends If0 super(instructions, type, pc); } + @Override + public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) + { + if (super.isSame(thisIc, otherIc)) + return true; + + if (otherIc.getInstruction() instanceof IfGt) + { + return true; + } + + return false; + } + + @Override + public void map(ParallelExecutorMapping mapping, InstructionContext ctx, InstructionContext other) + { + if (other.getInstruction() instanceof IfGt) + { + super.mapOtherBranch(mapping, ctx, other); + } + else + { + super.map(mapping, ctx, other); + } + } } diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java b/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java index c402682e99..c55c7b9cf3 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java @@ -9,6 +9,7 @@ import net.runelite.deob.Method; import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; import net.runelite.deob.attributes.code.instruction.types.MappableInstruction; +import net.runelite.deob.attributes.code.instructions.InvokeStatic; import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; @@ -118,14 +119,12 @@ public class MappingExecutorUtil if (className.startsWith("java/")) return false; -// switch (className) -// { -// case "java/lang/String": -// -// } -// if (m.getClassEntry().getName().equals("java/lang/String")) -// return false; return true; } + + public static boolean isInlineable(Instruction i) + { + return i instanceof InvokeStatic && isMappable((InvokeStatic) i); + } } diff --git a/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java b/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java index cca1db0398..85a18febce 100644 --- a/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java +++ b/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java @@ -4,6 +4,7 @@ import java.util.List; import net.runelite.deob.Method; import net.runelite.deob.attributes.code.instruction.types.ReturnInstruction; import net.runelite.deob.attributes.code.instructions.InvokeStatic; +import net.runelite.deob.deobfuscators.rename.MappingExecutorUtil; public class ParallellMappingExecutor { @@ -82,13 +83,13 @@ public class ParallellMappingExecutor return step(); } - if (p1.getInstruction() instanceof InvokeStatic && !(p2.getInstruction() instanceof InvokeStatic)) + if (MappingExecutorUtil.isInlineable(p1.getInstruction()) && !MappingExecutorUtil.isInlineable(p2.getInstruction())) { f1 = stepInto(f1); f1 = popStack(f1); p1 = f1.getInstructions().get(f1.getInstructions().size() - 1); } - else if (p2.getInstruction() instanceof InvokeStatic && !(p1.getInstruction() instanceof InvokeStatic)) + else if (MappingExecutorUtil.isInlineable(p2.getInstruction()) && !MappingExecutorUtil.isInlineable(p1.getInstruction())) { f2 = stepInto(f2); f2 = popStack(f2); diff --git a/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java b/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java index 566a830b3c..6099c2b1e0 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/rename/MapStaticTest.java @@ -11,6 +11,7 @@ import java.util.Map.Entry; import java.util.Set; import net.runelite.deob.ClassFile; import net.runelite.deob.ClassGroup; +import net.runelite.deob.Deob; import net.runelite.deob.Method; import net.runelite.deob.util.JarUtil; import org.junit.Assert; @@ -31,6 +32,7 @@ public class MapStaticTest { "class107.method2427", "class107.method2344" }, { "client.init", "client.init" }, { "class162.method3270", "class86.method2020" }, + { "class29.method711", "class36.method742" }, }; // @Test @@ -75,8 +77,8 @@ public class MapStaticTest ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar")); ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar")); - Method m1 = group1.findClass("class162").findMethod("method3270"); - Method m2 = group2.findClass("class86").findMethod("method2020"); + Method m1 = group1.findClass("class29").findMethod("method711"); + Method m2 = group2.findClass("class36").findMethod("method742"); ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2); @@ -93,17 +95,54 @@ public class MapStaticTest ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar")); ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar")); - Method m1 = group1.findClass("client").findMethod("init"); - Method m2 = group2.findClass("client").findMethod("init"); + List m1s = getInitialMethods(group1), m2s = getInitialMethods(group2); + //Method m1 = group1.findClass("client").findMethod("init"); + //Method m2 = group2.findClass("client").findMethod("init"); + + assert m1s.size() == m2s.size(); HashMap all = new HashMap(); - map(all, new HashSet(), m1, m2); - - for (Entry e : all.entrySet()) + for (int i = 0; i < m1s.size(); ++i) { - System.out.println(e.getKey() + " <-> " + e.getValue()); + Method m1 = m1s.get(i), m2 = m2s.get(i); + + assert m1.getPoolMethod().equals(m2.getPoolMethod()); + + map(all, new HashSet(), m1, m2); + + for (Entry e : all.entrySet()) + { + System.out.println(e.getKey() + " <-> " + e.getValue()); + } + System.out.println("Total " + all.size()); } - System.out.println("Total " + all.size()); + } + + public List getInitialMethods(ClassGroup group) + { + List methods = new ArrayList<>(); + + group.buildClassGraph(); // required when looking up methods + group.lookup(); // lookup methods + + for (ClassFile cf : group.getClasses()) + { + for (Method m : cf.getMethods().getMethods()) + { + if (!Deob.isObfuscated(m.getName()) && !m.getName().startsWith("<")) + { + if (m.getCode() == null) + { + methods.add(m); + continue; + } + + methods.add(m); // I guess this method name is overriding a jre interface (init, run, ?). + } + } + } + + return methods; } private void map(Map all, Set invalid, Method m1, Method m2)