Begin moving code to do mapping to core. Write out annotation mapper.

This commit is contained in:
Adam
2016-02-28 19:39:16 -05:00
parent 7b46ae596f
commit a16a8a5a38
20 changed files with 3036 additions and 486 deletions

View File

@@ -146,4 +146,9 @@ public class Attributes
element.setValue(value);
annotation.addElement(element);
}
public Annotations getAnnotations()
{
return (Annotations) findType(AttributeType.RUNTIMEVISIBLEANNOTATIONS);
}
}

View File

@@ -0,0 +1,119 @@
package net.runelite.deob.deobfuscators.rename;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Field;
import net.runelite.deob.Method;
import net.runelite.deob.attributes.Attributes;
import net.runelite.deob.attributes.annotation.Annotation;
import net.runelite.deob.attributes.annotation.Element;
import net.runelite.deob.signature.Type;
public class AnnotationMapper
{
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
private static final Type IMPLEMENTS = new Type("Lnet/runelite/mapping/Implements;");
private final ClassGroup source, target;
private final ParallelExecutorMapping mapping;
public AnnotationMapper(ClassGroup source, ClassGroup target, ParallelExecutorMapping mapping)
{
this.source = source;
this.target = target;
this.mapping = mapping;
}
public void run()
{
int count = 0;
for (ClassFile c : source.getClasses())
{
ClassFile other = target.findClass(c.getName());
if (other == null)
continue;
count += run(c, other);
}
System.out.println("Copied " + count + " annotations");
}
private int run(ClassFile from, ClassFile to)
{
int count = 0;
count += copyAnnotations(from.getAttributes(), to.getAttributes());
for (Field f : from.getFields().getFields())
{
if (!hasCopyableAnnotation(f.getAttributes()))
continue;
Field other = (Field) mapping.get(f);
if (other == null)
{
assert false;
}
count += copyAnnotations(f.getAttributes(), other.getAttributes());
}
for (Method m : to.getMethods().getMethods())
{
if (!hasCopyableAnnotation(m.getAttributes()))
continue;
Method other = (Method) mapping.get(m);
if (other == null)
{
assert false;
}
count += copyAnnotations(m.getAttributes(), other.getAttributes());
}
return count;
}
private int copyAnnotations(Attributes from, Attributes to)
{
int count = 0;
if (from.getAnnotations() == null)
return count;
for (Annotation a : from.getAnnotations().getAnnotations())
{
if (isCopyable(a))
{
assert a.getElements().size() == 1;
Element e = a.getElements().get(0);
to.addAnnotation(a.getType(), e.getType().toString(), e.getValue().copy());
++count;
}
}
return count;
}
private boolean hasCopyableAnnotation(Attributes a)
{
if (a.getAnnotations() == null)
return false;
for (Annotation an : a.getAnnotations().getAnnotations())
if (isCopyable(an))
return true;
return false;
}
private boolean isCopyable(Annotation a)
{
return a.getType().equals(EXPORT) || a.getType().equals(IMPLEMENTS);
}
}

View File

