Check per pop if its multiple places or not
This commit is contained in:
@@ -22,6 +22,7 @@ import net.runelite.deob.attributes.code.instructions.SiPush;
|
|||||||
import net.runelite.deob.execution.Execution;
|
import net.runelite.deob.execution.Execution;
|
||||||
import net.runelite.deob.execution.Frame;
|
import net.runelite.deob.execution.Frame;
|
||||||
import net.runelite.deob.execution.InstructionContext;
|
import net.runelite.deob.execution.InstructionContext;
|
||||||
|
import net.runelite.deob.execution.Stack;
|
||||||
import net.runelite.deob.execution.StackContext;
|
import net.runelite.deob.execution.StackContext;
|
||||||
|
|
||||||
public class MultiplicationDeobfuscator implements Deobfuscator
|
public class MultiplicationDeobfuscator implements Deobfuscator
|
||||||
@@ -60,14 +61,21 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
|||||||
return me;
|
return me;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.getInstruction() instanceof IMul)
|
// if (ctx.getInstruction() instanceof IMul)
|
||||||
{
|
// {
|
||||||
if (!this.isOnlyPath(e, ctx))
|
// if (!isOnlyPath(e, ctx))
|
||||||
throw new IllegalStateException();
|
// throw new IllegalStateException();
|
||||||
}
|
// }
|
||||||
|
|
||||||
for (StackContext sctx : ctx.getPops())
|
for (StackContext sctx : ctx.getPops())
|
||||||
{
|
{
|
||||||
|
if (ctx.getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
|
if (!isOnlyPath(e, ctx, sctx))
|
||||||
|
continue;
|
||||||
|
//throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
InstructionContext i = sctx.getPushed();
|
InstructionContext i = sctx.getPushed();
|
||||||
|
|
||||||
// int count2 = 0;
|
// int count2 = 0;
|
||||||
@@ -257,12 +265,50 @@ public class MultiplicationDeobfuscator implements Deobfuscator
|
|||||||
for (StackContext sctx : i.getPushes())
|
for (StackContext sctx : i.getPushes())
|
||||||
if (sctx.getPopped().size() > 1)
|
if (sctx.getPopped().size() > 1)
|
||||||
return false;
|
return false;
|
||||||
///if (i.getPushes().size() > 1)
|
}
|
||||||
// return false;
|
return true;
|
||||||
// if (!Objects.equals(i.getPushes().get(0).getPopped(), ctx.getPushes().get(0).getPopped()))
|
}
|
||||||
// {
|
|
||||||
// return false;
|
private static boolean ictxEqualsDir(InstructionContext one, InstructionContext two, StackContext sctx)
|
||||||
// }
|
{
|
||||||
|
if (one.getInstruction() != two.getInstruction())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check if stack at time of execution is equal
|
||||||
|
List<StackContext> ours = one.getStack().getStack(), theirs = two.getStack().getStack();
|
||||||
|
//Stack ours = new Stack(one.getStack()), // copy stacks since we destroy them
|
||||||
|
// theirs = new Stack(two.getStack());
|
||||||
|
|
||||||
|
if (ours.size() != theirs.size()) // is this possible?
|
||||||
|
return false;
|
||||||
|
|
||||||
|
assert ours.contains(sctx);
|
||||||
|
int i = ours.indexOf(sctx);
|
||||||
|
|
||||||
|
StackContext theirsctx = theirs.get(i);
|
||||||
|
|
||||||
|
if (sctx.getPushed().getInstruction() != theirsctx.getPushed().getInstruction())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOnlyPath(Execution execution, InstructionContext ctx, StackContext sctx)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
assert ctx.getInstruction() instanceof IMul;
|
||||||
|
Collection<InstructionContext> ins = execution.getInstructonContexts(ctx.getInstruction());
|
||||||
|
for (InstructionContext i : ins)
|
||||||
|
{
|
||||||
|
if (!ictxEqualsDir(ctx, i, sctx))
|
||||||
|
/// if (!i.equals(ctx))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (StackContext s : i.getPushes())
|
||||||
|
if (s.getPopped().size() > 1)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,11 +81,12 @@ public class MultiplicationExpression
|
|||||||
PushConstantInstruction pci = (PushConstantInstruction) i.getInstruction();
|
PushConstantInstruction pci = (PushConstantInstruction) i.getInstruction();
|
||||||
Instruction newIns = pci.setConstant(new net.runelite.deob.pool.Integer(result));
|
Instruction newIns = pci.setConstant(new net.runelite.deob.pool.Integer(result));
|
||||||
++count;
|
++count;
|
||||||
if (newIns != pci)
|
assert newIns == pci;
|
||||||
{
|
// if (newIns != pci)
|
||||||
newIns.getInstructions().replace((Instruction) pci, newIns);
|
// {
|
||||||
replace = true;
|
// newIns.getInstructions().replace((Instruction) pci, newIns);
|
||||||
}
|
// replace = true;
|
||||||
|
// }
|
||||||
result = 1; // rest of the results go to 1
|
result = 1; // rest of the results go to 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.runelite.deob.execution;
|
package net.runelite.deob.execution;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Stack
|
public class Stack
|
||||||
{
|
{
|
||||||
@@ -12,7 +13,7 @@ public class Stack
|
|||||||
stack = new StackContext[sz*2]; // XXX FIXME
|
stack = new StackContext[sz*2]; // XXX FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Stack(Stack other)
|
public Stack(Stack other)
|
||||||
{
|
{
|
||||||
this.size = other.size;
|
this.size = other.size;
|
||||||
this.stack = Arrays.copyOf(other.stack, other.stack.length);
|
this.stack = Arrays.copyOf(other.stack, other.stack.length);
|
||||||
@@ -56,4 +57,9 @@ public class Stack
|
|||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<StackContext> getStack()
|
||||||
|
{
|
||||||
|
return Arrays.asList(stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,8 @@ public class StackContext
|
|||||||
|
|
||||||
public void addPopped(InstructionContext popped)
|
public void addPopped(InstructionContext popped)
|
||||||
{
|
{
|
||||||
//assert !this.poppeds.contains(popped);
|
|
||||||
if (!this.poppeds.contains(popped))
|
if (!this.poppeds.contains(popped))
|
||||||
this.poppeds.add(popped);
|
this.poppeds.add(popped);
|
||||||
//assert this.popped == null;
|
|
||||||
//this.popped = popped;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType()
|
public Type getType()
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ import net.runelite.deob.attributes.code.Instructions;
|
|||||||
import net.runelite.deob.attributes.code.instructions.Dup_X1;
|
import net.runelite.deob.attributes.code.instructions.Dup_X1;
|
||||||
import net.runelite.deob.attributes.code.instructions.IAdd;
|
import net.runelite.deob.attributes.code.instructions.IAdd;
|
||||||
import net.runelite.deob.attributes.code.instructions.IConst_0;
|
import net.runelite.deob.attributes.code.instructions.IConst_0;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.IConst_1;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.IConst_2;
|
||||||
import net.runelite.deob.attributes.code.instructions.IConst_3;
|
import net.runelite.deob.attributes.code.instructions.IConst_3;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.IDiv;
|
||||||
import net.runelite.deob.attributes.code.instructions.ILoad;
|
import net.runelite.deob.attributes.code.instructions.ILoad;
|
||||||
import net.runelite.deob.attributes.code.instructions.IMul;
|
import net.runelite.deob.attributes.code.instructions.IMul;
|
||||||
import net.runelite.deob.attributes.code.instructions.IStore_0;
|
import net.runelite.deob.attributes.code.instructions.IStore_0;
|
||||||
@@ -166,84 +169,6 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
Assert.assertEquals(1, constant4.getConstantAsInt());
|
Assert.assertEquals(1, constant4.getConstantAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
|
||||||
// public void testDupX1_3()
|
|
||||||
// {
|
|
||||||
// ClassGroup group = ClassGroupFactory.generateGroup();
|
|
||||||
// Code code = group.findClass("test").findMethod("func").getCode();
|
|
||||||
// Instructions ins = code.getInstructions();
|
|
||||||
//
|
|
||||||
// code.setMaxStack(2);
|
|
||||||
//
|
|
||||||
// Instruction[] prepareVariables = {
|
|
||||||
// new IConst_3(ins),
|
|
||||||
// new IStore_0(ins),
|
|
||||||
// new IConst_3(ins),
|
|
||||||
// new IStore_1(ins),
|
|
||||||
// new IConst_3(ins),
|
|
||||||
// new IStore_2(ins),
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// for (Instruction i : prepareVariables)
|
|
||||||
// ins.addInstruction(i);
|
|
||||||
//
|
|
||||||
// LDC_W constant1 = new LDC_W(ins, 1381104939),
|
|
||||||
// constant2 = new LDC_W(ins, 1381104939),
|
|
||||||
// constant3 = new LDC_W(ins, 981643079),
|
|
||||||
// constant4 = new LDC_W(ins, 1807370871),
|
|
||||||
// constant5 = new LDC_W(ins, 1807370871),
|
|
||||||
// constant6 = new LDC_W(ins, 981643079);
|
|
||||||
//
|
|
||||||
// NOP label1 = new NOP(ins),
|
|
||||||
// label2 = new NOP(ins);
|
|
||||||
//
|
|
||||||
// Instruction body[] = {
|
|
||||||
// new IConst_1(ins),
|
|
||||||
// new ILoad(ins, 0),
|
|
||||||
// new If(ins, label1),
|
|
||||||
// constant1,
|
|
||||||
// new ILoad(ins, 1),
|
|
||||||
// new IMul(ins),
|
|
||||||
// new Goto(ins, label2),
|
|
||||||
// label1,
|
|
||||||
// new ILoad(ins, 1),
|
|
||||||
// constant2,
|
|
||||||
// new IMul(ins),
|
|
||||||
// constant3,
|
|
||||||
// new ILoad(ins, 2),
|
|
||||||
// constant4,
|
|
||||||
// new IMul(ins),
|
|
||||||
// new IMul(ins),
|
|
||||||
// new IAdd(ins),
|
|
||||||
// new IConst_2(ins),
|
|
||||||
// new IDiv(ins),
|
|
||||||
// label2,
|
|
||||||
// constant5,
|
|
||||||
// new IMul(ins),
|
|
||||||
// constant6,
|
|
||||||
// new IMul(ins),
|
|
||||||
// new IStore(ins, 3),
|
|
||||||
// new VReturn(ins)
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// for (Instruction i : body)
|
|
||||||
// ins.addInstruction(i);
|
|
||||||
//
|
|
||||||
// Execution e = new Execution(group);
|
|
||||||
// e.populateInitialMethods();
|
|
||||||
// e.run();
|
|
||||||
//
|
|
||||||
// Deobfuscator d = new MultiplicationDeobfuscator();
|
|
||||||
// d.run(group);
|
|
||||||
//
|
|
||||||
// Assert.assertEquals(1381104939, constant1.getConstantAsInt());
|
|
||||||
// Assert.assertEquals(1381104939, constant2.getConstantAsInt());
|
|
||||||
// Assert.assertEquals(981643079, constant3.getConstantAsInt());
|
|
||||||
// Assert.assertEquals(1807370871, constant4.getConstantAsInt());
|
|
||||||
// Assert.assertEquals(1807370871, constant5.getConstantAsInt());
|
|
||||||
// Assert.assertEquals(981643079, constant6.getConstantAsInt());
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_3()
|
public void testDupX1_3()
|
||||||
{
|
{
|
||||||
@@ -311,8 +236,65 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
|
|
||||||
Assert.assertEquals(1381104939, constant1.getConstantAsInt());
|
Assert.assertEquals(1381104939, constant1.getConstantAsInt());
|
||||||
Assert.assertEquals(1381104939, constant2.getConstantAsInt());
|
Assert.assertEquals(1381104939, constant2.getConstantAsInt());
|
||||||
Assert.assertEquals(981643079, constant3.getConstantAsInt());
|
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||||
Assert.assertEquals(1, constant4.getConstantAsInt());
|
Assert.assertEquals(1, constant4.getConstantAsInt());
|
||||||
Assert.assertEquals(1, constant5.getConstantAsInt());
|
Assert.assertEquals(981643079, constant5.getConstantAsInt()); // assumes result is moved to the end here.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDupX1_4()
|
||||||
|
{
|
||||||
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
|
Instructions ins = code.getInstructions();
|
||||||
|
|
||||||
|
code.setMaxStack(2);
|
||||||
|
|
||||||
|
Instruction[] prepareVariables = {
|
||||||
|
new IConst_3(ins),
|
||||||
|
new IStore_0(ins),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Instruction i : prepareVariables)
|
||||||
|
ins.addInstruction(i);
|
||||||
|
|
||||||
|
LDC_W constant1 = new LDC_W(ins, 1807370871),
|
||||||
|
constant2 = new LDC_W(ins, 981643079);
|
||||||
|
|
||||||
|
NOP label1 = new NOP(ins);
|
||||||
|
|
||||||
|
Instruction body[] = {
|
||||||
|
new ILoad(ins, 0),
|
||||||
|
new LDC_W(ins, 2),
|
||||||
|
new IMul(ins),
|
||||||
|
|
||||||
|
new IConst_0(ins),
|
||||||
|
new If0(ins, label1),
|
||||||
|
|
||||||
|
new Pop(ins),
|
||||||
|
new LDC_W(ins, 3),
|
||||||
|
|
||||||
|
label1,
|
||||||
|
constant1,
|
||||||
|
new IMul(ins),
|
||||||
|
constant2,
|
||||||
|
new IMul(ins),
|
||||||
|
new VReturn(ins)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Instruction i : body)
|
||||||
|
ins.addInstruction(i);
|
||||||
|
|
||||||
|
Execution e = new Execution(group);
|
||||||
|
e.populateInitialMethods();
|
||||||
|
e.run();
|
||||||
|
|
||||||
|
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||||
|
|
||||||
|
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||||
|
d.run(group);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||||
|
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user