diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java new file mode 100644 index 0000000000..b509bddb85 --- /dev/null +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java @@ -0,0 +1,113 @@ +package net.runelite.deob.deobfuscators.mapping; + +import java.util.ArrayList; +import java.util.List; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.Field; +import net.runelite.asm.Method; +import net.runelite.asm.attributes.Annotations; +import net.runelite.asm.attributes.Attributes; +import net.runelite.asm.signature.Type; + +public class AnnotationIntegrityChecker +{ + private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;"); + + private ClassGroup one, two; + private ParallelExecutorMapping mapping; + + public AnnotationIntegrityChecker(ClassGroup one, ClassGroup two, ParallelExecutorMapping mapping) + { + this.one = one; + this.two = two; + this.mapping = mapping; + } + + public void run() + { + for (ClassFile cf : one.getClasses()) + { + ClassFile other = (ClassFile) mapping.get(cf); + + List exf1 = getExportedFields(cf); + List exm1 = getExportedMethods(cf); + + for (Field f1 : exf1) + { + if (f1.isStatic()) + continue; + + Field f2 = findExportedField(other, getExportedName(f1.getAttributes())); + + if (f2 == null) + { + System.out.println("Missing exported field on " + other + " named " + getExportedName(f1.getAttributes())); + } + } + + for (Method m1 : exm1) + { + if (m1.isStatic()) + continue; + + Method m2 = findExportedMethod(other, getExportedName(m1.getAttributes())); + + if (m2 == null) + { + System.out.println("Missing exported method on " + other + " named " + getExportedName(m1.getAttributes())); + } + } + } + } + + private List getExportedFields(ClassFile clazz) + { + List list = new ArrayList<>(); + for (Field f : clazz.getFields().getFields()) + { + if (getExportedName(f.getAttributes()) != null) + list.add(f); + } + return list; + } + + private List getExportedMethods(ClassFile clazz) + { + List list = new ArrayList<>(); + for (Method m : clazz.getMethods().getMethods()) + { + if (getExportedName(m.getAttributes()) != null) + list.add(m); + } + return list; + } + + private String getExportedName(Attributes attr) + { + Annotations an = attr.getAnnotations(); + + if (an == null || an.find(EXPORT) == null) + { + return null; + } + + return an.find(EXPORT).getElement().getString(); + } + + private Field findExportedField(ClassFile clazz, String name) + { + for (Field f : getExportedFields(clazz)) + if (getExportedName(f.getAttributes()).equals(name)) + return f; + return null; + } + + private Method findExportedMethod(ClassFile clazz, String name) + { + for (Method m : getExportedMethods(clazz)) + if (getExportedName(m.getAttributes()).equals(name)) + return m; + return null; + } +} diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java index 4a11287be7..f40815e9ce 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java @@ -29,19 +29,11 @@ public class AnnotationMapper public void run() { int count = 0; - - ClassGroupMapper m = new ClassGroupMapper(source, target); - m.map(); for (ClassFile c : source.getClasses()) { - ClassFile other = m.get(c); - - if (other == null) - { - other = (ClassFile) mapping.get(c); - System.out.println("FALLBACK " + c + " -> " + other); - } + ClassFile other = (ClassFile) mapping.get(c); + System.out.println(c + " -> " + other); if (other == null) { diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/ClassMapper.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/ClassMapper.java index e8cf1bdeed..d4958703fd 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/mapping/ClassMapper.java +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/ClassMapper.java @@ -1,7 +1,6 @@ package net.runelite.deob.deobfuscators.mapping; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/ExecutionMapper.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/ExecutionMapper.java index 99d1da66c5..50f73d39f1 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/mapping/ExecutionMapper.java +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/ExecutionMapper.java @@ -23,6 +23,7 @@ public class ExecutionMapper public ParallelExecutorMapping run() { ParallelExecutorMapping highest = null; + boolean multiple = false; for (Method m : methods2) { @@ -30,9 +31,19 @@ public class ExecutionMapper mappings.put(m, mapping); if (highest == null || mapping.same > highest.same) + { highest = mapping; + multiple = false; + } + else if (mapping.same == highest.same) + { + multiple = true; + } } + if (multiple) + return null; + return highest; } } diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/Mapper.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/Mapper.java index 292931cb6c..744f55589d 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/mapping/Mapper.java +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/Mapper.java @@ -59,6 +59,9 @@ public class Mapper ExecutionMapper em = new ExecutionMapper(m, methods); ParallelExecutorMapping mapping = em.run(); + if (mapping == null) + continue; + mapping.map(mapping.m1, mapping.m2); pmes.add(mapping); @@ -85,6 +88,9 @@ public class Mapper ExecutionMapper em = new ExecutionMapper(m, methods); ParallelExecutorMapping mapping = em.run(); + if (mapping == null) + continue; + mapping.map(mapping.m1, mapping.m2); pmes.add(mapping); @@ -129,7 +135,6 @@ public class Mapper PacketHandler highestHandler = null; ParallelExecutorMapping highest = null; - int maxContradictions = 0; for (int j = 0; j < mappings.packetHandler2.size(); ++j) { @@ -148,22 +153,12 @@ public class Mapper int p = pem.contradicts(mapping); - if (if1.getPacketId() == 9 && (if2.getPacketId() == 25 || if2.getPacketId() == 187)) - { - int i444 =6; - pem.contradicts(mapping); - } - - //if (highest == null || p < maxContradictions) if (highest == null || mapping.getMap().size() > highest.getMap().size()) { if (p == 0 && mapping.crashed == false) - //if (p == 0) - //if (!pem.contradicts(mapping)) { highest = mapping; highestHandler = if2; - maxContradictions = p; } } } @@ -171,7 +166,6 @@ public class Mapper if (highest == null) { continue; - //int i44 = 5; } System.out.println(if1 + " <-> " + highestHandler + " <-> " + highest.getMap().size() + " " + highest.crashed); all.merge(highest); diff --git a/src/main/java/net/runelite/deob/deobfuscators/mapping/ParallelExecutorMapping.java b/src/main/java/net/runelite/deob/deobfuscators/mapping/ParallelExecutorMapping.java index f49b802e74..115b3a007a 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/mapping/ParallelExecutorMapping.java +++ b/src/main/java/net/runelite/deob/deobfuscators/mapping/ParallelExecutorMapping.java @@ -33,7 +33,7 @@ public class ParallelExecutorMapping @Override public String toString() { - return "ParallelExecutorMapping{size = " + map.size() + ", crashed = " + crashed + "}"; + return "ParallelExecutorMapping{size = " + map.keySet().size() + ", crashed = " + crashed + ", same = " + same + "}"; } private Mapping getMapping(Object from, Object to) @@ -143,6 +143,29 @@ public class ParallelExecutorMapping mapClass(key, value); } + + /* get leftover classes, they usually contain exclusively static + * fields and methods so they're hard to pinpoint + */ + ClassGroupMapper m = new ClassGroupMapper(group, group2); + m.map(); + + for (ClassFile cf : group.getClasses()) + if (!map.containsKey(cf)) + { + ClassFile other = m.get(cf); + if (other == null) + { + System.out.println("Unable to map class " + cf); + } + else + { + System.out.println("Build classes fallback " + cf + " -> " + other); + + Mapping ma = getMapping(cf, other); + ma.inc(); + } + } } public Object get(Object o) diff --git a/src/test/java/net/runelite/deob/deobfuscators/rename/AnnotationMapperTest.java b/src/test/java/net/runelite/deob/deobfuscators/rename/AnnotationMapperTest.java index 182b55904b..94756f51fc 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/rename/AnnotationMapperTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/rename/AnnotationMapperTest.java @@ -3,14 +3,21 @@ package net.runelite.deob.deobfuscators.rename; import java.io.File; import java.io.IOException; import net.runelite.asm.ClassGroup; -import net.runelite.deob.updater.UpdateMappings; +import net.runelite.asm.Method; +import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker; +import net.runelite.deob.deobfuscators.mapping.AnnotationMapper; +import net.runelite.deob.deobfuscators.mapping.Mapper; +import net.runelite.deob.deobfuscators.mapping.MappingExecutorUtil; +import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping; +import static net.runelite.deob.deobfuscators.rename.MapStaticTest.print; +import static net.runelite.deob.deobfuscators.rename.MapStaticTest.summary; import net.runelite.deob.util.JarUtil; import org.junit.Test; public class AnnotationMapperTest { private static final String JAR1 = "C:\\Users\\Adam\\.m2\\repository\\net\\runelite\\rs\\rs-client\\1.0-SNAPSHOT\\rs-client-1.0-SNAPSHOT.jar", - JAR2 = "d:/rs/07/gamepack_v21_deobfuscated.jar", + JAR2 = "d:/rs/07/gamepack_113_deobfuscated.jar", OUT = "d:/rs/07/adamout.jar"; @Test @@ -19,10 +26,30 @@ public class AnnotationMapperTest ClassGroup group1 = JarUtil.loadJar(new File(JAR1)); ClassGroup group2 = JarUtil.loadJar(new File(JAR2)); - UpdateMappings um = new UpdateMappings(group1, group2); - um.update(); + Mapper mapper = new Mapper(group1, group2); + mapper.run(); + ParallelExecutorMapping mapping = mapper.getMapping(); - um.save(new File(OUT)); + summary(mapping, group1); + + String sg1 = print(group1), + sg2 = print(group2); + + System.out.println("GROUP 1 " + sg1); + System.out.println("GROUP 2 " + sg2); + + Method m1 = group1.findClass("class199").findMethod("method3902"); + Method m2 = (Method) mapping.get(m1); + + MappingExecutorUtil.map(m1, m2); + + AnnotationMapper amapper = new AnnotationMapper(group1, group2, mapping); + amapper.run(); + + AnnotationIntegrityChecker aic = new AnnotationIntegrityChecker(group1, group2, mapping); + aic.run(); + + JarUtil.saveJar(group2, new File(OUT)); } }