@@ -0,0 +1,199 @@
package net.runelite.deob.deobfuscators.rename;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Method;
import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.execution.ParallellMappingExecutor;
public class Mapper
{
private static final int MAX_CLASSES = 250;
private final ClassGroup source, target;
private ParallelExecutorMapping mapping;
public Mapper(ClassGroup source, ClassGroup target)
{
this.source = source;
this.target = target;
}
public ParallelExecutorMapping getMapping()
{
return mapping;
}
public void run()
{
ParallelExecutorMapping finalm = new ParallelExecutorMapping(source, target);
finalm.merge(mapStaticMethods(source, target));
finalm.merge(mapMethods(source, target));
finalm.merge(mapPackets(source, target));
mapping = finalm;
}
private ParallelExecutorMapping mapMethods(ClassGroup one, ClassGroup two)
{
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (int i = -1; i < MAX_CLASSES; ++i)
{
ClassFile c1, c2;
if (i == -1)
{
c1 = one.findClass("client");
c2 = two.findClass("client");
}
else
{
c1 = one.findClass("class" + i);
c2 = two.findClass("class" + i);
}
if (c1 == null || c2 == null)
continue;
MethodSignatureMapper msm = new MethodSignatureMapper();
msm.map(c1, c2);
Multimap<Method, Method> map = msm.getMap();
for (Method m : map.keySet())
{
Collection<Method> methods = map.get(m);
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
}
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
}
private ParallelExecutorMapping mapStaticMethods(ClassGroup one, ClassGroup two)
{
StaticMethodSignatureMapper smsm = new StaticMethodSignatureMapper();
smsm.map(one, two);
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (Method m : smsm.getMap().keySet())
{
Collection<Method> methods = smsm.getMap().get(m);
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
}
private void map(Map<Object, Object> all, List<ParallelExecutorMapping> result, Method m1, Method m2)
{
if (all.containsKey(m1))
return;
all.put(m1, m2);
assert (m1.getCode() == null) == (m2.getCode() == null);
if (m1.getCode() == null)
return;
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
if (mappings.getMap().isEmpty() && mappings.crashed)
return;
mappings.map(m1, m2);
result.add(mappings);
for (Map.Entry<Object, Object> e : mappings.getMap().entrySet())
{
if (e.getKey() instanceof Method)
{
Method n1 = (Method) e.getKey(),
n2 = (Method) e.getValue();
map(all, result, n1, n2);
}
else
{
all.put(e.getKey(), e.getValue());
}
}
}
private ParallelExecutorMapping mapPackets(ClassGroup group1, ClassGroup group2)
{
// XXX PULL THESE FROM PREVIOUS MAPPINGS
group1.findClass("client").findField("field446").packetHandler = true;
group2.findClass("client").findField("field324").packetHandler = true;
Method m1 = group1.findClass("client").findMethod("vmethod3096");
Method m2 = group2.findClass("client").findMethod("vmethod2975");
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
System.out.println(mappings.packetHandler1.size() + " vs " + mappings.packetHandler2.size() + " handlers");
assert mappings.packetHandler1.size() == mappings.packetHandler2.size();
ParallellMappingExecutor.enable = true;
ParallelExecutorMapping all = new ParallelExecutorMapping(group1, group2);
for (int i = 0; i < mappings.packetHandler1.size(); ++i)
{
PacketHandler if1 = mappings.packetHandler1.get(i);
PacketHandler highestHandler = null;
ParallelExecutorMapping highest = null;
for (int j = 0; j < mappings.packetHandler2.size(); ++j)
{
PacketHandler if2 = mappings.packetHandler2.get(j);
Instruction i1 = if1.getFirstInsOfHandler(),
i2 = if2.getFirstInsOfHandler();
ParallelExecutorMapping mapping = MappingExecutorUtil.mapFrame(group1, group2, i1, i2);
if (mapping.getMap().isEmpty())
continue;
if (highest == null || mapping.getMap().size() > highest.getMap().size())
{
highest = mapping;
highestHandler = if2;
}
}
System.out.println(if1 + " <-> " + highestHandler + " <-> " + highest.getMap().size() + " " + highest.crashed);
all.merge(highest);
}
ParallellMappingExecutor.enable = false;
return all;
}
}

View File

@@ -1,173 +0,0 @@
package net.runelite.deob.deobfuscators.rename;
import com.google.common.collect.Multimap;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Field;
import net.runelite.deob.Method;
import net.runelite.deob.util.JarUtil;
public class Rename
{
private static final int MAX_CLASSES = 250;
private ClassGroup source, target;
private ParallelExecutorMapping mapping;
public Rename(ClassGroup source, ClassGroup target)
{
this.source = source;
this.target = target;
}
public ParallelExecutorMapping getMapping()
{
return mapping;
}
public void run()
{
ParallelExecutorMapping finalm = new ParallelExecutorMapping(source, target);
finalm.merge(staticMethodSignatureMapper());
finalm.merge(methodSignatureMapper());
for (int i = -1; i < MAX_CLASSES; ++i)
{
ClassFile c1;
if (i == -1)
{
c1 = source.findClass("client");
}
else
{
c1 = source.findClass("class" + i);
}
if (c1 == null)
continue;
for (Method m : c1.getMethods().getMethods())
{
if (!finalm.getMap().containsKey(m))
System.out.println("missing " + m);
}
for (Field m : c1.getFields().getFields())
{
if (!finalm.getMap().containsKey(m))
System.out.println("missing " + m);
}
}
mapping = finalm;
}
private ParallelExecutorMapping methodSignatureMapper()
{
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (int i = -1; i < MAX_CLASSES; ++i)
{
ClassFile c1, c2;
if (i == -1)
{
c1 = source.findClass("client");
c2 = target.findClass("client");
}
else
{
c1 = source.findClass("class" + i);
c2 = target.findClass("class" + i);
}
if (c1 == null || c2 == null)
continue;
MethodSignatureMapper msm = new MethodSignatureMapper();
msm.map(c1, c2);
Multimap<Method, Method> map = msm.getMap();
for (Method m : map.keySet())
{
Collection<Method> methods = map.get(m);
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
}
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(source, target);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
}
private ParallelExecutorMapping staticMethodSignatureMapper()
{
StaticMethodSignatureMapper smsm = new StaticMethodSignatureMapper();
smsm.map(source, target);
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (Method m : smsm.getMap().keySet())
{
Collection<Method> methods = smsm.getMap().get(m);
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(source, target);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
}
private void map(Map<Object, Object> all, List<ParallelExecutorMapping> result, Method m1, Method m2)
{
if (all.containsKey(m1))
return;
all.put(m1, m2);
assert (m1.getCode() == null) == (m2.getCode() == null);
if (m1.getCode() == null)
return;
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
if (mappings.getMap().isEmpty() && mappings.crashed)
return;
mappings.map(m1, m2);
result.add(mappings);
for (Map.Entry<Object, Object> e : mappings.getMap().entrySet())
{
if (e.getKey() instanceof Method)
{
Method n1 = (Method) e.getKey(),
n2 = (Method) e.getValue();
map(all, result, n1, n2);
}
}
}
}

View File

@@ -35,6 +35,12 @@ public class Class extends PoolEntry
this.name = name;
}
@Override
public Class copy()
{
return new Class(name);
}
@Override
public void resolve(ConstantPool pool)

View File

@@ -24,6 +24,12 @@ public class Double extends PoolEntry
value = d;
}
@Override
public Double copy()
{
return new Double(value);
}
@Override
public boolean equals(Object other)

View File

@@ -27,6 +27,12 @@ public class Field extends PoolEntry
this.clazz = clazz;
this.nat = nat;
}
@Override
public Field copy()
{
return new Field(clazz.copy(), nat.copy());
}
@Override
public void resolve(ConstantPool pool)

View File

@@ -24,6 +24,12 @@ public class Float extends PoolEntry
value = f;
}
@Override
public Float copy()
{
return new Float(value);
}
@Override
public boolean equals(Object other)

