mctx stuff made this easier.

This commit is contained in:
Adam
2016-04-04 18:35:52 -04:00
parent 0b8e56d385
commit 3ea32bd123
7 changed files with 369 additions and 441 deletions

View File

@@ -22,7 +22,6 @@ public class Execution
private MultiValueMap<WeakInstructionContext, Method> invokes = new MultiValueMap<>(); private MultiValueMap<WeakInstructionContext, Method> invokes = new MultiValueMap<>();
public boolean paused; public boolean paused;
public boolean step = false; public boolean step = false;
public boolean processInvokes = true;
private List<ExecutionVisitor> visitors = new ArrayList<>(); private List<ExecutionVisitor> visitors = new ArrayList<>();
private List<FrameVisitor> frameVisitors = new ArrayList<>(); private List<FrameVisitor> frameVisitors = new ArrayList<>();
private List<MethodContextVisitor> methodContextVisitors = new ArrayList<>(); private List<MethodContextVisitor> methodContextVisitors = new ArrayList<>();
@@ -98,9 +97,6 @@ public class Execution
if (step) // step executor if (step) // step executor
return null; return null;
if (!processInvokes)
return null;
if (hasInvoked(from, to)) if (hasInvoked(from, to))
return null; return null;

View File

@@ -29,7 +29,6 @@ import net.runelite.asm.attributes.code.instructions.LDC2_W;
import net.runelite.asm.attributes.code.instructions.LDC_W; import net.runelite.asm.attributes.code.instructions.LDC_W;
import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.attributes.code.instructions.LMul;
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;
import net.runelite.asm.execution.StackContext; import net.runelite.asm.execution.StackContext;
import net.runelite.asm.pool.PoolEntry; import net.runelite.asm.pool.PoolEntry;
@@ -41,6 +40,7 @@ import net.runelite.asm.attributes.code.instructions.If;
import net.runelite.asm.attributes.code.instructions.If0; import net.runelite.asm.attributes.code.instructions.If0;
import net.runelite.asm.attributes.code.instructions.LAdd; import net.runelite.asm.attributes.code.instructions.LAdd;
import net.runelite.asm.attributes.code.instructions.LCmp; import net.runelite.asm.attributes.code.instructions.LCmp;
import net.runelite.asm.execution.MethodContext;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
public class ModArith implements Deobfuscator public class ModArith implements Deobfuscator
@@ -82,14 +82,9 @@ public class ModArith implements Deobfuscator
return l; return l;
} }
private void findObfuscatedFields() private void findObfuscatedFields(MethodContext mctx)
{ {
// find a direct big*field with no other fields involved for (InstructionContext ctx : mctx.getInstructionContexts())
obfuscatedFields.clear();
for (Frame f : execution.processedFrames)
{
for (InstructionContext ctx : f.getInstructions())
{ {
if (ctx.getInstruction() instanceof SetFieldInstruction) if (ctx.getInstruction() instanceof SetFieldInstruction)
{ {
@@ -182,7 +177,7 @@ public class ModArith implements Deobfuscator
try try
{ {
MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(execution, ctx, ctx.getInstruction().getClass()); MultiplicationExpression expr = MultiplicationDeobfuscator.parseExpression(ctx, ctx.getInstruction().getClass());
if (expr.hasFieldOtherThan(other.getMyField())) if (expr.hasFieldOtherThan(other.getMyField()))
continue; continue;
} }
@@ -205,7 +200,6 @@ public class ModArith implements Deobfuscator
this.obfuscatedFields.add(other.getMyField()); this.obfuscatedFields.add(other.getMyField());
} }
} }
}
static class AssociatedConstant static class AssociatedConstant
{ {
@@ -215,10 +209,9 @@ public class ModArith implements Deobfuscator
} }
private MultiValueMap<Field, AssociatedConstant> constants = new MultiValueMap(); private MultiValueMap<Field, AssociatedConstant> constants = new MultiValueMap();
private void findUses2() private void findUses2(MethodContext mctx)
{ {
for (Frame f : execution.processedFrames) for (InstructionContext ctx : mctx.getInstructionContexts())
for (InstructionContext ctx : f.getInstructions())
{ {
if (ctx.getInstruction() instanceof FieldInstruction) if (ctx.getInstruction() instanceof FieldInstruction)
{ {
@@ -283,10 +276,9 @@ public class ModArith implements Deobfuscator
} }
} }
private void findUses() private void findUses(MethodContext mctx)
{ {
for (Frame f : execution.processedFrames) for (InstructionContext ctx : mctx.getInstructionContexts())
for (InstructionContext ctx : f.getInstructions())
{ {
if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul) if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul)
{ {
@@ -709,13 +701,19 @@ public class ModArith implements Deobfuscator
constantSetters.clear(); constantSetters.clear();
constants.clear(); constants.clear();
// find a direct big*field with no other fields involved
obfuscatedFields.clear();
execution = new Execution(group); execution = new Execution(group);
execution.addMethodContextVisitor(i -> findObfuscatedFields(i));
execution.addMethodContextVisitor(i -> findUses(i));
execution.addMethodContextVisitor(i -> findUses2(i));
execution.populateInitialMethods(); execution.populateInitialMethods();
execution.run(); execution.run();
findObfuscatedFields(); // findObfuscatedFields();
findUses(); // findUses();
findUses2(); // findUses2();
reduce2(); reduce2();
int i = 0; int i = 0;

View File

@@ -4,10 +4,8 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.asm.Method;
import net.runelite.deob.Deobfuscator; import net.runelite.deob.Deobfuscator;
import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.Instructions;
import net.runelite.asm.attributes.code.instruction.types.DupInstruction; import net.runelite.asm.attributes.code.instruction.types.DupInstruction;
import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction;
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction; import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
@@ -25,7 +23,6 @@ import net.runelite.asm.attributes.code.instructions.LMul;
import net.runelite.asm.attributes.code.instructions.LSub; import net.runelite.asm.attributes.code.instructions.LSub;
import net.runelite.asm.attributes.code.instructions.SiPush; import net.runelite.asm.attributes.code.instructions.SiPush;
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;
import net.runelite.asm.execution.MethodContext; import net.runelite.asm.execution.MethodContext;
import net.runelite.asm.execution.StackContext; import net.runelite.asm.execution.StackContext;
@@ -245,7 +242,6 @@ public class MultiplicationDeobfuscator implements Deobfuscator
{ {
assert ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul; assert ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul;
// XXX this needs to be all in all frames
Collection<InstructionContext> ins = ctx.getFrame().getMethodCtx().getInstructonContexts(ctx.getInstruction()); Collection<InstructionContext> ins = ctx.getFrame().getMethodCtx().getInstructonContexts(ctx.getInstruction());
for (InstructionContext i : ins) for (InstructionContext i : ins)
{ {
@@ -346,7 +342,6 @@ public class MultiplicationDeobfuscator implements Deobfuscator
count = 0; count = 0;
Execution e = new Execution(group); Execution e = new Execution(group);
//e.addFrameVisitor(f -> visit(f));
e.addMethodContextVisitor(m -> visit(m)); e.addMethodContextVisitor(m -> visit(m));
e.populateInitialMethods(); e.populateInitialMethods();
e.run(); e.run();

View File

@@ -1,6 +1,5 @@
package net.runelite.deob.deobfuscators.arithmetic; package net.runelite.deob.deobfuscators.arithmetic;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.deob.Deobfuscator; import net.runelite.deob.Deobfuscator;
@@ -11,47 +10,36 @@ import net.runelite.asm.attributes.code.instructions.IMul;
import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.attributes.code.instructions.LMul;
import net.runelite.asm.attributes.code.instructions.NOP; import net.runelite.asm.attributes.code.instructions.NOP;
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;
import net.runelite.asm.execution.MethodContext;
import net.runelite.asm.execution.StackContext; import net.runelite.asm.execution.StackContext;
class MPair
{
int removeIdx;
InstructionContext ctx;
public MPair(int removeIdx, InstructionContext ctx)
{
this.removeIdx = removeIdx;
this.ctx = ctx;
}
}
public class MultiplyOneDeobfuscator implements Deobfuscator public class MultiplyOneDeobfuscator implements Deobfuscator
{ {
private int count; private int count;
private List<MPair> pairs = new ArrayList<>();
private void visit(InstructionContext ictx) private void visit(MethodContext mctx)
{
for (InstructionContext ictx : mctx.getInstructionContexts())
{ {
Instruction instruction = ictx.getInstruction(); Instruction instruction = ictx.getInstruction();
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
{ {
return; continue;
} }
Instructions ins = ictx.getInstruction().getInstructions(); Instructions ins = ictx.getInstruction().getInstructions();
if (ins == null) if (ins == null)
{ {
return; continue;
} }
List<Instruction> ilist = ins.getInstructions(); List<Instruction> ilist = ins.getInstructions();
if (!ilist.contains(ictx.getInstruction())) if (!ilist.contains(ictx.getInstruction()))
{ {
return; // already done continue; // already done
} }
StackContext one = ictx.getPops().get(0); StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1); StackContext two = ictx.getPops().get(1);
@@ -70,38 +58,26 @@ public class MultiplyOneDeobfuscator implements Deobfuscator
if (removeIdx == -1) if (removeIdx == -1)
{ {
return; continue;
} }
pairs.add(new MPair(removeIdx, ictx)); if (!MultiplicationDeobfuscator.isOnlyPath(ictx, removeIdx == 0 ? one : two))
++count;
}
private void visit(Frame f)
{
for (MPair p : pairs)
{
StackContext one = p.ctx.getPops().get(0);
StackContext two = p.ctx.getPops().get(1);
if (!MultiplicationDeobfuscator.isOnlyPath(p.ctx, p.removeIdx == 0 ? one : two))
{ {
continue; continue;
} }
p.ctx.removeStack(p.removeIdx); ictx.removeStack(removeIdx);
p.ctx.getInstruction().getInstructions().replace(p.ctx.getInstruction(), new NOP(p.ctx.getInstruction().getInstructions())); ins.replace(ictx.getInstruction(), new NOP(ins));
++count;
} }
pairs.clear();
} }
@Override @Override
public void run(ClassGroup group) public void run(ClassGroup group)
{ {
Execution e = new Execution(group); Execution e = new Execution(group);
e.addExecutionVisitor(i -> visit(i)); e.addMethodContextVisitor(i -> visit(i));
e.addFrameVisitor(v -> visit(v));
e.populateInitialMethods(); e.populateInitialMethods();
e.run(); e.run();

View File

@@ -1,6 +1,5 @@
package net.runelite.deob.deobfuscators.arithmetic; package net.runelite.deob.deobfuscators.arithmetic;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.deob.Deobfuscator; import net.runelite.deob.Deobfuscator;
@@ -12,27 +11,28 @@ import net.runelite.asm.attributes.code.instructions.LDC2_W;
import net.runelite.asm.attributes.code.instructions.LDC_W; import net.runelite.asm.attributes.code.instructions.LDC_W;
import net.runelite.asm.attributes.code.instructions.LMul; import net.runelite.asm.attributes.code.instructions.LMul;
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;
import net.runelite.asm.execution.MethodContext;
import net.runelite.asm.execution.StackContext; import net.runelite.asm.execution.StackContext;
public class MultiplyZeroDeobfuscator implements Deobfuscator public class MultiplyZeroDeobfuscator implements Deobfuscator
{ {
private int count; private int count;
private List<InstructionContext> pending = new ArrayList<>();
private void visit(InstructionContext ictx) private void visit(MethodContext mctx)
{
for (InstructionContext ictx : mctx.getInstructionContexts())
{ {
Instruction instruction = ictx.getInstruction(); Instruction instruction = ictx.getInstruction();
Instructions ins = instruction.getInstructions(); Instructions ins = instruction.getInstructions();
if (ins == null) if (ins == null)
{ {
return; continue;
} }
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
{ {
return; continue;
} }
List<Instruction> ilist = ins.getInstructions(); List<Instruction> ilist = ins.getInstructions();
@@ -67,26 +67,13 @@ public class MultiplyZeroDeobfuscator implements Deobfuscator
if (remove == false) if (remove == false)
{ {
return; continue;
} }
if (!ilist.contains(instruction)) if (!ilist.contains(instruction))
{ {
return; // already done continue; // already done
} }
pending.add(ictx);
++count;
}
private void visit(Frame frame)
{
for (InstructionContext ictx : pending)
{
Instruction instruction = ictx.getInstruction();
Instructions ins = instruction.getInstructions();
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null))
{ {
continue; continue;
@@ -108,16 +95,17 @@ public class MultiplyZeroDeobfuscator implements Deobfuscator
{ {
throw new IllegalStateException(); throw new IllegalStateException();
} }
++count;
} }
pending.clear();
} }
@Override @Override
public void run(ClassGroup group) public void run(ClassGroup group)
{ {
Execution e = new Execution(group); Execution e = new Execution(group);
e.addExecutionVisitor(i -> visit(i)); e.addMethodContextVisitor(i -> visit(i));
e.addFrameVisitor(v -> visit(v));
e.populateInitialMethods(); e.populateInitialMethods();
e.run(); e.run();

View File

@@ -1,6 +1,5 @@
package net.runelite.deob.deobfuscators.arithmetic; package net.runelite.deob.deobfuscators.arithmetic;
import java.util.Collection;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.deob.ClassGroupFactory; import net.runelite.deob.ClassGroupFactory;
import net.runelite.deob.Deobfuscator; import net.runelite.deob.Deobfuscator;
@@ -32,7 +31,6 @@ import net.runelite.asm.attributes.code.instructions.NOP;
import net.runelite.asm.attributes.code.instructions.Pop; import net.runelite.asm.attributes.code.instructions.Pop;
import net.runelite.asm.attributes.code.instructions.VReturn; import net.runelite.asm.attributes.code.instructions.VReturn;
import net.runelite.asm.execution.Execution; import net.runelite.asm.execution.Execution;
import net.runelite.asm.execution.InstructionContext;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;

View File

@@ -3,31 +3,8 @@ package net.runelite.deob.deobfuscators.arithmetic;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
import net.runelite.deob.ClassGroupFactory;
import net.runelite.deob.Deobfuscator;
import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.Instructions;
import net.runelite.asm.attributes.code.instructions.Goto;
import net.runelite.asm.attributes.code.instructions.IConst_1;
import net.runelite.asm.attributes.code.instructions.IConst_2;
import net.runelite.asm.attributes.code.instructions.IConst_3;
import net.runelite.asm.attributes.code.instructions.IConst_M1;
import net.runelite.asm.attributes.code.instructions.IDiv;
import net.runelite.asm.attributes.code.instructions.ILoad;
import net.runelite.asm.attributes.code.instructions.IMul;
import net.runelite.asm.attributes.code.instructions.IStore_0;
import net.runelite.asm.attributes.code.instructions.IStore_1;
import net.runelite.asm.attributes.code.instructions.IfEq;
import net.runelite.asm.attributes.code.instructions.IfICmpEq;
import net.runelite.asm.attributes.code.instructions.LDC_W;
import net.runelite.asm.attributes.code.instructions.NOP;
import net.runelite.asm.attributes.code.instructions.SiPush;
import net.runelite.asm.attributes.code.instructions.VReturn;
import net.runelite.asm.execution.Execution;
import net.runelite.deob.util.JarUtil; import net.runelite.deob.util.JarUtil;
import org.junit.After; import org.junit.After;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@@ -35,7 +12,7 @@ import org.junit.rules.TemporaryFolder;
public class MultiplyZeroDeobfuscatorTest public class MultiplyZeroDeobfuscatorTest
{ {
private static final File GAMEPACK = new File("c:/rs/gamepack_v19.jar"); private static final File GAMEPACK = new File("d:/rs/07/gamepack_v19.jar");
@Rule @Rule
public TemporaryFolder folder = new TemporaryFolder(); public TemporaryFolder folder = new TemporaryFolder();