Add annotation integrity checker, if execution mapper can't decide return null

This commit is contained in:
Adam
2016-04-22 19:07:50 -04:00
parent 2af1cfb7fe
commit 3174cc49d5
7 changed files with 188 additions and 29 deletions

View File

@@ -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<Field> exf1 = getExportedFields(cf);
List<Method> 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<Field> getExportedFields(ClassFile clazz)
{
List<Field> list = new ArrayList<>();
for (Field f : clazz.getFields().getFields())
{
if (getExportedName(f.getAttributes()) != null)
list.add(f);
}
return list;
}
private List<Method> getExportedMethods(ClassFile clazz)
{
List<Method> 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;
}
}

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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));
}
}