View File

@@ -24,6 +24,12 @@ public class Integer extends PoolEntry
value = i;
}
@Override
public Integer copy()
{
return new Integer(value);
}
@Override
public boolean equals(Object other)

View File

@@ -28,6 +28,12 @@ public class InterfaceMethod extends PoolEntry
classIndex = is.readUnsignedShort();
natIndex = is.readUnsignedShort();
}
@Override
public InterfaceMethod copy()
{
return new InterfaceMethod(clazz.copy(), nat.copy());
}
@Override
public void resolve(ConstantPool pool)

View File

@@ -24,6 +24,12 @@ public class Long extends PoolEntry
value = l;
}
@Override
public Long copy()
{
return new Long(value);
}
@Override
public boolean equals(Object other)

View File

@@ -29,6 +29,12 @@ public class Method extends PoolEntry
natIndex = is.readUnsignedShort();
}
@Override
public Method copy()
{
return new Method(clazz.copy(), nat.copy());
}
@Override
public java.lang.String toString()
{

View File

@@ -41,6 +41,24 @@ public class NameAndType extends PoolEntry
this.name = name;
this.type = type;
}
@Override
public NameAndType copy()
{
if (signature != null)
{
return new NameAndType(name, new Signature(signature));
}
else if (type != null)
{
return new NameAndType(name, new Type(type));
}
else
{
assert false;
return null;
}
}
@Override
public void resolve(ConstantPool pool)

