Is this right? math tests pass
This commit is contained in:
@@ -1,31 +1,31 @@
|
||||
package net.runelite.asm.execution;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.Deob;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.Deob;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
|
||||
public class Execution
|
||||
{
|
||||
private ClassGroup group;
|
||||
public List<Frame> frames = new LinkedList<>();
|
||||
public List<Frame> frames = new ArrayList<>(), framesOther = new ArrayList<>();
|
||||
public Set<Method> methods = new HashSet<>(); // all methods
|
||||
public Set<Instruction> executed = new HashSet<>(); // executed instructions
|
||||
private MultiValueMap<WeakInstructionContext, Method> invokes = new MultiValueMap<>();
|
||||
public MultiValueMap<Instruction, InstructionContext> contexts = new MultiValueMap<>(); // XXX this should move to method ctx probably
|
||||
public boolean paused;
|
||||
public boolean step = false;
|
||||
public boolean processInvokes = true;
|
||||
private List<ExecutionVisitor> visitors = new ArrayList<>();
|
||||
private List<FrameVisitor> frameVisitors = new ArrayList<>();
|
||||
private List<MethodContextVisitor> methodContextVisitors = new ArrayList<>();
|
||||
|
||||
public Execution(ClassGroup group)
|
||||
{
|
||||
@@ -85,9 +85,12 @@ public class Execution
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addFrame(Frame frame)
|
||||
public void addFrame(Frame frame)
|
||||
{
|
||||
frames.add(frame);
|
||||
if (frames.isEmpty() || frames.get(0).getMethod() == frame.getMethod())
|
||||
frames.add(frame);
|
||||
else
|
||||
framesOther.add(frame);
|
||||
}
|
||||
|
||||
public Frame invoke(InstructionContext from, Method to)
|
||||
@@ -95,6 +98,9 @@ public class Execution
|
||||
if (step) // step executor
|
||||
return null;
|
||||
|
||||
if (!processInvokes)
|
||||
return null;
|
||||
|
||||
if (hasInvoked(from, to))
|
||||
return null;
|
||||
|
||||
@@ -131,15 +137,17 @@ public class Execution
|
||||
accept(frame);
|
||||
|
||||
frames.remove(frame);
|
||||
|
||||
if (frames.isEmpty())
|
||||
{
|
||||
accept(frame.getMethodCtx());
|
||||
frames.addAll(framesOther);
|
||||
framesOther.clear();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Processed " + fcount + " frames");
|
||||
}
|
||||
|
||||
// public Collection<InstructionContext> getInstructonContexts(Instruction i)
|
||||
// {
|
||||
// return contexts.getCollection(i);
|
||||
// }
|
||||
|
||||
public void addExecutionVisitor(ExecutionVisitor ev)
|
||||
{
|
||||
@@ -160,4 +168,14 @@ public class Execution
|
||||
{
|
||||
frameVisitors.forEach(v -> v.visit(f));
|
||||
}
|
||||
|
||||
public void addMethodContextVisitor(MethodContextVisitor mcv)
|
||||
{
|
||||
methodContextVisitors.add(mcv);
|
||||
}
|
||||
|
||||
public void accept(MethodContext m)
|
||||
{
|
||||
methodContextVisitors.forEach(mc -> mc.visit(m));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class Frame
|
||||
public Frame dup()
|
||||
{
|
||||
Frame other = new Frame(this);
|
||||
execution.frames.add(other);
|
||||
execution.addFrame(other);
|
||||
return other;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ public class Frame
|
||||
}
|
||||
|
||||
assert ictx.getInstruction() == oldCur || oldCur instanceof Wide;
|
||||
execution.contexts.put(oldCur, ictx);
|
||||
ctx.contexts.put(oldCur, ictx);
|
||||
|
||||
execution.executed.add(oldCur);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ public class MethodContext
|
||||
{
|
||||
private Execution execution;
|
||||
private MultiValueMap<InstructionContext, Instruction> visited = new MultiValueMap<>();
|
||||
public MultiValueMap<Instruction, InstructionContext> contexts = new MultiValueMap<>(); // XXX this should move to method ctx probably
|
||||
|
||||
public MethodContext(Execution execution)
|
||||
{
|
||||
@@ -23,4 +24,14 @@ public class MethodContext
|
||||
visited.put(from, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
public Collection<InstructionContext> getInstructonContexts(Instruction i)
|
||||
{
|
||||
return contexts.getCollection(i);
|
||||
}
|
||||
|
||||
public Collection<InstructionContext> getInstructionContexts()
|
||||
{
|
||||
return (Collection) contexts.values();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.runelite.asm.execution;
|
||||
|
||||
public interface MethodContextVisitor
|
||||
{
|
||||
void visit(MethodContext context);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
@@ -26,6 +27,7 @@ import net.runelite.asm.attributes.code.instructions.SiPush;
|
||||
import net.runelite.asm.execution.Execution;
|
||||
import net.runelite.asm.execution.Frame;
|
||||
import net.runelite.asm.execution.InstructionContext;
|
||||
import net.runelite.asm.execution.MethodContext;
|
||||
import net.runelite.asm.execution.StackContext;
|
||||
import net.runelite.asm.execution.VariableContext;
|
||||
import net.runelite.asm.execution.Variables;
|
||||
@@ -49,12 +51,10 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
System.out.println("Total changed " + count);
|
||||
}
|
||||
|
||||
public static MultiplicationExpression parseExpression(Execution e, InstructionContext ctx, Class want)
|
||||
public static MultiplicationExpression parseExpression(InstructionContext ctx, Class want)
|
||||
{
|
||||
MultiplicationExpression me = new MultiplicationExpression();
|
||||
|
||||
// assert !(ctx.getInstruction() instanceof DupInstruction);
|
||||
|
||||
if (ctx.getInstruction() instanceof LVTInstruction)
|
||||
{
|
||||
LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
|
||||
@@ -82,7 +82,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
assert storelvt.store();
|
||||
|
||||
InstructionContext pushed = storeCtx.getPops().get(0).getPushed();
|
||||
return parseExpression(e, pushed, want);
|
||||
return parseExpression(pushed, want);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
{
|
||||
if (ctx.getInstruction().getClass() == want)
|
||||
{
|
||||
if (!isOnlyPath(e, ctx, sctx))
|
||||
if (!isOnlyPath(ctx, sctx))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
// chained imul, append to me
|
||||
try
|
||||
{
|
||||
MultiplicationExpression other = parseExpression(e, i, want);
|
||||
MultiplicationExpression other = parseExpression(i, want);
|
||||
|
||||
me.instructions.addAll(other.instructions);
|
||||
me.subexpressions.addAll(other.subexpressions);
|
||||
@@ -142,7 +142,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
// imul using result of iadd or isub. evaluate expression
|
||||
try
|
||||
{
|
||||
MultiplicationExpression other = parseExpression(e, i, want);
|
||||
MultiplicationExpression other = parseExpression(i, want);
|
||||
|
||||
// subexpr
|
||||
me.subexpressions.add(other);
|
||||
@@ -174,7 +174,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
StackContext orig = dup.getOriginal(sctx); // original
|
||||
try
|
||||
{
|
||||
MultiplicationExpression other = parseExpression(e, orig.getPushed(), want);
|
||||
MultiplicationExpression other = parseExpression(orig.getPushed(), want);
|
||||
// this expression is used elsewhere like 'pushConstant' so any changes
|
||||
// done to it affect that, too. so multiply it by existing values?
|
||||
if (orig.getPushed().getInstruction() instanceof IAdd || orig.getPushed().getInstruction() instanceof ISub
|
||||
@@ -209,7 +209,7 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
else if (ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub
|
||||
|| ctx.getInstruction() instanceof LAdd || ctx.getInstruction() instanceof LSub)
|
||||
{
|
||||
MultiplicationExpression other = parseExpression(e, i, want); // parse this side of the add/sub
|
||||
MultiplicationExpression other = parseExpression(i, want); // parse this side of the add/sub
|
||||
|
||||
me.subexpressions.add(other);
|
||||
}
|
||||
@@ -225,25 +225,6 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
return me;
|
||||
}
|
||||
|
||||
public static boolean isOnlyPath(Execution execution, InstructionContext ctx)
|
||||
{
|
||||
assert ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul;
|
||||
|
||||
Collection<InstructionContext> ins = execution.getInstructonContexts(ctx.getInstruction());
|
||||
for (InstructionContext i : ins)
|
||||
{
|
||||
if (!i.equals(ctx))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (StackContext sctx : i.getPushes())
|
||||
if (sctx.getPopped().size() > 1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean ictxEqualsDir(InstructionContext one, InstructionContext two, StackContext sctx)
|
||||
{
|
||||
if (one.getInstruction() != two.getInstruction())
|
||||
@@ -260,77 +241,116 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isOnlyPath(Execution execution, InstructionContext ctx, StackContext sctx)
|
||||
public static boolean isOnlyPath(InstructionContext ctx, StackContext sctx)
|
||||
{
|
||||
assert ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul;
|
||||
|
||||
Collection<InstructionContext> ins = execution.getInstructonContexts(ctx.getInstruction());
|
||||
// XXX this needs to be all in all frames
|
||||
Collection<InstructionContext> ins = ctx.getFrame().getMethodCtx().getInstructonContexts(ctx.getInstruction());
|
||||
for (InstructionContext i : ins)
|
||||
{
|
||||
if (!ictxEqualsDir(ctx, i, sctx))
|
||||
{
|
||||
if (sctx == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Instruction poppedIns = null;
|
||||
for (StackContext s : i.getPushes())
|
||||
for (InstructionContext i2 : s.getPopped())
|
||||
if (!i.equals(ctx))
|
||||
{
|
||||
if (poppedIns == null)
|
||||
poppedIns = i2.getInstruction();
|
||||
else if (poppedIns != i2.getInstruction())
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (StackContext sctx2 : i.getPushes())
|
||||
{
|
||||
if (sctx2.getPopped().size() > 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything which pushed the parameters must be the same
|
||||
if (!ictxEqualsDir(ctx, i, sctx))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// everything which pops the result must be the same
|
||||
Instruction poppedIns = null;
|
||||
for (StackContext s : i.getPushes())
|
||||
for (InstructionContext i2 : s.getPopped())
|
||||
{
|
||||
if (poppedIns == null)
|
||||
poppedIns = i2.getInstruction();
|
||||
else if (poppedIns != i2.getInstruction())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<Instruction> done = new HashSet<>();
|
||||
|
||||
private void visit(MethodContext ctx)
|
||||
{
|
||||
for (InstructionContext ictx : ctx.getInstructionContexts())
|
||||
{
|
||||
Instruction instruction = ictx.getInstruction();
|
||||
|
||||
if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiplicationExpression expression;
|
||||
try
|
||||
{
|
||||
expression = parseExpression(ictx, instruction.getClass());
|
||||
}
|
||||
catch (IllegalStateException ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (done.contains(instruction))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
done.add(instruction);
|
||||
|
||||
assert instruction instanceof IMul || instruction instanceof LMul;
|
||||
if (instruction instanceof IMul)
|
||||
{
|
||||
count += expression.simplify(1);
|
||||
}
|
||||
else if (instruction instanceof LMul)
|
||||
{
|
||||
count += expression.simplify(1L);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count;
|
||||
|
||||
private int runOnce()
|
||||
{
|
||||
group.buildClassGraph();
|
||||
|
||||
count = 0;
|
||||
|
||||
Execution e = new Execution(group);
|
||||
//e.addFrameVisitor(f -> visit(f));
|
||||
e.addMethodContextVisitor(m -> visit(m));
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (Frame frame : e.processedFrames)
|
||||
for (InstructionContext ictx : frame.getInstructions())
|
||||
{
|
||||
Instruction instruction = ictx.getInstruction();
|
||||
|
||||
if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
|
||||
continue;
|
||||
|
||||
MultiplicationExpression expression;
|
||||
try
|
||||
{
|
||||
expression = parseExpression(e, ictx, instruction.getClass());
|
||||
}
|
||||
catch (IllegalStateException ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
continue;
|
||||
|
||||
if (done.contains(instruction))
|
||||
continue;
|
||||
done.add(instruction);
|
||||
|
||||
assert instruction instanceof IMul || instruction instanceof LMul;
|
||||
if (instruction instanceof IMul)
|
||||
count += expression.simplify(1);
|
||||
else if (instruction instanceof LMul)
|
||||
count += expression.simplify(1L);
|
||||
else
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
@@ -10,12 +11,26 @@ import net.runelite.asm.attributes.code.instructions.IMul;
|
||||
import net.runelite.asm.attributes.code.instructions.LMul;
|
||||
import net.runelite.asm.attributes.code.instructions.NOP;
|
||||
import net.runelite.asm.execution.Execution;
|
||||
import net.runelite.asm.execution.Frame;
|
||||
import net.runelite.asm.execution.InstructionContext;
|
||||
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
|
||||
{
|
||||
private int count;
|
||||
private List<MPair> pairs = new ArrayList<>();
|
||||
|
||||
private void visit(InstructionContext ictx)
|
||||
{
|
||||
@@ -58,22 +73,35 @@ public class MultiplyOneDeobfuscator implements Deobfuscator
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MultiplicationDeobfuscator.isOnlyPath(e, ictx, removeIdx == 0 ? one : two))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ictx.removeStack(removeIdx);
|
||||
ins.replace(ictx.getInstruction(), new NOP(ins));
|
||||
pairs.add(new MPair(removeIdx, ictx));
|
||||
|
||||
++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;
|
||||
}
|
||||
|
||||
p.ctx.removeStack(p.removeIdx);
|
||||
p.ctx.getInstruction().getInstructions().replace(p.ctx.getInstruction(), new NOP(p.ctx.getInstruction().getInstructions()));
|
||||
}
|
||||
pairs.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ClassGroup group)
|
||||
{
|
||||
Execution e = new Execution(group);
|
||||
e.addExecutionVisitor(i -> visit(i));
|
||||
e.addFrameVisitor(v -> visit(v));
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
@@ -17,80 +18,109 @@ import net.runelite.asm.execution.StackContext;
|
||||
|
||||
public class MultiplyZeroDeobfuscator implements Deobfuscator
|
||||
{
|
||||
private int count;
|
||||
private List<InstructionContext> pending = new ArrayList<>();
|
||||
|
||||
private void visit(InstructionContext ictx)
|
||||
{
|
||||
Instruction instruction = ictx.getInstruction();
|
||||
Instructions ins = instruction.getInstructions();
|
||||
if (ins == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Instruction> ilist = ins.getInstructions();
|
||||
|
||||
StackContext one = ictx.getPops().get(0);
|
||||
StackContext two = ictx.getPops().get(1);
|
||||
|
||||
Instruction ione = one.getPushed().getInstruction(),
|
||||
itwo = two.getPushed().getInstruction();
|
||||
|
||||
boolean remove = false;
|
||||
if (ione instanceof PushConstantInstruction)
|
||||
{
|
||||
PushConstantInstruction pci = (PushConstantInstruction) ione;
|
||||
Number value = (Number) pci.getConstant().getObject();
|
||||
|
||||
if (DMath.equals(value, 0))
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
if (itwo instanceof PushConstantInstruction)
|
||||
{
|
||||
PushConstantInstruction pci = (PushConstantInstruction) itwo;
|
||||
Number value = (Number) pci.getConstant().getObject();
|
||||
|
||||
if (DMath.equals(value, 0))
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (remove == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ilist.contains(instruction))
|
||||
{
|
||||
return; // 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))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// remove both, remove imul, push 0
|
||||
ictx.removeStack(1);
|
||||
ictx.removeStack(0);
|
||||
|
||||
if (instruction instanceof IMul)
|
||||
{
|
||||
ins.replace(instruction, new LDC_W(ins, new net.runelite.asm.pool.Integer(0)));
|
||||
}
|
||||
else if (instruction instanceof LMul)
|
||||
{
|
||||
ins.replace(instruction, new LDC2_W(ins, 0L));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
pending.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ClassGroup group)
|
||||
{
|
||||
group.buildClassGraph();
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.addExecutionVisitor(i -> visit(i));
|
||||
e.addFrameVisitor(v -> visit(v));
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (Frame frame : e.processedFrames)
|
||||
for (InstructionContext ictx : frame.getInstructions())
|
||||
{
|
||||
Instruction instruction = ictx.getInstruction();
|
||||
Instructions ins = instruction.getInstructions();
|
||||
if (ins == null)
|
||||
continue;
|
||||
|
||||
if (!(instruction instanceof IMul) && !(instruction instanceof LMul))
|
||||
continue;
|
||||
|
||||
List<Instruction> ilist = ins.getInstructions();
|
||||
|
||||
StackContext one = ictx.getPops().get(0);
|
||||
StackContext two = ictx.getPops().get(1);
|
||||
|
||||
Instruction ione = one.getPushed().getInstruction(),
|
||||
itwo = two.getPushed().getInstruction();
|
||||
|
||||
boolean remove = false;
|
||||
if (ione instanceof PushConstantInstruction)
|
||||
{
|
||||
PushConstantInstruction pci = (PushConstantInstruction) ione;
|
||||
Number value = (Number) pci.getConstant().getObject();
|
||||
|
||||
if (DMath.equals(value, 0))
|
||||
remove = true;
|
||||
}
|
||||
if (itwo instanceof PushConstantInstruction)
|
||||
{
|
||||
PushConstantInstruction pci = (PushConstantInstruction) itwo;
|
||||
Number value = (Number) pci.getConstant().getObject();
|
||||
|
||||
if (DMath.equals(value, 0))
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (remove == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ilist.contains(instruction))
|
||||
continue; // already done
|
||||
|
||||
if (!MultiplicationDeobfuscator.isOnlyPath(e, ictx))
|
||||
continue;
|
||||
|
||||
// remove both, remove imul, push 0
|
||||
|
||||
ictx.removeStack(1);
|
||||
ictx.removeStack(0);
|
||||
|
||||
if (instruction instanceof IMul)
|
||||
ins.replace(instruction, new LDC_W(ins, new net.runelite.asm.pool.Integer(0)));
|
||||
else if (instruction instanceof LMul)
|
||||
ins.replace(instruction, new LDC2_W(ins, 0L));
|
||||
else
|
||||
throw new IllegalStateException();
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
System.out.println("Removed " + count + " 0 multiplications");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,14 +231,14 @@ public class MultiplicationDeobfuscatorTest
|
||||
|
||||
assert constant4.getConstantAsInt() * constant5.getConstantAsInt() == 1;
|
||||
|
||||
{
|
||||
Collection<InstructionContext> ctxs = e.getInstructonContexts(body[3]);
|
||||
assert ctxs.size() == 1;
|
||||
|
||||
InstructionContext ictx = ctxs.iterator().next();
|
||||
boolean onlyPath = MultiplicationDeobfuscator.isOnlyPath(e, ictx);
|
||||
Assert.assertFalse(onlyPath);
|
||||
}
|
||||
// {
|
||||
// Collection<InstructionContext> ctxs = e.getInstructonContexts(body[3]);
|
||||
// assert ctxs.size() == 1;
|
||||
//
|
||||
// InstructionContext ictx = ctxs.iterator().next();
|
||||
// boolean onlyPath = MultiplicationDeobfuscator.isOnlyPath(e, ictx);
|
||||
// Assert.assertFalse(onlyPath);
|
||||
// }
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
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 org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class MultiplyZeroDeobfuscatorTest
|
||||
{
|
||||
private static final File GAMEPACK = new File("c:/rs/gamepack_v19.jar");
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = new TemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(GAMEPACK);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
MultiplyZeroDeobfuscator m = new MultiplyZeroDeobfuscator();
|
||||
m.run(group);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user