more work

This commit is contained in:
Adam
2015-10-30 22:36:29 -04:00
parent 8e68963f65
commit 113363cd67
5 changed files with 157 additions and 51 deletions

View File

@@ -23,6 +23,12 @@ public class LDC2_W extends Instruction implements PushConstantInstruction
super(instructions, type, pc); super(instructions, type, pc);
} }
public LDC2_W(Instructions instructions, long value)
{
super(instructions, InstructionType.LDC2_W, -1);
this.value = new net.runelite.deob.pool.Long(value);
}
@Override @Override
public void load(DataInputStream is) throws IOException public void load(DataInputStream is) throws IOException
{ {

View File

@@ -14,6 +14,12 @@ public class LMul extends Instruction
{ {
super(instructions, type, pc); super(instructions, type, pc);
} }
public LMul(Instructions instructions)
{
super(instructions, InstructionType.LMUL, -1);
}
@Override @Override
public void execute(Frame frame) public void execute(Frame frame)

View File

@@ -20,6 +20,16 @@ public class DMath
return modInverse(BigInteger.valueOf(val), 64).longValue(); return modInverse(BigInteger.valueOf(val), 64).longValue();
} }
public static Number modInverse(Number value)
{
if (value instanceof Integer)
return modInverse((int) value);
else if (value instanceof Long)
return modInverse((long) value);
else
throw new IllegalArgumentException();
}
public static boolean isInversable(int val) public static boolean isInversable(int val)
{ {
try try
@@ -33,6 +43,29 @@ public class DMath
} }
} }
private static boolean isInversable(long val)
{
try
{
modInverse(val);
return true;
}
catch (ArithmeticException ex)
{
return false;
}
}
public static boolean isInversable(Number value)
{
if (value instanceof Integer)
return isInversable((int) value);
else if (value instanceof Long)
return isInversable((long) value);
else
throw new IllegalArgumentException();
}
public static boolean isBig(int val) public static boolean isBig(int val)
{ {
if ((val & 0x80000000) != 0) if ((val & 0x80000000) != 0)
@@ -58,4 +91,30 @@ public class DMath
else else
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
public static Number multiply(Number one, Number two)
{
assert one.getClass() == two.getClass();
if (one instanceof Integer)
return (int) one * (int) two;
else if (one instanceof Long)
return (long) one * (long) two;
else
throw new IllegalArgumentException();
}
public static boolean equals(Number one, int two)
{
if (one instanceof Long)
return equals(one, ((long) two) & 0xffffffff);
return one.intValue() == two;
}
public static boolean equals(Number one, long two)
{
if (one instanceof Integer)
return equals(one, (int) one);
return one.longValue() == two;
}
} }

View File

