From 95c4c441d06e509b4beaa9dff4dfea7c3f222300 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 18 Oct 2015 18:41:04 -0400 Subject: [PATCH] Rewrite rename unique to work much different. Seems to run ok. --- .../java/net/runelite/deob/ClassFile.java | 7 +- src/main/java/net/runelite/deob/Deob.java | 90 ++++++------ src/main/java/net/runelite/deob/Method.java | 10 +- .../deob/attributes/code/Instruction.java | 13 +- .../deob/attributes/code/Instructions.java | 17 +-- .../code/instructions/ANewArray.java | 27 +++- .../code/instructions/CheckCast.java | 16 ++- .../code/instructions/GetField.java | 19 ++- .../code/instructions/GetStatic.java | 23 ++- .../code/instructions/InstanceOf.java | 16 ++- .../code/instructions/InvokeInterface.java | 27 +--- .../code/instructions/InvokeSpecial.java | 28 ++-- .../code/instructions/InvokeStatic.java | 34 +---- .../code/instructions/InvokeVirtual.java | 27 +--- .../code/instructions/MultiANewArray.java | 26 +++- .../attributes/code/instructions/New.java | 16 ++- .../code/instructions/PutField.java | 30 ++-- .../code/instructions/PutStatic.java | 28 ++-- .../deob/deobfuscators/RenameUnique.java | 134 +++++++++++++++--- .../java/net/runelite/deob/pool/Method.java | 10 ++ .../runelite/deob/signature/Signature.java | 5 +- .../net/runelite/deob/signature/Type.java | 6 + .../net/runelite/deob/util/NameMappings.java | 32 +++++ 23 files changed, 386 insertions(+), 255 deletions(-) create mode 100644 src/main/java/net/runelite/deob/util/NameMappings.java diff --git a/src/main/java/net/runelite/deob/ClassFile.java b/src/main/java/net/runelite/deob/ClassFile.java index 3320f250e8..ed35fea9f2 100644 --- a/src/main/java/net/runelite/deob/ClassFile.java +++ b/src/main/java/net/runelite/deob/ClassFile.java @@ -166,6 +166,11 @@ public class ClassFile { return fields.findField(name); } + + public Class getPoolClass() + { + return name; + } public Field findFieldDeep(NameAndType nat) { @@ -201,7 +206,7 @@ public class ClassFile ClassFile parent = getParent(); if (parent != null) - return parent.findMethodDeep(nat); + return parent.findMethodDeepStatic(nat); return null; } diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java index 3d880d3194..881323e349 100644 --- a/src/main/java/net/runelite/deob/Deob.java +++ b/src/main/java/net/runelite/deob/Deob.java @@ -39,40 +39,40 @@ public class Deob ClassGroup group = loadJar(args[0]); - //run(group, new RenameUnique()); + run(group, new RenameUnique()); + + // remove except RuntimeException + run(group, new RuntimeExceptions()); + + // remove unused methods + run(group, new UnusedMethods()); + + run(group, new UnreachedCode()); + + // remove illegal state exceptions, frees up some parameters + run(group, new IllegalStateExceptions()); + + // remove constant logically dead parameters + run(group, new ConstantParameter()); + + // remove unhit blocks + run(group, new UnreachedCode()); -// // remove except RuntimeException -// run(group, new RuntimeExceptions()); -// -// // remove unused methods -// run(group, new UnusedMethods()); -// -// run(group, new UnreachedCode()); -// -// // remove illegal state exceptions, frees up some parameters -// run(group, new IllegalStateExceptions()); -// -// // remove constant logically dead parameters -// run(group, new ConstantParameter()); -// -// // remove unhit blocks -// run(group, new UnreachedCode()); -// // // remove unused parameters // run(group, new UnusedParameters()); // // // remove jump obfuscation // //new Jumps().run(group); // -// // remove unused fields -// run(group, new UnusedFields()); -// -// // remove unused methods, again? -// run(group, new UnusedMethods()); + // remove unused fields + run(group, new UnusedFields()); + + // remove unused methods, again? + run(group, new UnusedMethods()); // // run(group, new MethodInliner()); // -// run(group, new MethodMover()); +// //run(group, new MethodMover()); // // run(group, new FieldInliner()); // @@ -82,27 +82,27 @@ public class Deob // // run(group, new UnusedClass()); - ModArith mod = new ModArith(); - mod.run(group); - - int last = -1, cur; - while ((cur = mod.runOnce()) > 0) - { - new MultiplicationDeobfuscator().run(group); - - new MultiplyOneDeobfuscator().run(group); - - new MultiplyZeroDeobfuscator().run(group); - - if (last == cur) - { - System.out.println("break"); - break; - } - - last = cur; - //break; - } +// ModArith mod = new ModArith(); +// mod.run(group); +// +// int last = -1, cur; +// while ((cur = mod.runOnce()) > 0) +// { +// new MultiplicationDeobfuscator().run(group); +// +// new MultiplyOneDeobfuscator().run(group); +// +// new MultiplyZeroDeobfuscator().run(group); +// +// if (last == cur) +// { +// System.out.println("break"); +// break; +// } +// +// last = cur; +// //break; +// } saveJar(group, args[1]); diff --git a/src/main/java/net/runelite/deob/Method.java b/src/main/java/net/runelite/deob/Method.java index 77a2833c83..96943360d9 100644 --- a/src/main/java/net/runelite/deob/Method.java +++ b/src/main/java/net/runelite/deob/Method.java @@ -151,7 +151,15 @@ public class Method { return new net.runelite.deob.pool.Method( new net.runelite.deob.pool.Class(this.getMethods().getClassFile().getName()), - new NameAndType(this.getName(), this.getDescriptor()) + new NameAndType(this.getName(), new Signature(this.getDescriptor())) + ); + } + + public net.runelite.deob.pool.InterfaceMethod getPoolInterfaceMethod() + { + return new net.runelite.deob.pool.InterfaceMethod( + new net.runelite.deob.pool.Class(this.getMethods().getClassFile().getName()), + new NameAndType(this.getName(), new Signature(this.getDescriptor())) ); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/Instruction.java b/src/main/java/net/runelite/deob/attributes/code/Instruction.java index dbd93a8736..c6773226e3 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Instruction.java +++ b/src/main/java/net/runelite/deob/attributes/code/Instruction.java @@ -1,10 +1,7 @@ package net.runelite.deob.attributes.code; import java.io.DataInputStream; -import net.runelite.deob.ClassFile; import net.runelite.deob.ConstantPool; -import net.runelite.deob.Field; -import net.runelite.deob.Method; import net.runelite.deob.block.Block; import net.runelite.deob.execution.Frame; @@ -12,6 +9,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import net.runelite.deob.util.NameMappings; public abstract class Instruction { @@ -222,15 +220,12 @@ public abstract class Instruction { } - public void renameClass(ClassFile cf, String name) + // look up symbols from pool + public void lookup2() { } - public void renameField(Field f, net.runelite.deob.pool.Field name) - { - } - - public void renameMethod(Method oldMethod, net.runelite.deob.pool.Method newMethod) + public void regeneratePool() { } diff --git a/src/main/java/net/runelite/deob/attributes/code/Instructions.java b/src/main/java/net/runelite/deob/attributes/code/Instructions.java index 2125c9c1a3..b3329045f4 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Instructions.java +++ b/src/main/java/net/runelite/deob/attributes/code/Instructions.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; +import net.runelite.deob.util.NameMappings; public class Instructions { @@ -253,24 +254,18 @@ public class Instructions return null; } - public void renameClass(ClassFile cf, String name) + public void lookup() { for (Instruction i : instructions) - i.renameClass(cf, name); + i.lookup2(); } - public void renameField(Field f, net.runelite.deob.pool.Field newField) + public void regeneratePool() { for (Instruction i : instructions) - i.renameField(f, newField); + i.regeneratePool(); } - - public void renameMethod(Method oldMethod, net.runelite.deob.pool.Method newMethod) - { - for (Instruction i : instructions) - i.renameMethod(oldMethod, newMethod); - } - + public void replace(Instruction oldi, Instruction newi) { assert oldi != newi; diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/ANewArray.java b/src/main/java/net/runelite/deob/attributes/code/instructions/ANewArray.java index 0e47651364..381bd406c3 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/ANewArray.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/ANewArray.java @@ -14,10 +14,14 @@ import net.runelite.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class ANewArray extends Instruction { private Class clazz; + private ClassFile myClass; + private int dimensions; public ANewArray(Instructions instructions, InstructionType type, int pc) { @@ -59,10 +63,27 @@ public class ANewArray extends Instruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { net.runelite.deob.signature.Type t = new net.runelite.deob.signature.Type(clazz.getName()); - if (t.getType().equals("L" + cf.getName() + ";") || t.getType().equals(cf.getName())) - clazz = new Class(name, t.getArrayDims()); + String name = t.getType(); + if (name.startsWith("L") && name.endsWith(";")) + name = name.substring(1, name.length() - 1); + ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); + myClass = group.findClass(name); + dimensions = t.getArrayDims(); + } + + @Override + public void regeneratePool() + { + if (myClass != null) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < this.dimensions; ++i) + sb.append('['); + sb.append("L" + myClass.getName() + ";"); + clazz = new Class(sb.toString()); + } } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/CheckCast.java b/src/main/java/net/runelite/deob/attributes/code/instructions/CheckCast.java index 33a8cc9812..b0a34b8361 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/CheckCast.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/CheckCast.java @@ -14,10 +14,13 @@ import net.runelite.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class CheckCast extends Instruction { private Class clazz; + private ClassFile myClass; public CheckCast(Instructions instructions, InstructionType type, int pc) { @@ -57,9 +60,16 @@ public class CheckCast extends Instruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (clazz.getName().equals(cf.getName())) - clazz = new Class(name); + ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); + myClass = group.findClass(clazz.getName()); + } + + @Override + public void regeneratePool() + { + if (myClass != null) + clazz = myClass.getPoolClass(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java b/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java index 318645a9ad..e21f1830d3 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/GetField.java @@ -17,12 +17,15 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; import net.runelite.deob.deobfuscators.arithmetic.Encryption; import net.runelite.deob.deobfuscators.arithmetic.Pair; +import net.runelite.deob.util.NameMappings; public class GetField extends Instruction implements GetFieldInstruction { private Field field; + private net.runelite.deob.Field myField; public GetField(Instructions instructions, InstructionType type, int pc) { @@ -81,21 +84,15 @@ public class GetField extends Instruction implements GetFieldInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (field.getClassEntry().getName().equals(cf.getName())) - field = new Field(new Class(name), field.getNameAndType()); - - if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) - field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new net.runelite.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); + myField = getMyField(); } @Override - public void renameField(net.runelite.deob.Field f, Field newField) + public void regeneratePool() { - net.runelite.deob.Field f2 = getMyField(); - - if (f2 == f) - field = newField; + if (myField != null) + field = myField.getPoolField(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java index 7299357251..1f8db72264 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/GetStatic.java @@ -17,12 +17,15 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; import net.runelite.deob.deobfuscators.arithmetic.Encryption; import net.runelite.deob.deobfuscators.arithmetic.Pair; +import net.runelite.deob.util.NameMappings; public class GetStatic extends Instruction implements GetFieldInstruction { private Field field; + private net.runelite.deob.Field myField; public GetStatic(Instructions instructions, InstructionType type, int pc) { @@ -83,25 +86,17 @@ public class GetStatic extends Instruction implements GetFieldInstruction net.runelite.deob.Field f2 = cf.findFieldDeep(nat); return f2; } - + @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (field.getClassEntry().getName().equals(cf.getName())) - field = new Field(new Class(name), field.getNameAndType()); - - if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) - field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new net.runelite.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); + myField = this.getMyField(); } @Override - public void renameField(net.runelite.deob.Field f, Field newField) + public void regeneratePool() { - net.runelite.deob.Field f2 = getMyField(); - - if (f2 == f) - { - field = newField; - } + if (myField != null) + field = myField.getPoolField(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InstanceOf.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InstanceOf.java index 76fdbd900e..67345d0775 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/InstanceOf.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InstanceOf.java @@ -13,10 +13,13 @@ import net.runelite.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class InstanceOf extends Instruction { private Class clazz; + private ClassFile myClass; public InstanceOf(Instructions instructions, InstructionType type, int pc) { @@ -55,9 +58,16 @@ public class InstanceOf extends Instruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (clazz.getName().equals(cf.getName())) - clazz = new Class(name); + ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); + myClass = group.findClass(clazz.getName()); + } + + @Override + public void regeneratePool() + { + if (myClass != null) + clazz = myClass.getPoolClass(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java index e926446534..3b55806b4e 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java @@ -24,11 +24,13 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.runelite.deob.execution.Execution; +import net.runelite.deob.util.NameMappings; public class InvokeInterface extends Instruction implements InvokeInstruction { private InterfaceMethod method; private int count; + private List myMethods; public InvokeInterface(Instructions instructions, InstructionType type, int pc) { @@ -142,30 +144,15 @@ public class InvokeInterface extends Instruction implements InvokeInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (method.getClassEntry().getName().equals(cf.getName())) - method = new InterfaceMethod(new Class(name), method.getNameAndType()); - - Signature signature = method.getNameAndType().getDescriptor(); - for (int i = 0; i < signature.size(); ++i) - { - net.runelite.deob.signature.Type type = signature.getTypeOfArg(i); - - if (type.getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfArg(i, new net.runelite.deob.signature.Type("L" + name + ";", type.getArrayDims())); - } - - // rename return type - if (signature.getReturnValue().getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfReturnValue(new net.runelite.deob.signature.Type("L" + name + ";", signature.getReturnValue().getArrayDims())); + myMethods = this.getMethods(); } @Override - public void renameMethod(net.runelite.deob.Method m, Method newMethod) + public void regeneratePool() { - for (net.runelite.deob.Method m2 : getMethods()) - if (m2.equals(m)) - method = new InterfaceMethod(newMethod.getClassEntry(), newMethod.getNameAndType()); + if (!myMethods.isEmpty()) + method = myMethods.get(0).getPoolInterfaceMethod(); // is this right? } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java index 8df3eceeb4..54c84a0021 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java @@ -23,10 +23,13 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.runelite.deob.execution.Execution; +import net.runelite.deob.pool.InterfaceMethod; +import net.runelite.deob.util.NameMappings; public class InvokeSpecial extends Instruction implements InvokeInstruction { private Method method; + private List myMethods; public InvokeSpecial(Instructions instructions, InstructionType type, int pc) { @@ -134,30 +137,15 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (method.getClassEntry().getName().equals(cf.getName())) - method = new Method(new Class(name), method.getNameAndType()); - - Signature signature = method.getNameAndType().getDescriptor(); - for (int i = 0; i < signature.size(); ++i) - { - net.runelite.deob.signature.Type type = signature.getTypeOfArg(i); - - if (type.getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfArg(i, new net.runelite.deob.signature.Type("L" + name + ";", type.getArrayDims())); - } - - // rename return type - if (signature.getReturnValue().getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfReturnValue(new net.runelite.deob.signature.Type("L" + name + ";", signature.getReturnValue().getArrayDims())); + myMethods = this.getMethods(); } @Override - public void renameMethod(net.runelite.deob.Method m, Method newMethod) + public void regeneratePool() { - for (net.runelite.deob.Method m2 : getMethods()) - if (m2.equals(m)) - method = newMethod; + if (!myMethods.isEmpty()) + method = myMethods.get(0).getPoolMethod(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java index d3bc166584..617d78a57c 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java @@ -23,10 +23,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.runelite.deob.execution.Execution; +import net.runelite.deob.util.NameMappings; public class InvokeStatic extends Instruction implements InvokeInstruction { private Method method; + private List myMethods; public InvokeStatic(Instructions instructions, InstructionType type, int pc) { @@ -138,37 +140,15 @@ public class InvokeStatic extends Instruction implements InvokeInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (method.getClassEntry().getName().equals(cf.getName())) - method = new Method(new Class(name), method.getNameAndType()); - - Signature signature = method.getNameAndType().getDescriptor(); - for (int i = 0; i < signature.size(); ++i) - { - net.runelite.deob.signature.Type type = signature.getTypeOfArg(i); - - if (type.getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfArg(i, new net.runelite.deob.signature.Type("L" + name + ";", type.getArrayDims())); - } - - // rename return type - if (signature.getReturnValue().getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfReturnValue(new net.runelite.deob.signature.Type("L" + name + ";", signature.getReturnValue().getArrayDims())); + myMethods = this.getMethods(); } @Override - public void renameMethod(net.runelite.deob.Method m, Method newMethod) + public void regeneratePool() { - ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); - ClassFile otherClass = group.findClass(method.getClassEntry().getName()); - if (otherClass == null) - return; // not our class - - net.runelite.deob.Method other = otherClass.findMethodDeepStatic(method.getNameAndType()); - assert other.isStatic(); - - if (other.equals(m)) - method = newMethod; + if (!myMethods.isEmpty()) + method = myMethods.get(0).getPoolMethod(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java index c374548e57..c2467d7ec0 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java @@ -23,10 +23,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import net.runelite.deob.execution.Execution; +import net.runelite.deob.util.NameMappings; public class InvokeVirtual extends Instruction implements InvokeInstruction { private Method method; + private List myMethods; public InvokeVirtual(Instructions instructions, InstructionType type, int pc) { @@ -139,30 +141,15 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (method.getClassEntry().getName().equals(cf.getName())) - method = new Method(new Class(name), method.getNameAndType()); - - Signature signature = method.getNameAndType().getDescriptor(); - for (int i = 0; i < signature.size(); ++i) - { - net.runelite.deob.signature.Type type = signature.getTypeOfArg(i); - - if (type.getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfArg(i, new net.runelite.deob.signature.Type("L" + name + ";", type.getArrayDims())); - } - - // rename return type - if (signature.getReturnValue().getType().equals("L" + cf.getName() + ";")) - signature.setTypeOfReturnValue(new net.runelite.deob.signature.Type("L" + name + ";", signature.getReturnValue().getArrayDims())); + myMethods = this.getMethods(); } @Override - public void renameMethod(net.runelite.deob.Method m, Method newMethod) + public void regeneratePool() { - for (net.runelite.deob.Method m2 : getMethods()) - if (m2.equals(m)) - method = newMethod; + if (!myMethods.isEmpty()) + method = myMethods.get(0).getPoolMethod(); // is this right? } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/MultiANewArray.java b/src/main/java/net/runelite/deob/attributes/code/instructions/MultiANewArray.java index a29de34494..e37dbe7bd5 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/MultiANewArray.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/MultiANewArray.java @@ -14,11 +14,14 @@ import net.runelite.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class MultiANewArray extends Instruction { private Class clazz; private int dimensions; + private ClassFile myClass; public MultiANewArray(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -63,11 +66,26 @@ public class MultiANewArray extends Instruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - // class is an array type, ugh. net.runelite.deob.signature.Type t = new net.runelite.deob.signature.Type(clazz.getName()); - if (t.getType().equals("L" + cf.getName() + ";")) - clazz = new Class("L" + name + ";", t.getArrayDims()); + String name = t.getType(); + if (name.startsWith("L") && name.endsWith(";")) + name = name.substring(1, name.length() - 1); + ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); + myClass = group.findClass(name); + } + + @Override + public void regeneratePool() + { + if (myClass != null) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < this.dimensions; ++i) + sb.append('['); + sb.append("L" + myClass.getName() + ";"); + clazz = new Class(sb.toString()); + } } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/New.java b/src/main/java/net/runelite/deob/attributes/code/instructions/New.java index a3af1181eb..d57a567386 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/New.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/New.java @@ -14,10 +14,13 @@ import net.runelite.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class New extends Instruction { private Class clazz; + private ClassFile myClass; public New(Instructions instructions, InstructionType type, int pc) { @@ -58,9 +61,16 @@ public class New extends Instruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (clazz.getName().equals(cf.getName())) - clazz = new Class(name); + ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup(); + myClass = group.findClass(clazz.getName()); + } + + @Override + public void regeneratePool() + { + if (myClass != null) + clazz = myClass.getPoolClass(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java b/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java index 1b4664e3d5..b78b513329 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/PutField.java @@ -16,12 +16,15 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; import net.runelite.deob.deobfuscators.arithmetic.Encryption; import net.runelite.deob.deobfuscators.arithmetic.Pair; +import net.runelite.deob.util.NameMappings; public class PutField extends Instruction implements SetFieldInstruction { private Field field; + private net.runelite.deob.Field myField; public PutField(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -74,32 +77,17 @@ public class PutField extends Instruction implements SetFieldInstruction net.runelite.deob.Field f2 = cf.findFieldDeep(nat); return f2; } - + @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (field.getClassEntry().getName().equals(cf.getName())) - field = new Field(new Class(name), field.getNameAndType()); - - if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) - field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new net.runelite.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); + myField = getMyField(); } @Override - public void renameField(net.runelite.deob.Field f, Field newField) + public void regeneratePool() { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - - ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); - if (cf == null) - return; - - net.runelite.deob.Field f2 = cf.findFieldDeep(nat); - - if (f2 == f) - { - field = newField; - } + if (myField != null) + field = myField.getPoolField(); } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java index ce1d31b2f7..425ae1d120 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/PutStatic.java @@ -16,10 +16,13 @@ import net.runelite.deob.pool.NameAndType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.util.NameMappings; public class PutStatic extends Instruction implements SetFieldInstruction { private Field field; + private net.runelite.deob.Field myField; public PutStatic(Instructions instructions, InstructionType type, int pc) throws IOException { @@ -73,30 +76,15 @@ public class PutStatic extends Instruction implements SetFieldInstruction } @Override - public void renameClass(ClassFile cf, String name) + public void lookup2() { - if (field.getClassEntry().getName().equals(cf.getName())) - field = new Field(new Class(name), field.getNameAndType()); - - if (field.getNameAndType().getDescriptorType().getType().equals("L" + cf.getName() + ";")) - field = new Field(field.getClassEntry(), new NameAndType(field.getNameAndType().getName(), new net.runelite.deob.signature.Type("L" + name + ";", field.getNameAndType().getDescriptorType().getArrayDims()))); + myField = getMyField(); } @Override - public void renameField(net.runelite.deob.Field f, Field newField) + public void regeneratePool() { - Class clazz = field.getClassEntry(); - NameAndType nat = field.getNameAndType(); - - ClassFile cf = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName()); - if (cf == null) - return; - - net.runelite.deob.Field f2 = cf.findFieldDeep(nat); - - if (f2 == f) - { - field = newField; - } + if (myField != null) + field = myField.getPoolField(); } } diff --git a/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java b/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java index 6f78f2b6e8..33e749d2c8 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java +++ b/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java @@ -17,6 +17,8 @@ import net.runelite.deob.signature.Signature; import net.runelite.deob.signature.Type; import java.util.HashSet; import java.util.Set; +import net.runelite.deob.attributes.Code; +import net.runelite.deob.util.NameMappings; public class RenameUnique implements Deobfuscator { @@ -49,8 +51,8 @@ public class RenameUnique implements Deobfuscator // rename on instructions. this includes method calls and field accesses. if (method.getCode() != null) { - Instructions instructions = method.getCode().getInstructions(); - instructions.renameClass(cf, name); +// Instructions instructions = method.getCode().getInstructions(); +// instructions.renameClass(cf, name); // rename on exception handlers Exceptions exceptions = method.getCode().getExceptions(); @@ -99,7 +101,7 @@ public class RenameUnique implements Deobfuscator new net.runelite.deob.pool.Class(field.getFields().getClassFile().getName()), new NameAndType(name, field.getType()) ); - instructions.renameField(field, newField); + //instructions.renameField(field, newField); } } } @@ -183,7 +185,7 @@ public class RenameUnique implements Deobfuscator new net.runelite.deob.pool.Class(m.getMethods().getClassFile().getName()), new NameAndType(name, m.getNameAndType().getDescriptor()) ); - instructions.renameMethod(m, newMethod); + //instructions.renameMethod(m, newMethod); } } } @@ -192,36 +194,45 @@ public class RenameUnique implements Deobfuscator for (Method m : methods) m.setName(name); } - - @Override - public void run(ClassGroup group) + + private NameMappings generateClassNames(ClassGroup group) { + NameMappings map = new NameMappings(); int i = 0; - int classes = 0, fields = 0, methods = 0; - - group.buildClassGraph(); for (ClassFile cf : group.getClasses()) { if (cf.getName().length() > 2) continue; - renameClass(group, cf, "class" + i++); - ++classes; + map.map(cf.getPoolClass(), "class" + i++); } - // rename fields + return map; + } + + private NameMappings generatFieldNames(ClassGroup group) + { + NameMappings map = new NameMappings(); + int i = 0; + for (ClassFile cf : group.getClasses()) for (Field field : cf.getFields().getFields()) { if (field.getName().length() > 2) continue; - renameField(group, field, "field" + i++); - ++fields; + map.map(field.getPoolField(), "field" + i++); } - // rename methods + return map; + } + + private NameMappings generateMethodNames(ClassGroup group) + { + NameMappings map = new NameMappings(); + int i = 0; + for (ClassFile cf : group.getClasses()) for (Method method : cf.getMethods().getMethods()) { @@ -237,10 +248,99 @@ public class RenameUnique implements Deobfuscator else name = "vmethod" + i++; - renameMethod(group, virtualMethods, name); + for (Method m : virtualMethods) + map.map(m.getPoolMethod(), name); + } + + return map; + } + + private void lookup(ClassGroup group) + { + for (ClassFile cf : group.getClasses()) + for (Method m : cf.getMethods().getMethods()) + { + Code c = m.getCode(); + if (c == null) + continue; + + c.getInstructions().lookup(); + } + } + + private void regeneratePool(ClassGroup group) + { + for (ClassFile cf : group.getClasses()) + for (Method m : cf.getMethods().getMethods()) + { + Code c = m.getCode(); + if (c == null) + continue; + + c.getInstructions().regeneratePool(); + } + } + + @Override + public void run(ClassGroup group) + { + group.buildClassGraph(); + lookup(group); + + NameMappings mappings = this.generateClassNames(group); + + //renameIns(group, mappings); + + int i = 0; + int classes = 0, fields = 0, methods = 0; + + for (ClassFile cf : group.getClasses()) + { + String newName = mappings.get(cf.getPoolClass()); + if (newName == null) + continue; + + renameClass(group, cf, newName); + ++classes; + } + + mappings = this.generatFieldNames(group); + + //renameIns(group, mappings); + + // rename fields + for (ClassFile cf : group.getClasses()) + for (Field field : cf.getFields().getFields()) + { + String newName = mappings.get(field.getPoolField()); + if (newName == null) + continue; + + renameField(group, field, newName); + ++fields; + } + + mappings = this.generateMethodNames(group); + + //renameIns(group, mappings); + + // rename methods + for (ClassFile cf : group.getClasses()) + for (Method method : cf.getMethods().getMethods()) + { + String newName = mappings.get(method.getPoolMethod()); + if (newName == null) + continue; + + List virtualMethods = getVirutalMethods(method); + assert !virtualMethods.isEmpty(); + + renameMethod(group, virtualMethods, newName); methods += virtualMethods.size(); } + this.regeneratePool(group); + System.out.println("Uniquely renamed " + classes + " classes, " + fields + " fields, and " + methods + " methods"); } } diff --git a/src/main/java/net/runelite/deob/pool/Method.java b/src/main/java/net/runelite/deob/pool/Method.java index 91d2e34d44..6b68b89d79 100644 --- a/src/main/java/net/runelite/deob/pool/Method.java +++ b/src/main/java/net/runelite/deob/pool/Method.java @@ -5,6 +5,7 @@ import net.runelite.deob.ConstantPool; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Objects; public class Method extends PoolEntry { @@ -51,6 +52,15 @@ public class Method extends PoolEntry Method m = (Method) other; return clazz.equals(m.clazz) && nat.equals(m.nat); } + + @Override + public int hashCode() + { + int hash = 7; + hash = 67 * hash + Objects.hashCode(this.clazz); + hash = 67 * hash + Objects.hashCode(this.nat); + return hash; + } public Class getClassEntry() { diff --git a/src/main/java/net/runelite/deob/signature/Signature.java b/src/main/java/net/runelite/deob/signature/Signature.java index d03abebd5d..37b6316ed7 100644 --- a/src/main/java/net/runelite/deob/signature/Signature.java +++ b/src/main/java/net/runelite/deob/signature/Signature.java @@ -33,8 +33,9 @@ public class Signature public Signature(Signature other) { - rv = other.rv; - arguments.addAll(other.arguments); + rv = new Type(other.rv); + for (Type t : other.arguments) + arguments.add(new Type(t)); } @Override diff --git a/src/main/java/net/runelite/deob/signature/Type.java b/src/main/java/net/runelite/deob/signature/Type.java index f3b9ee397d..216bf16964 100644 --- a/src/main/java/net/runelite/deob/signature/Type.java +++ b/src/main/java/net/runelite/deob/signature/Type.java @@ -22,6 +22,12 @@ public class Type this.arrayDimms = dimms; } + public Type(Type other) + { + type = other.type; + arrayDimms = other.arrayDimms; + } + public String getType() { return type; diff --git a/src/main/java/net/runelite/deob/util/NameMappings.java b/src/main/java/net/runelite/deob/util/NameMappings.java new file mode 100644 index 0000000000..b3303fbeea --- /dev/null +++ b/src/main/java/net/runelite/deob/util/NameMappings.java @@ -0,0 +1,32 @@ +package net.runelite.deob.util; + +import java.util.HashMap; +import java.util.Map; +import net.runelite.deob.pool.Class; +import net.runelite.deob.pool.Field; +import net.runelite.deob.pool.Method; + +public class NameMappings +{ + private final Map map = new HashMap<>(); + + public void map(Class cf, String name) + { + map.put(cf, name); + } + + public void map(Field field, String name) + { + map.put(field, name); + } + + public void map(Method method, String name) + { + map.put(method, name); + } + + public String get(Object object) + { + return map.get(object); + } +}