This commit is contained in:
Adam
2016-04-03 20:06:27 -04:00
parent eaf870be77
commit d1433c6e84
3 changed files with 97 additions and 48 deletions

View File

@@ -25,6 +25,7 @@ public class Execution
public boolean paused; public boolean paused;
public boolean step = false; public boolean step = false;
private List<ExecutionVisitor> visitors = new ArrayList<>(); private List<ExecutionVisitor> visitors = new ArrayList<>();
private List<FrameVisitor> frameVisitors = new ArrayList<>();
public Execution(ClassGroup group) public Execution(ClassGroup group)
{ {
@@ -127,6 +128,8 @@ public class Execution
assert frames.get(0) == frame; assert frames.get(0) == frame;
assert !frame.isExecuting(); assert !frame.isExecuting();
accept(frame);
frames.remove(frame); frames.remove(frame);
} }
@@ -147,4 +150,14 @@ public class Execution
{ {
visitors.forEach(v -> v.visit(ic)); visitors.forEach(v -> v.visit(ic));
} }
public void addFrameVisitor(FrameVisitor pv)
{
this.frameVisitors.add(pv);
}
public void accept(Frame f)
{
frameVisitors.forEach(v -> v.visit(f));
}
} }

View File

@@ -0,0 +1,6 @@
package net.runelite.asm.execution;
public interface FrameVisitor
{
void visit(Frame f);
}

View File

@@ -1,7 +1,10 @@
package net.runelite.deob.deobfuscators; package net.runelite.deob.deobfuscators;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import net.runelite.asm.ClassFile; import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
@@ -17,15 +20,18 @@ import net.runelite.asm.attributes.code.instructions.Goto;
import net.runelite.asm.attributes.code.instructions.If; import net.runelite.asm.attributes.code.instructions.If;
import net.runelite.asm.attributes.code.instructions.New; import net.runelite.asm.attributes.code.instructions.New;
import net.runelite.asm.execution.Execution; import net.runelite.asm.execution.Execution;
import net.runelite.asm.execution.Frame;
import net.runelite.asm.execution.InstructionContext; import net.runelite.asm.execution.InstructionContext;
public class IllegalStateExceptions implements Deobfuscator public class IllegalStateExceptions implements Deobfuscator
{ {
/* find if, new, ..., athrow, replace with goto */ private int count;
private int checkOnce(Execution execution, ClassGroup group) private Set<Instruction> interesting = new HashSet<>();
{ private InstructionContext currentInstruction;
int count = 0;
/* find if, new, ..., athrow, replace with goto */
private void findInteresting(ClassGroup group)
{
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
{ {
for (Method m : cf.getMethods().getMethods()) for (Method m : cf.getMethods().getMethods())
@@ -53,25 +59,49 @@ public class IllegalStateExceptions implements Deobfuscator
if (!clazz.getName().equals("java/lang/IllegalStateException")) if (!clazz.getName().equals("java/lang/IllegalStateException"))
continue; continue;
interesting.add(ins);
}
}
}
}
private void visit(InstructionContext ic)
{
if (interesting.contains(ic.getInstruction()))
{
assert currentInstruction == null;
currentInstruction = ic;
}
}
private void visit(Frame f)
{
if (currentInstruction == null)
return;
processOne(currentInstruction);
currentInstruction = null;
}
private void processOne(InstructionContext ic)
{
Instruction ins = ic.getInstruction();
Instructions instructions = ins.getInstructions();
List<Instruction> ilist = instructions.getInstructions();
JumpingInstruction jumpIns = (JumpingInstruction) ins; JumpingInstruction jumpIns = (JumpingInstruction) ins;
assert jumpIns.getJumps().size() == 1; assert jumpIns.getJumps().size() == 1;
Instruction to = jumpIns.getJumps().get(0); Instruction to = jumpIns.getJumps().get(0);
// remove stack of if. // remove stack of if.
Collection<InstructionContext> ics = execution.getInstructonContexts(ins);
if (ics == null)
continue; // never executed
for (InstructionContext ic : ics)
{
if (ins instanceof If) if (ins instanceof If)
{
ic.removeStack(1); ic.removeStack(1);
ic.removeStack(0);
break; // XXX I guess this doesnt matter we're only removing one path
} }
ic.removeStack(0);
// instruction is no longer at 'i' because we've just removed stuff... int i = ilist.indexOf(ins);
i = ilist.indexOf(ins); assert i != -1;
// remove up to athrow // remove up to athrow
while (!(ins instanceof AThrow)) while (!(ins instanceof AThrow))
@@ -79,7 +109,9 @@ public class IllegalStateExceptions implements Deobfuscator
// modify instructions which jump to here to instead jump to 'to' // modify instructions which jump to here to instead jump to 'to'
for (Instruction from : ilist) for (Instruction from : ilist)
{
from.replace(ins, to); from.replace(ins, to);
}
instructions.remove(ins); instructions.remove(ins);
ins = ilist.get(i); // don't need to ++i because ins = ilist.get(i); // don't need to ++i because
@@ -95,21 +127,19 @@ public class IllegalStateExceptions implements Deobfuscator
++count; ++count;
} }
}
}
return count;
}
@Override @Override
public void run(ClassGroup group) public void run(ClassGroup group)
{ {
group.buildClassGraph(); findInteresting(group);
Execution execution = new Execution(group); Execution execution = new Execution(group);
execution.addExecutionVisitor(i -> visit(i));
execution.addFrameVisitor(i -> visit(i));
execution.populateInitialMethods(); execution.populateInitialMethods();
execution.run(); execution.run();
int count = checkOnce(execution, group); assert currentInstruction == null;
System.out.println("Removed " + count + " illegal state exceptions"); System.out.println("Removed " + count + " illegal state exceptions");
} }