Interesting work using pme to detect method equality
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
package net.runelite.deob.deobfuscators.rename;
|
|
||||||
|
|
||||||
public class MappingException extends Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -66,7 +66,7 @@ public class MappingExecutorUtil
|
|||||||
return map1.equals(map2);
|
return map1.equals(map2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ParallelExecutorMapping map(Method m1, Method m2) throws MappingException
|
public static ParallelExecutorMapping map(Method m1, Method m2)
|
||||||
{
|
{
|
||||||
ClassGroup group1 = m1.getMethods().getClassFile().getGroup();
|
ClassGroup group1 = m1.getMethods().getClassFile().getGroup();
|
||||||
ClassGroup group2 = m2.getMethods().getClassFile().getGroup();
|
ClassGroup group2 = m2.getMethods().getClassFile().getGroup();
|
||||||
@@ -169,16 +169,16 @@ public class MappingExecutorUtil
|
|||||||
// continue;
|
// continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
mi1.map(mappings, p1, p2);
|
mi1.map(mappings, p1, p2);
|
||||||
}
|
// }
|
||||||
catch (Throwable ex)
|
// catch (Throwable ex)
|
||||||
{
|
// {
|
||||||
p1.getFrame().stop();
|
// p1.getFrame().stop();
|
||||||
p2.getFrame().stop();
|
// p2.getFrame().stop();
|
||||||
ex.printStackTrace();
|
// ex.printStackTrace();
|
||||||
}
|
// }
|
||||||
|
|
||||||
e.paused = e2.paused = false;
|
e.paused = e2.paused = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package net.runelite.deob.deobfuscators.rename;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import net.runelite.deob.ClassFile;
|
||||||
|
import net.runelite.deob.Method;
|
||||||
|
import net.runelite.deob.Methods;
|
||||||
|
import net.runelite.deob.signature.Signature;
|
||||||
|
|
||||||
|
public class MethodSignatureMapper
|
||||||
|
{
|
||||||
|
private Map<Method, Method> map = new HashMap<>();
|
||||||
|
|
||||||
|
private long count(Methods methods, Signature sig)
|
||||||
|
{
|
||||||
|
return methods.getMethods().stream().filter(m -> m.getDescriptor().equals(sig)).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Method get(Methods methods, Signature sig)
|
||||||
|
{
|
||||||
|
Optional<Method> o = methods.getMethods().stream().filter(m -> m.getDescriptor().equals(sig)).findFirst();
|
||||||
|
return o.isPresent() ? o.get() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void map(ClassFile c1, ClassFile c2)
|
||||||
|
{
|
||||||
|
for (Method m : c1.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
if (m.isStatic() || m.getName().equals("<init>") || count(c1.getMethods(), m.getDescriptor()) > 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Method other = get(c2.getMethods(), m.getDescriptor());
|
||||||
|
if (other == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
map.put(m, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Method, Method> getMap()
|
||||||
|
{
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -349,15 +349,8 @@ public class Rename2
|
|||||||
if (m1.getName().equals("<clinit>") || m1.getName().equals("<init>"))
|
if (m1.getName().equals("<clinit>") || m1.getName().equals("<init>"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ParallelExecutorMapping mapping = null;
|
ParallelExecutorMapping mapping = MappingExecutorUtil.map(m1, m2);
|
||||||
try
|
|
||||||
{
|
|
||||||
mapping = MappingExecutorUtil.map(m1, m2);
|
|
||||||
}
|
|
||||||
catch (MappingException ex)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
System.out.println("EXEC " + count++ + " " + mname(m1) + " " + mname(m2) + " " + mapping);
|
System.out.println("EXEC " + count++ + " " + mname(m1) + " " + mname(m2) + " " + mapping);
|
||||||
|
|
||||||
for (Entry<Object, Object> e : mapping.getMap().entrySet())
|
for (Entry<Object, Object> e : mapping.getMap().entrySet())
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package net.runelite.deob.deobfuscators.rename;
|
||||||
|
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import net.runelite.deob.ClassFile;
|
||||||
|
import net.runelite.deob.ClassGroup;
|
||||||
|
import net.runelite.deob.Method;
|
||||||
|
import net.runelite.deob.signature.Signature;
|
||||||
|
|
||||||
|
public class StaticMethodSignatureMapper
|
||||||
|
{
|
||||||
|
private Multimap<Method, Method> map = ArrayListMultimap.create();
|
||||||
|
|
||||||
|
private List<Method> getStaticMethods(ClassGroup group)
|
||||||
|
{
|
||||||
|
List<Method> methods = new ArrayList<>();
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
if (m.isStatic() && !m.getName().equals("<clinit>"))
|
||||||
|
methods.add(m);
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Method> getStaticMethodsOfSignature(ClassGroup group, Signature sig)
|
||||||
|
{
|
||||||
|
return getStaticMethods(group).stream().filter(m -> m.getDescriptor().equals(sig)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void map(ClassGroup group1, ClassGroup group2)
|
||||||
|
{
|
||||||
|
for (Method m : getStaticMethods(group1))
|
||||||
|
{
|
||||||
|
map.putAll(m, getStaticMethodsOfSignature(group2, m.getDescriptor()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Multimap<Method, Method> getMap()
|
||||||
|
{
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -180,7 +180,7 @@ public class ParallellMappingExecutor
|
|||||||
if (oldf1.otherStatic == oldf2 && oldf2.otherStatic == oldf1)
|
if (oldf1.otherStatic == oldf2 && oldf2.otherStatic == oldf1)
|
||||||
{
|
{
|
||||||
mappings.map(oldf1.getMethod(), oldf2.getMethod());
|
mappings.map(oldf1.getMethod(), oldf2.getMethod());
|
||||||
System.out.println("STEP OUT " + oldf1.getMethod() + " <-> " + oldf2.getMethod());
|
// System.out.println("STEP OUT " + oldf1.getMethod() + " <-> " + oldf2.getMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (e.frames.size() - s1 != e2.frames.size() - s2)
|
// if (e.frames.size() - s1 != e2.frames.size() - s2)
|
||||||
@@ -279,7 +279,7 @@ public class ParallellMappingExecutor
|
|||||||
stepf2.otherStatic = stepf1;
|
stepf2.otherStatic = stepf1;
|
||||||
|
|
||||||
doubleStep.add(stepf1.getMethod());
|
doubleStep.add(stepf1.getMethod());
|
||||||
System.out.println("STEP " + stepf1.getMethod() + " <-> " + stepf2.getMethod());
|
//System.out.println("STEP " + stepf1.getMethod() + " <-> " + stepf2.getMethod());
|
||||||
|
|
||||||
return step();
|
return step();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.runelite.deob.deobfuscators.rename;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -65,7 +66,7 @@ public class MapStaticTest
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAll() throws IOException, MappingException
|
public void testAll() throws IOException
|
||||||
{
|
{
|
||||||
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
||||||
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
||||||
@@ -82,7 +83,7 @@ public class MapStaticTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws IOException, MappingException
|
public void test() throws IOException
|
||||||
{
|
{
|
||||||
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
ClassGroup group1 = JarUtil.loadJar(new File(JAR1));
|
||||||
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
ClassGroup group2 = JarUtil.loadJar(new File(JAR2));
|
||||||
@@ -196,23 +197,98 @@ public class MapStaticTest
|
|||||||
map(all, pmes, m1, m2);
|
map(all, pmes, m1, m2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 250; ++i)
|
||||||
|
{
|
||||||
|
ClassFile c1 = group1.findClass("class" + i);
|
||||||
|
ClassFile c2 = group2.findClass("class" + i);
|
||||||
|
|
||||||
|
if (c1 == null || c2 == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MethodSignatureMapper msm = new MethodSignatureMapper();
|
||||||
|
msm.map(c1, c2);
|
||||||
|
|
||||||
|
Map<Method, Method> map = msm.getMap();
|
||||||
|
for (Entry<Method, Method> e : map.entrySet())
|
||||||
|
{
|
||||||
|
HashMap<Object, Object> all = new HashMap();
|
||||||
|
map(all, pmes, e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ParallelExecutorMapping finalm = new ParallelExecutorMapping();
|
ParallelExecutorMapping finalm = new ParallelExecutorMapping();
|
||||||
for (ParallelExecutorMapping pme : pmes)
|
for (ParallelExecutorMapping pme : pmes)
|
||||||
finalm.merge(pme);
|
finalm.merge(pme);
|
||||||
|
|
||||||
summary(finalm);
|
summary(finalm);
|
||||||
print(group1);
|
print(group1);
|
||||||
System.out.println("db step " + ParallellMappingExecutor.doubleStep.size());
|
// System.out.println("db step " + ParallellMappingExecutor.doubleStep.size());
|
||||||
|
//
|
||||||
|
// for (Method m : group1.findClass("client").getMethods().getMethods())
|
||||||
|
// {
|
||||||
|
// if (!finalm.getMap().containsKey(m) && !m.isStatic())
|
||||||
|
// System.out.println("missing " + m);
|
||||||
|
// }
|
||||||
|
// for (Field m : group1.findClass("client").getFields().getFields())
|
||||||
|
// {
|
||||||
|
// if (!finalm.getMap().containsKey(m))
|
||||||
|
// System.out.println("missing " + m);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
for (Method m : group1.findClass("client").getMethods().getMethods())
|
//@Test
|
||||||
|
public void testMapperMap() throws IOException
|
||||||
|
{
|
||||||
|
ClassGroup one = JarUtil.loadJar(new File(JAR1));
|
||||||
|
ClassGroup two = JarUtil.loadJar(new File(JAR2));
|
||||||
|
|
||||||
|
List<ParallelExecutorMapping> pmes = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 250; ++i)
|
||||||
{
|
{
|
||||||
if (!finalm.getMap().containsKey(m) && !m.isStatic())
|
ClassFile c1 = one.findClass("class" + i);
|
||||||
System.out.println("missing " + m);
|
ClassFile c2 = two.findClass("class" + i);
|
||||||
|
|
||||||
|
if (c1 == null || c2 == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MethodSignatureMapper msm = new MethodSignatureMapper();
|
||||||
|
msm.map(c1, c2);
|
||||||
|
|
||||||
|
Map<Method, Method> map = msm.getMap();
|
||||||
|
for (Entry<Method, Method> e : map.entrySet())
|
||||||
|
{
|
||||||
|
HashMap<Object, Object> all = new HashMap();
|
||||||
|
map(all, pmes, e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (Field m : group1.findClass("client").getFields().getFields())
|
ParallelExecutorMapping finalm = new ParallelExecutorMapping();
|
||||||
|
for (ParallelExecutorMapping pme : pmes)
|
||||||
|
finalm.merge(pme);
|
||||||
|
|
||||||
|
summary(finalm);
|
||||||
|
print(one);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStaticMapperMap() throws IOException
|
||||||
|
{
|
||||||
|
ClassGroup one = JarUtil.loadJar(new File(JAR1));
|
||||||
|
ClassGroup two = JarUtil.loadJar(new File(JAR2));
|
||||||
|
|
||||||
|
StaticMethodSignatureMapper smsm = new StaticMethodSignatureMapper();
|
||||||
|
smsm.map(one, two);
|
||||||
|
|
||||||
|
for (Method m : smsm.getMap().keySet())
|
||||||
{
|
{
|
||||||
if (!finalm.getMap().containsKey(m))
|
Collection<Method> methods = smsm.getMap().get(m);
|
||||||
System.out.println("missing " + m);
|
|
||||||
|
if (methods.size() == 1)
|
||||||
|
{
|
||||||
|
Method other = methods.stream().findFirst().get();
|
||||||
|
ParallelExecutorMapping pme = MappingExecutorUtil.map(m, other);
|
||||||
|
|
||||||
|
System.out.println(m + " " + other + " " + pme.getMap().size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,19 +346,19 @@ public class MapStaticTest
|
|||||||
int i=5;
|
int i=5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelExecutorMapping mappings;
|
ParallelExecutorMapping
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
mappings = MappingExecutorUtil.map(m1, m2);
|
mappings = MappingExecutorUtil.map(m1, m2);
|
||||||
}
|
// }
|
||||||
catch (Throwable ex)
|
// catch (Throwable ex)
|
||||||
{
|
// {
|
||||||
ex.printStackTrace();
|
// ex.printStackTrace();
|
||||||
System.err.println("Error mapping " + m1 + " to " + m2);
|
// System.err.println("Error mapping " + m1 + " to " + m2);
|
||||||
//if (test)
|
// //if (test)
|
||||||
// throw ex;
|
// // throw ex;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
result.add(mappings);
|
result.add(mappings);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class MapTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws IOException, MappingException
|
public void test() throws IOException
|
||||||
{
|
{
|
||||||
ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar"));
|
ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar"));
|
||||||
ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
|
ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
|
||||||
|
|||||||
Reference in New Issue
Block a user