Allow parallel mapping executor to step through static methods if it encounters an invokestatic that doesn't match the other executor. Maybe works. Hitting an ifnull vs if check fail in my test.

This commit is contained in:
Adam
2016-01-01 19:01:40 -05:00
parent 6bb02614ca
commit d029c128e3
5 changed files with 137 additions and 17 deletions

View File

@@ -92,8 +92,8 @@ public class MappingExecutorUtil
System.out.println(p1.getInstruction() + " <-> " + p2.getInstruction());
assert p1.getInstruction().getInstructions().getCode().getAttributes().getMethod() == m1;
assert p2.getInstruction().getInstructions().getCode().getAttributes().getMethod() == m2;
//assert p1.getInstruction().getInstructions().getCode().getAttributes().getMethod() == m1;
//assert p2.getInstruction().getInstructions().getCode().getAttributes().getMethod() == m2;
assert p1.getInstruction() instanceof MappableInstruction;
assert p2.getInstruction() instanceof MappableInstruction;

View File

@@ -30,6 +30,7 @@ public class Frame
protected Method nonStatic; // next non static method up the stack
private Frame caller;
public Frame other; // in the other execution for mapping
public Frame returnTo; // is this the same as caller?
public Frame(Execution execution, Method method)
{
@@ -219,9 +220,7 @@ public class Frame
if (oldCur == cur)
{
int idx = instructions.indexOf(cur);
assert idx != -1;
cur = instructions.get(idx + 1);
this.nextInstruction();
}
else
{
@@ -236,6 +235,16 @@ public class Frame
}
}
public void nextInstruction()
{
Instructions ins = method.getCode().getInstructions();
List<Instruction> instructions = ins.getInstructions();
int idx = instructions.indexOf(cur);
assert idx != -1;
cur = instructions.get(idx + 1);
}
private void processExceptions(Instruction i)
{
if (this.execution.step)

View File

@@ -1,5 +1,9 @@
package net.runelite.deob.execution;
import net.runelite.deob.Method;
import net.runelite.deob.attributes.code.instruction.types.ReturnInstruction;
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
public class ParallellMappingExecutor
{
private Execution e, e2;
@@ -44,10 +48,24 @@ public class ParallellMappingExecutor
// step frame
f1.execute();
f2.execute();
f1 = popStack(f1);
f2 = popStack(f2);
// get what each frame is paused/exited on
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
if (p1.getInstruction() instanceof InvokeStatic && !(p2.getInstruction() instanceof InvokeStatic))
{
f1 = stepInto(f1);
p1 = f1.getInstructions().get(f1.getInstructions().size() - 1);
}
else if (p2.getInstruction() instanceof InvokeStatic && !(p1.getInstruction() instanceof InvokeStatic))
{
f2 = stepInto(f2);
p2 = f2.getInstructions().get(f2.getInstructions().size() - 1);
}
// frames can stop executing at different times if one sees a jump
// that has been done before, so stop both and remove the pending branch
@@ -89,4 +107,72 @@ public class ParallellMappingExecutor
{
return p2;
}
private Frame stepInto(Frame f)
{
Execution e = f.getExecution();
assert e == this.e || e == e2;
assert e.frames.get(0) == f;
InstructionContext i = f.getInstructions().get(f.getInstructions().size() - 1);
assert i.getInstruction() instanceof InvokeStatic;
InvokeStatic is = (InvokeStatic) i.getInstruction();
Method to = is.getMethods().get(0);
Frame f2 = new Frame(e, to);
f2.initialize(i);
e.frames.remove(0); // old frame goes away
e.frames.add(0, f2);
assert f.other.other == f;
f2.other = f.other; // even though theyre in different methods
f.other.other = f2;
f.other = null;
f2.returnTo = new Frame(f); // where to go when we're done
// step new frame
f2.execute();
return f2;
}
private Frame popStack(Frame f)
{
Execution e = f.getExecution();
if (f.isExecuting() || f.returnTo == null)
return f;
InstructionContext i = f.getInstructions().get(f.getInstructions().size() - 1);
if (!(i.getInstruction() instanceof ReturnInstruction))
return f;
assert e.frames.contains(f);
assert !e.frames.contains(f.returnTo);
// replace frame with returnTo
assert e.frames.get(0) == f;
e.frames.remove(0);
e.frames.add(0, f.returnTo);
assert f.other.other == f;
assert f.returnTo.other == null;
Frame newFrame = f.returnTo;
newFrame.other = f.other;
newFrame.other.other = newFrame;
f.other = null;
// step return frame
f.returnTo.execute();
return f.returnTo;
}
}

View File

@@ -0,0 +1,36 @@
package net.runelite.deob.deobfuscators.rename;
import java.io.File;
import java.io.IOException;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Method;
import net.runelite.deob.util.JarUtil;
import org.junit.Assert;
import org.junit.Test;
public class MapStaticTest
{
//@Test
public void testMappable() throws IOException
{
ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar"));
ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
// Assert.assertTrue(MappingExecutorUtil.isMappable(
// group1.findClass("class99").findMethod("method2220"),
// group2.findClass("class99").findMethod("method2149")
// ));
}
@Test
public void test() throws IOException
{
ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar"));
ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
Method m1 = group1.findClass("client").findMethod("vmethod3050");
Method m2 = group2.findClass("client").findMethod("vmethod3007");
ParallelExecutorMapping mappings = MappingExecutorUtil.map(m1, m2);
}
}

View File

@@ -2,19 +2,8 @@ package net.runelite.deob.deobfuscators.rename;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Method;
import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.attributes.code.instruction.types.MappableInstruction;
import net.runelite.deob.execution.Execution;
import net.runelite.deob.execution.Frame;
import net.runelite.deob.execution.InstructionContext;
import net.runelite.deob.execution.ParallellMappingExecutor;
import net.runelite.deob.util.JarUtil;
import org.junit.Assert;
import org.junit.Test;
@@ -34,7 +23,7 @@ public class MapTest
}
@Test
public void main() throws IOException
public void test() throws IOException
{
ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar"));
ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));