@@ -21,6 +21,7 @@ import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction;
import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction; import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction;
import net.runelite.deob.attributes.code.instructions.IMul; import net.runelite.deob.attributes.code.instructions.IMul;
import net.runelite.deob.attributes.code.instructions.LDC2_W;
import net.runelite.deob.attributes.code.instructions.LDC_W; import net.runelite.deob.attributes.code.instructions.LDC_W;
import net.runelite.deob.attributes.code.instructions.LMul; import net.runelite.deob.attributes.code.instructions.LMul;
import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Execution;
@@ -76,12 +77,12 @@ public class ModArith implements Deobfuscator
if (sfi.getMyField() == field) if (sfi.getMyField() == field)
{ {
InstructionContext pushedsfi = ctx.getPops().get(0).getPushed(); InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
if (pushedsfi.getInstruction() instanceof LDC_W) if (pushedsfi.getInstruction() instanceof LDC_W || pushedsfi.getInstruction() instanceof LDC2_W)
{ {
LDC_W ldc = (LDC_W) pushedsfi.getInstruction(); PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction();
if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long) if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long)
{ {
Number it = ldc.getNumber(); Number it = (Number) ldc.getConstant().getObject();
if (DMath.isBig(it)) if (DMath.isBig(it))
// field = constant // field = constant
return true; return true;
@@ -92,16 +93,16 @@ public class ModArith implements Deobfuscator
Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction(); Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction();
Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction(); Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction();
LDC_W pci = null; PushConstantInstruction pci = null;
Instruction other = null; Instruction other = null;
if (one instanceof LDC_W) if (one instanceof LDC_W || one instanceof LDC2_W)
{ {
pci = (LDC_W) one; pci = (PushConstantInstruction) one;
other = two; other = two;
} }
else if (two instanceof LDC_W) else if (two instanceof LDC_W || two instanceof LDC2_W)
{ {
pci = (LDC_W) two; pci = (PushConstantInstruction) two;
other = one; other = one;
} }
@@ -110,7 +111,7 @@ public class ModArith implements Deobfuscator
{ {
if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long) if (pci.getConstant().getObject() instanceof Integer || pci.getConstant().getObject() instanceof Long)
{ {
Number i = pci.getNumber(); Number i = (Number) pci.getConstant().getObject();
if (DMath.isBig(i)) if (DMath.isBig(i))
// field = constant * not other field // field = constant * not other field
return true; return true;
@@ -127,16 +128,16 @@ public class ModArith implements Deobfuscator
Instruction one = ctx.getPops().get(0).getPushed().getInstruction(); Instruction one = ctx.getPops().get(0).getPushed().getInstruction();
Instruction two = ctx.getPops().get(1).getPushed().getInstruction(); Instruction two = ctx.getPops().get(1).getPushed().getInstruction();
LDC_W pc = null; PushConstantInstruction pc = null;
GetFieldInstruction other = null; GetFieldInstruction other = null;
if (one instanceof LDC_W && two instanceof GetFieldInstruction) if ((one instanceof LDC_W || one instanceof LDC2_W) && two instanceof GetFieldInstruction)
{ {
pc = (LDC_W) one; pc = (PushConstantInstruction) one;
other = (GetFieldInstruction) two; other = (GetFieldInstruction) two;
} }
else if (two instanceof LDC_W && one instanceof GetFieldInstruction) else if ((two instanceof LDC_W || two instanceof LDC2_W) && one instanceof GetFieldInstruction)
{ {
pc = (LDC_W) two; pc = (PushConstantInstruction) two;
other = (GetFieldInstruction) one; other = (GetFieldInstruction) one;
} }
@@ -151,7 +152,7 @@ public class ModArith implements Deobfuscator
if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long)) if (!(pc.getConstant().getObject() instanceof Integer) && !(pc.getConstant().getObject() instanceof Long))
continue; continue;
Number ivalue = pc.getNumber(); Number ivalue = (Number) pc.getConstant().getObject();
if (!DMath.isBig(ivalue)) if (!DMath.isBig(ivalue))
continue; continue;
@@ -225,13 +226,13 @@ public class ModArith implements Deobfuscator
for (InstructionContext i : l) for (InstructionContext i : l)
{ {
if (i.getInstruction() instanceof LDC_W) if (i.getInstruction() instanceof LDC_W || i.getInstruction() instanceof LDC2_W)
{ {
LDC_W w = (LDC_W) i.getInstruction(); PushConstantInstruction w = (PushConstantInstruction) i.getInstruction();
if (w.getConstant().getObject() instanceof Integer || w.getConstant().getObject() instanceof Long) if (w.getConstant().getObject() instanceof Integer || w.getConstant().getObject() instanceof Long)
{ {
AssociatedConstant n = new AssociatedConstant(); AssociatedConstant n = new AssociatedConstant();
n.value = w.getNumber(); n.value = (Number) w.getConstant().getObject();
n.other = other; n.other = other;
constants.put(fi.getMyField(), n); constants.put(fi.getMyField(), n);
} }
@@ -273,7 +274,7 @@ public class ModArith implements Deobfuscator
Number value = (Number) pc.getConstant().getObject(); Number value = (Number) pc.getConstant().getObject();
if ((int) value == 1 || (int) value == 0) if (DMath.equals(value, 1) || DMath.equals(value, 0))
continue; continue;
// field * constant // field * constant
@@ -290,13 +291,13 @@ public class ModArith implements Deobfuscator
StackContext value = ctx.getPops().get(0); // the first thing popped from both putfield and putstatic is the value StackContext value = ctx.getPops().get(0); // the first thing popped from both putfield and putstatic is the value
if (!(value.getPushed().getInstruction() instanceof IMul) && !(value.getPushed().getInstruction() instanceof LMul)) if (!(value.getPushed().getInstruction() instanceof IMul) && !(value.getPushed().getInstruction() instanceof LMul))
{ {
if (value.getPushed().getInstruction() instanceof LDC_W) if (value.getPushed().getInstruction() instanceof LDC_W || value.getPushed().getInstruction() instanceof LDC2_W)
{ {
LDC_W ldc = (LDC_W) value.getPushed().getInstruction(); PushConstantInstruction ldc = (PushConstantInstruction) value.getPushed().getInstruction();
if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long) if (ldc.getConstant().getObject() instanceof Integer || ldc.getConstant().getObject() instanceof Long)
{ {
Number i = ldc.getNumber(); Number i = (Number) ldc.getConstant().getObject();
if (DMath.isBig(i)) if (DMath.isBig(i))
// field = constant // field = constant
@@ -327,7 +328,7 @@ public class ModArith implements Deobfuscator
Number value2 = (Number) pc.getConstant().getObject(); Number value2 = (Number) pc.getConstant().getObject();
if ((int) value2 == 1 || (int) value2 == 0) if (DMath.equals(value2, 1) || DMath.equals(value2, 0))
continue; continue;
// field = something * constant // field = something * constant
@@ -340,21 +341,29 @@ public class ModArith implements Deobfuscator
{ {
// multiply each by each, // multiply each by each,
// lowest number wins // lowest number wins
int s1 = 0, s2 = 0; Number s1 = 0, s2 = 0;
int smallest = 0; Number smallest = 0;
for (Integer i : constants) for (Number i : constants)
{ {
for (Integer i2 : constants) for (Number i2 : constants)
{ {
if (i == 0 || i2 == 0) if (DMath.equals(i, 0) || DMath.equals(i2, 0))
continue; continue;
int result = i * i2; Number result = DMath.multiply(i, i2);
if (result == 0) if (DMath.equals(result, 0))
continue; continue;
if (smallest == 0 || result == 1 || Math.abs(result) < Math.abs(smallest)) boolean smaller;
if (smallest.longValue() == 0L)
smaller = false;
else if (i instanceof Long)
smaller = Math.abs((long) result) < Math.abs((long) smallest);
else
smaller = Math.abs((int) result) < Math.abs((int) smallest);
if (DMath.equals(smallest, 0) || DMath.equals(result, 1) || smaller)
{ {
s1 = i; s1 = i;
s2 = i2; s2 = i2;
@@ -363,7 +372,7 @@ public class ModArith implements Deobfuscator
} }
} }
if (smallest != 1) if (!DMath.equals(smallest, 1))
{ {
if (DMath.isInversable(smallest)) if (DMath.isInversable(smallest))
{ {
@@ -372,15 +381,15 @@ public class ModArith implements Deobfuscator
if (DMath.isInversable(s1)) if (DMath.isInversable(s1))
{ {
s2 = s2 * DMath.modInverse(smallest); s2 = DMath.multiply(s2, DMath.modInverse(smallest));
smallest = 1; smallest = 1;
assert s1 * s2 == 1; assert DMath.multiply(s1, s2).intValue() == 1;
} }
else if (DMath.isInversable(s2)) else if (DMath.isInversable(s2))
{ {
s1 = s1 * DMath.modInverse(smallest); s1 = DMath.multiply(s1, DMath.modInverse(smallest));
smallest = 1; smallest = 1;
assert s1 * s2 == 1; assert DMath.multiply(s1, s2).intValue() == 1;
} }
else else
{ {
@@ -392,22 +401,22 @@ public class ModArith implements Deobfuscator
{ {
if (DMath.isInversable(s1)) if (DMath.isInversable(s1))
{ {
int newTwo = DMath.modInverse(s1); Number newTwo = DMath.modInverse(s1);
if (newTwo * smallest == s2) if (DMath.multiply(newTwo, smallest).equals(s2))
{ {
s2 = newTwo; s2 = newTwo;
smallest = 1; smallest = 1;
assert s1 * s2 == 1; assert DMath.multiply(s1, s2).intValue() == 1;
} }
} }
else if (DMath.isInversable(s2)) else if (DMath.isInversable(s2))
{ {
int newTwo = DMath.modInverse(s2); Number newTwo = DMath.modInverse(s2);
if (newTwo * smallest == s1) if (DMath.multiply(newTwo, smallest).equals(s1))
{ {
s1 = newTwo; s1 = newTwo;
smallest = 1; smallest = 1;
assert s1 * s2 == 1; assert DMath.multiply(s1, s2).intValue() == 1;
} }
} }
else else
@@ -452,9 +461,9 @@ public class ModArith implements Deobfuscator
} }
// figure out if value is a getter or setter // figure out if value is a getter or setter
private boolean isGetterOrSetter(Field field, boolean getter, int value) private boolean isGetterOrSetter(Field field, boolean getter, Number value)
{ {
Collection<Integer> c; Collection<Number> c;
if (getter) if (getter)
c = this.constantGetters.getCollection(field); c = this.constantGetters.getCollection(field);
else else
@@ -465,12 +474,12 @@ public class ModArith implements Deobfuscator
if (c.contains(value)) if (c.contains(value))
return true; return true;
for (int i : c) for (Number i : c)
{ {
// i = value * constant // i = value * constant
// find constant = i * modInverse(value) // find constant = i * modInverse(value)
int constant = i * DMath.modInverse(value); Number constant = DMath.multiply(i, DMath.modInverse(value));
if (!DMath.isBig(constant)) if (!DMath.isBig(constant))
return true; return true;
@@ -571,8 +580,18 @@ public class ModArith implements Deobfuscator
// insert push getter // insert push getter
// insert imul // insert imul
ilist.add(i++, new LDC_W(ins, new net.runelite.deob.pool.Integer(p.getter))); if (p.getType() == Integer.class)
ilist.add(i++, new IMul(ins)); {
ilist.add(i++, new LDC_W(ins, new net.runelite.deob.pool.Integer((int) p.getter)));
ilist.add(i++, new IMul(ins));
}
else if (p.getType() == Long.class)
{
ilist.add(i++, new LDC2_W(ins, (long) p.getter));
ilist.add(i++, new LMul(ins));
}
else
throw new IllegalStateException();
} }
else if (in instanceof GetFieldInstruction) else if (in instanceof GetFieldInstruction)
{ {
@@ -588,8 +607,18 @@ public class ModArith implements Deobfuscator
// add after: push setter // add after: push setter
// imul // imul
ilist.add(++i, new LDC_W(ins, new net.runelite.deob.pool.Integer(p.setter))); if (p.getType() == Integer.class)
ilist.add(++i, new IMul(ins)); {
ilist.add(++i, new LDC_W(ins, new net.runelite.deob.pool.Integer((int) p.setter)));
ilist.add(++i, new IMul(ins));
}
else if (p.getType() == Long.class)
{
ilist.add(++i, new LDC2_W(ins, (long) p.setter));
ilist.add(++i, new LMul(ins));
}
else
throw new IllegalStateException();
} }
} }
} }

View File

@@ -5,5 +5,11 @@ import net.runelite.deob.Field;
public class Pair public class Pair
{ {
public Field field; public Field field;
public int getter, setter; public Number getter, setter;
public Class getType()
{
assert getter.getClass() == setter.getClass();
return getter.getClass();
}
} }