View File

@@ -31,6 +31,8 @@ public abstract class PoolEntry
@Override
public abstract int hashCode();
public abstract PoolEntry copy();
public abstract void write(DataOutputStream out) throws IOException;

View File

@@ -26,6 +26,12 @@ public class String extends PoolEntry
string = str;
}
@Override
public String copy()
{
return new String(string);
}
@Override
public void resolve(ConstantPool pool)

View File

@@ -24,6 +24,12 @@ public class UTF8 extends PoolEntry
string = value;
}
@Override
public UTF8 copy()
{
return new UTF8(string);
}
@Override
public boolean equals(Object other)

View File

@@ -0,0 +1,28 @@
package net.runelite.deob.deobfuscators.rename;
import java.io.File;
import java.io.IOException;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.util.JarUtil;
import org.junit.Test;
public class AnnotationMapperTest
{
private static final String JAR1 = MapStaticTest.class.getResource("/adamin1.jar").getFile(),
JAR2 = MapStaticTest.class.getResource("/adamin2.jar").getFile();
@Test
public void testRun() throws IOException
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
Mapper mapper = new Mapper(group1, group2);
mapper.run();
ParallelExecutorMapping mapping = mapper.getMapping();
AnnotationMapper amapper = new AnnotationMapper(group1, group2, mapping);
amapper.run();
}
}

View File

@@ -197,210 +197,210 @@ public class MapStaticTest
System.out.println("Total " + total + ". " + fields + " fields, " + staticMethod + " static methods, " + method + " methods");
}
@Test
public void testAllMap() throws Exception
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
List<Method> 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();
List<ParallelExecutorMapping> pmes = new ArrayList<>();
// for (int i = 0; i < m1s.size(); ++i)
// @Test
// public void testAllMap() throws Exception
// {
// ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
// ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
//
// List<Method> 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();
//
// List<ParallelExecutorMapping> pmes = new ArrayList<>();
//// for (int i = 0; i < m1s.size(); ++i)
//// {
//// Method m1 = m1s.get(i), m2 = m2s.get(i);
////
//// assert m1.getPoolMethod().equals(m2.getPoolMethod());
////
//// HashMap<Object, Object> all = new HashMap();
//// map(all, pmes, m1, m2);/fil
//// }
//
// ParallelExecutorMapping finalm = new ParallelExecutorMapping(group1, group2);
// for (ParallelExecutorMapping pme : pmes)
// finalm.merge(pme);
//
//
// finalm.merge(testStaticMapperMap(group1, group2));
// finalm.merge(testMapperMap(group1, group2));
// finalm.merge(this.testPackets(group1, group2));
//
// for (int i = -1; i < 250; ++i)
// {
// Method m1 = m1s.get(i), m2 = m2s.get(i);
//
// assert m1.getPoolMethod().equals(m2.getPoolMethod());
//
// HashMap<Object, Object> all = new HashMap();
// map(all, pmes, m1, m2);/fil
// ClassFile c1;
//
// if (i == -1)
// {
// c1 = group1.findClass("client");
// }
// else
// {
// c1 = group1.findClass("class" + i);
// }
//
// if (c1 == null)
// continue;
//
// for (Method m : c1.getMethods().getMethods())
// {
// if (!finalm.getMap().containsKey(m))
// System.out.println("missing " + m);
// }
// for (Field m : c1.getFields().getFields())
// {
// if (!finalm.getMap().containsKey(m))
// System.out.println("missing " + m);
// }
// }
ParallelExecutorMapping finalm = new ParallelExecutorMapping(group1, group2);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
finalm.merge(testStaticMapperMap(group1, group2));
finalm.merge(testMapperMap(group1, group2));
finalm.merge(this.testPackets(group1, group2));
for (int i = -1; i < 250; ++i)
{
ClassFile c1;
if (i == -1)
{
c1 = group1.findClass("client");
}
else
{
c1 = group1.findClass("class" + i);
}
if (c1 == null)
continue;
for (Method m : c1.getMethods().getMethods())
{
if (!finalm.getMap().containsKey(m))
System.out.println("missing " + m);
}
for (Field m : c1.getFields().getFields())
{
if (!finalm.getMap().containsKey(m))
System.out.println("missing " + m);
}
}
summary(finalm, group1);
String sg1 = print(group1),
sg2 = print(group2);
System.out.println("GROUP 1 " + sg1);
System.out.println("GROUP 2 " + sg2);
}
//
// summary(finalm, group1);
//
// String sg1 = print(group1),
// sg2 = print(group2);
//
// System.out.println("GROUP 1 " + sg1);
// System.out.println("GROUP 2 " + sg2);
// }
//@Test
public ParallelExecutorMapping testMapperMap(ClassGroup one, ClassGroup two) throws IOException
{
// ClassGroup one = JarUtil.loadJar(new File(JAR1));
// ClassGroup two = JarUtil.loadJar(new File(JAR2));
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (int i = -1; i < 250; ++i)
{
ClassFile c1, c2;
if (i == -1)
{
c1 = one.findClass("client");
c2 = two.findClass("client");
}
else
{
c1 = one.findClass("class" + i);
c2 = two.findClass("class" + i);
}
if (c1 == null || c2 == null)
continue;
MethodSignatureMapper msm = new MethodSignatureMapper();
msm.map(c1, c2);
Multimap<Method, Method> map = msm.getMap();
for (Method m : map.keySet())
{
Collection<Method> methods = map.get(m);
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
// ParallelExecutorMapping pme = MappingExecutorUtil.map(m, other);
//
// if (pme.getMap().isEmpty())
// continue;
//
// pme.map(m, other);
//
// pmes.add(pme);
}
//HashMap<Object, Object> all = new HashMap();
//map(all, pmes, e.getKey(), e.getValue());
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
// summary(finalm);
// print(one);
}
// public ParallelExecutorMapping testMapperMap(ClassGroup one, ClassGroup two) throws IOException
// {
//// ClassGroup one = JarUtil.loadJar(new File(JAR1));
//// ClassGroup two = JarUtil.loadJar(new File(JAR2));
//
// List<ParallelExecutorMapping> pmes = new ArrayList<>();
// for (int i = -1; i < 250; ++i)
// {
// ClassFile c1, c2;
//
// if (i == -1)
// {
// c1 = one.findClass("client");
// c2 = two.findClass("client");
// }
// else
// {
// c1 = one.findClass("class" + i);
// c2 = two.findClass("class" + i);
// }
//
// if (c1 == null || c2 == null)
// continue;
//
// MethodSignatureMapper msm = new MethodSignatureMapper();
// msm.map(c1, c2);
//
// Multimap<Method, Method> map = msm.getMap();
// for (Method m : map.keySet())
// {
// Collection<Method> methods = map.get(m);
//
// for (Method other : methods)
// {
// HashMap<Object, Object> all = new HashMap();
// map(all, pmes, m, other);
//// ParallelExecutorMapping pme = MappingExecutorUtil.map(m, other);
////
//// if (pme.getMap().isEmpty())
//// continue;
////
//// pme.map(m, other);
////
//// pmes.add(pme);
// }
// //HashMap<Object, Object> all = new HashMap();
// //map(all, pmes, e.getKey(), e.getValue());
// }
// }
// ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
// for (ParallelExecutorMapping pme : pmes)
// finalm.merge(pme);
//
// return finalm;
//// summary(finalm);
//// print(one);
// }
//@Test
public ParallelExecutorMapping testStaticMapperMap(ClassGroup one, ClassGroup two) throws IOException
{
// ClassGroup one = JarUtil.loadJar(new File(JAR1));
// ClassGroup two = JarUtil.loadJar(new File(JAR2));
StaticMethodSignatureMapper smsm = new StaticMethodSignatureMapper();
smsm.map(one, two);
List<ParallelExecutorMapping> pmes = new ArrayList<>();
for (Method m : smsm.getMap().keySet())
{
Collection<Method> methods = smsm.getMap().get(m);
//if (methods.size() >= 1)
{
for (Method other : methods)
{
HashMap<Object, Object> all = new HashMap();
map(all, pmes, m, other);
// ParallelExecutorMapping pme = MappingExecutorUtil.map(m, other);
//
// if (pme.getMap().isEmpty())
// continue;
//
// pme.map(m, other);
//
// pmes.add(pme);
}
}
}
ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
for (ParallelExecutorMapping pme : pmes)
finalm.merge(pme);
return finalm;
// summary(finalm);
// print(one);
}
// public ParallelExecutorMapping testStaticMapperMap(ClassGroup one, ClassGroup two) throws IOException
// {
//// ClassGroup one = JarUtil.loadJar(new File(JAR1));
//// ClassGroup two = JarUtil.loadJar(new File(JAR2));
//
// StaticMethodSignatureMapper smsm = new StaticMethodSignatureMapper();
// smsm.map(one, two);
//
// List<ParallelExecutorMapping> pmes = new ArrayList<>();
//
// for (Method m : smsm.getMap().keySet())
// {
// Collection<Method> methods = smsm.getMap().get(m);
//
// //if (methods.size() >= 1)
// {
// for (Method other : methods)
// {
// HashMap<Object, Object> all = new HashMap();
// map(all, pmes, m, other);
//
//// ParallelExecutorMapping pme = MappingExecutorUtil.map(m, other);
////
//// if (pme.getMap().isEmpty())
//// continue;
////
//// pme.map(m, other);
////
//// pmes.add(pme);
// }
// }
// }
//
// ParallelExecutorMapping finalm = new ParallelExecutorMapping(one, two);
// for (ParallelExecutorMapping pme : pmes)
// finalm.merge(pme);
//
// return finalm;
//// summary(finalm);
//// print(one);
// }
public List<Method> getInitialMethods(ClassGroup group)
{
List<Method> methods = new ArrayList<>();
group.buildClassGraph(); // required when looking up methods
group.lookup(); // lookup methods
for (ClassFile cf : group.getClasses())
{
List<Method> cmethods = new ArrayList<>();
for (Method m : cf.getMethods().getMethods())
{
if (!Deob.isObfuscated(m.getName()) && !m.getName().startsWith("<"))
{
if (m.getCode() == null)
{
methods.add(m);
continue;
}
cmethods.add(m); // I guess this method name is overriding a jre interface (init, run, ?).
}
}
// cmethods are scrambled randomally, so sort by name
cmethods = cmethods.stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
methods.addAll(cmethods);
}
return methods;
}
// public List<Method> getInitialMethods(ClassGroup group)
// {
// List<Method> methods = new ArrayList<>();
//
// group.buildClassGraph(); // required when looking up methods
// group.lookup(); // lookup methods
//
// for (ClassFile cf : group.getClasses())
// {
// List<Method> cmethods = new ArrayList<>();
//
// for (Method m : cf.getMethods().getMethods())
// {
// if (!Deob.isObfuscated(m.getName()) && !m.getName().startsWith("<"))
// {
// if (m.getCode() == null)
// {
// methods.add(m);
// continue;
// }
//
// cmethods.add(m); // I guess this method name is overriding a jre interface (init, run, ?).
// }
// }
//
// // cmethods are scrambled randomally, so sort by name
// cmethods = cmethods.stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
//
// methods.addAll(cmethods);
// }
//
// return methods;
// }
private void map(Map<Object, Object> all, List<ParallelExecutorMapping> result, Method m1, Method m2)
{
@@ -454,48 +454,40 @@ public class MapStaticTest
return "total methods/fields: " + total + ", " + methods + " methods, " + fields + " fields";
}
@Test
public void printTotalObjects() throws Exception
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
//print(group1);
}
@Test
public void testCore() throws Exception
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
Rename rename = new Rename(group1, group2);
rename.run();
ParallelExecutorMapping mapping = rename.getMapping();
mapping.merge(this.testPackets(group1, group2));
summary(rename.getMapping(), group1);
String sg1 = print(group1),
sg2 = print(group2);
System.out.println("GROUP 1 " + sg1);
System.out.println("GROUP 2 " + sg2);
List<Field> exported = getExportedFields(group1);
int mapped = 0, not = 0;
for (Field f : exported)
{
Field other = (Field) mapping.get(f);
if (other == null)
System.out.println("missing " + f + " " + other);
if (other != null) ++mapped;
else ++not;
}
System.out.println("Mapped " + mapped + " total " + (mapped+not));
}
// @Test
// public void testCore() throws Exception
// {
// ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
// ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
//
// Mapper rename = new Mapper(group1, group2);
// rename.run();
//
// ParallelExecutorMapping mapping = rename.getMapping();
//
// mapping.merge(this.testPackets(group1, group2));
//
// summary(rename.getMapping(), group1);
//
// String sg1 = print(group1),
// sg2 = print(group2);
//
// System.out.println("GROUP 1 " + sg1);
// System.out.println("GROUP 2 " + sg2);
//
// List<Field> exported = getExportedFields(group1);
// int mapped = 0, not = 0;
// for (Field f : exported)
// {
// Field other = (Field) mapping.get(f);
// if (other == null)
// System.out.println("missing " + f + " " + other);
// if (other != null) ++mapped;
// else ++not;
// }
// System.out.println("Mapped " + mapped + " total " + (mapped+not));
//
// }
private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
@@ -528,81 +520,92 @@ public class MapStaticTest
{
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
testPackets(group1, group2);
Mapper mapper = new Mapper(group1, group2);
mapper.run();
ParallelExecutorMapping mapping = mapper.getMapping();
summary(mapping, group1);
String sg1 = print(group1),
sg2 = print(group2);
System.out.println("GROUP 1 " + sg1);
System.out.println("GROUP 2 " + sg2);
}
//@Test
public ParallelExecutorMapping testPackets(ClassGroup group1, ClassGroup group2) throws IOException
{
//ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
//ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
group1.findClass("client").findField("field446").packetHandler = true;
group2.findClass("client").findField("field324").packetHandler = true;
Method m1 = group1.findClass("client").findMethod("vmethod3096");
Method m2 = group2.findClass("client").findMethod("vmethod2975");
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
System.out.println("BEGIN OF MAPPING");
for (Object o : mappings.getMap().keySet())
{
Object value = mappings.get(o);
System.out.println(o + " <-> " + value);
}
System.out.println("END OF MAPPINGS " + mappings.getMap().size());
System.out.println(mappings.packetHandler1.size() + " vs " + mappings.packetHandler2.size() + " handlers");
assert mappings.packetHandler1.size() == mappings.packetHandler2.size();
ParallellMappingExecutor.enable = true;
ParallelExecutorMapping all = new ParallelExecutorMapping(group1, group2);
for (int i = 0; i < mappings.packetHandler1.size(); ++i)
{
PacketHandler if1 = mappings.packetHandler1.get(i);
PacketHandler highestHandler = null;
ParallelExecutorMapping highest = null;
for (int j = 0; j < mappings.packetHandler2.size(); ++j)
{
PacketHandler if2 = mappings.packetHandler2.get(j);
Instruction i1 = if1.getFirstInsOfHandler(),
i2 = if2.getFirstInsOfHandler();
ParallelExecutorMapping mapping = MappingExecutorUtil.mapFrame(group1, group2, i1, i2);
if (mapping.getMap().isEmpty())
continue;
if (highest == null || mapping.getMap().size() > highest.getMap().size())
{
highest = mapping;
highestHandler = if2;
}
// Execution e1 = new Execution(group1);
// Execution e2 = new Execution(group2);
// public ParallelExecutorMapping testPackets(ClassGroup group1, ClassGroup group2) throws IOException
// {
// //ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
// //ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
//
// Frame f1 = new Frame(e1, i1.getInstructions().getCode().getAttributes().getMethod(), i1);
// Frame f2 = new Frame(e2, i2.getInstructions().getCode().getAttributes().getMethod(), i2);
//e1.frames.add(f1);
//e2.frames.add(f2);
}
System.out.println(if1 + " <-> " + highestHandler + " <-> " + highest.getMap().size() + " " + highest.crashed);
all.merge(highest);
}
ParallellMappingExecutor.enable = false;
return all;
}
// group1.findClass("client").findField("field446").packetHandler = true;
// group2.findClass("client").findField("field324").packetHandler = true;
//
// Method m1 = group1.findClass("client").findMethod("vmethod3096");
// Method m2 = group2.findClass("client").findMethod("vmethod2975");
//
// ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
//
// System.out.println("BEGIN OF MAPPING");
// for (Object o : mappings.getMap().keySet())
// {
// Object value = mappings.get(o);
// System.out.println(o + " <-> " + value);
// }
// System.out.println("END OF MAPPINGS " + mappings.getMap().size());
//
// System.out.println(mappings.packetHandler1.size() + " vs " + mappings.packetHandler2.size() + " handlers");
//
// assert mappings.packetHandler1.size() == mappings.packetHandler2.size();
//
// ParallellMappingExecutor.enable = true;
// ParallelExecutorMapping all = new ParallelExecutorMapping(group1, group2);
//
// for (int i = 0; i < mappings.packetHandler1.size(); ++i)
// {
// PacketHandler if1 = mappings.packetHandler1.get(i);
//
// PacketHandler highestHandler = null;
// ParallelExecutorMapping highest = null;
//
// for (int j = 0; j < mappings.packetHandler2.size(); ++j)
// {
// PacketHandler if2 = mappings.packetHandler2.get(j);
//
// Instruction i1 = if1.getFirstInsOfHandler(),
// i2 = if2.getFirstInsOfHandler();
//
// ParallelExecutorMapping mapping = MappingExecutorUtil.mapFrame(group1, group2, i1, i2);
//
// if (mapping.getMap().isEmpty())
// continue;
//
// if (highest == null || mapping.getMap().size() > highest.getMap().size())
// {
// highest = mapping;
// highestHandler = if2;
// }
//
//
//// Execution e1 = new Execution(group1);
//// Execution e2 = new Execution(group2);
////
//// Frame f1 = new Frame(e1, i1.getInstructions().getCode().getAttributes().getMethod(), i1);
//// Frame f2 = new Frame(e2, i2.getInstructions().getCode().getAttributes().getMethod(), i2);
//
// //e1.frames.add(f1);
// //e2.frames.add(f2);
// }
//
// System.out.println(if1 + " <-> " + highestHandler + " <-> " + highest.getMap().size() + " " + highest.crashed);
// all.merge(highest);
// }
//
// ParallellMappingExecutor.enable = false;
// return all;
// }
private static int handlers[][] = {
{ 74, 187 }

View File

@@ -2,6 +2,7 @@ package net.runelite.deob.runeloader;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Field;
@@ -23,9 +24,9 @@ import org.junit.Test;
public class MappingImporter
{
private static final File IN = new File("/Users/adam/w/rs/07/adamin.jar");
private static final File OUT = new File("/Users/adam/w/rs/07/adamout.jar");
private static final File RL_INJECTION = new File("/Users/adam/w/rs/07/rl/injection.json");
private static final File IN = new File("d:/rs/07/adamin.jar");
private static final File OUT = new File("d:/rs/07/adamout.jar");
private static final File RL_INJECTION = new File("C:\\Users\\Adam\\git\\jbytecode\\src\\test\\resources\\injection_v16.json");
private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");

File diff suppressed because it is too large Load Diff