Work.
This commit is contained in:
@@ -26,6 +26,7 @@ import net.runelite.deob.deobfuscators.UnusedFields;
|
|||||||
import net.runelite.deob.deobfuscators.UnusedMethods;
|
import net.runelite.deob.deobfuscators.UnusedMethods;
|
||||||
import net.runelite.deob.deobfuscators.UnusedParameters;
|
import net.runelite.deob.deobfuscators.UnusedParameters;
|
||||||
import net.runelite.deob.deobfuscators.arithmetic.ModArith;
|
import net.runelite.deob.deobfuscators.arithmetic.ModArith;
|
||||||
|
import net.runelite.deob.execution.Execution;
|
||||||
|
|
||||||
//move static methods
|
//move static methods
|
||||||
//move static fields
|
//move static fields
|
||||||
@@ -41,7 +42,6 @@ public class Deob
|
|||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
ClassGroup group = loadJar(args[0]);
|
ClassGroup group = loadJar(args[0]);
|
||||||
long bstart, bdur;
|
|
||||||
|
|
||||||
// bstart = System.currentTimeMillis();
|
// bstart = System.currentTimeMillis();
|
||||||
// new RenameUnique().run(group);
|
// new RenameUnique().run(group);
|
||||||
@@ -49,71 +49,45 @@ public class Deob
|
|||||||
// System.out.println("rename unique took " + bdur/1000L + " seconds");
|
// System.out.println("rename unique took " + bdur/1000L + " seconds");
|
||||||
|
|
||||||
// // remove except RuntimeException
|
// // remove except RuntimeException
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new RuntimeExceptions());
|
||||||
// new RuntimeExceptions().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("runtime exception took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove unused methods
|
// // remove unused methods
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new UnusedMethods());
|
||||||
// new UnusedMethods().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// new UnreachedCode().run(group);
|
// run(group, new UnreachedCode());
|
||||||
//
|
//
|
||||||
// // remove illegal state exceptions, frees up some parameters
|
// // remove illegal state exceptions, frees up some parameters
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new IllegalStateExceptions());
|
||||||
// new IllegalStateExceptions().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove constant logically dead parameters
|
// // remove constant logically dead parameters
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new ConstantParameter());
|
||||||
// new ConstantParameter().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("constant param took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove unhit blocks
|
// // remove unhit blocks
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new UnreachedCode());
|
||||||
// new UnreachedCode().run(group);
|
|
||||||
// //new UnusedBlocks().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("unused blocks took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove unused parameters
|
// // remove unused parameters
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new UnusedParameters());
|
||||||
// new UnusedParameters().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("unused params took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove jump obfuscation
|
// // remove jump obfuscation
|
||||||
// //new Jumps().run(group);
|
// //new Jumps().run(group);
|
||||||
//
|
//
|
||||||
// // remove unused fields
|
// // remove unused fields
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new UnusedFields());
|
||||||
// new UnusedFields().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("unused fields took " + bdur/1000L + " seconds");
|
|
||||||
//
|
//
|
||||||
// // remove unused methods, again?
|
// // remove unused methods, again?
|
||||||
// bstart = System.currentTimeMillis();
|
// run(group, new UnusedMethods());
|
||||||
// new UnusedMethods().run(group);
|
|
||||||
// bdur = System.currentTimeMillis() - bstart;
|
|
||||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
|
||||||
|
|
||||||
|
|
||||||
//new MethodInliner().run(group);
|
|
||||||
//
|
//
|
||||||
// new MethodMover().run(group);
|
// run(group, new MethodInliner());
|
||||||
//
|
//
|
||||||
// new FieldInliner().run(group);
|
// run(group, new MethodMover());
|
||||||
|
//
|
||||||
// XXX this is broken because when moving clinit around, some fields can depend on other fields
|
// run(group, new FieldInliner());
|
||||||
// (like multianewarray)
|
//
|
||||||
//new FieldMover().run(group);
|
// // XXX this is broken because when moving clinit around, some fields can depend on other fields
|
||||||
|
// // (like multianewarray)
|
||||||
//new UnusedClass().run(group);
|
// //new FieldMover().run(group);
|
||||||
|
//
|
||||||
|
// run(group, new UnusedClass());
|
||||||
|
|
||||||
// new ModularArithmeticDeobfuscation().run(group);
|
// new ModularArithmeticDeobfuscation().run(group);
|
||||||
|
|
||||||
@@ -168,4 +142,20 @@ public class Deob
|
|||||||
|
|
||||||
jout.close();
|
jout.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void run(ClassGroup group, Deobfuscator deob)
|
||||||
|
{
|
||||||
|
long bstart, bdur;
|
||||||
|
|
||||||
|
bstart = System.currentTimeMillis();
|
||||||
|
deob.run(group);
|
||||||
|
bdur = System.currentTimeMillis() - bstart;
|
||||||
|
|
||||||
|
System.out.println(deob.getClass().getName() + " took " + (bdur / 1000L) + " seconds");
|
||||||
|
|
||||||
|
// check code is still correct
|
||||||
|
Execution execution = new Execution(group);
|
||||||
|
execution.populateInitialMethods();
|
||||||
|
execution.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +45,6 @@ public class IMul extends Instruction
|
|||||||
{
|
{
|
||||||
int o = other * DMath.modInverse(one.encryption);
|
int o = other * DMath.modInverse(one.encryption);
|
||||||
|
|
||||||
System.out.println(other + " -> " + o);
|
|
||||||
|
|
||||||
encryption.change(pci, o);
|
encryption.change(pci, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +62,6 @@ public class IMul extends Instruction
|
|||||||
{
|
{
|
||||||
int o = other * DMath.modInverse(two.encryption);
|
int o = other * DMath.modInverse(two.encryption);
|
||||||
|
|
||||||
System.out.println(other + " -> " + o);
|
|
||||||
|
|
||||||
encryption.change(pci, o);
|
encryption.change(pci, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ import net.runelite.deob.pool.NameAndType;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction;
|
||||||
|
import net.runelite.deob.deobfuscators.arithmetic.Encryption;
|
||||||
|
import net.runelite.deob.deobfuscators.arithmetic.Pair;
|
||||||
|
|
||||||
public class PutField extends Instruction implements SetFieldInstruction
|
public class PutField extends Instruction implements SetFieldInstruction
|
||||||
{
|
{
|
||||||
@@ -43,10 +47,89 @@ public class PutField extends Instruction implements SetFieldInstruction
|
|||||||
InstructionContext ins = new InstructionContext(this, frame);
|
InstructionContext ins = new InstructionContext(this, frame);
|
||||||
Stack stack = frame.getStack();
|
Stack stack = frame.getStack();
|
||||||
|
|
||||||
StackContext object = stack.pop();
|
|
||||||
StackContext value = stack.pop();
|
StackContext value = stack.pop();
|
||||||
|
StackContext object = stack.pop();
|
||||||
ins.pop(object, value);
|
ins.pop(object, value);
|
||||||
|
|
||||||
|
Encryption encryption = frame.getExecution().getEncryption();
|
||||||
|
net.runelite.deob.Field myField = getMyField();
|
||||||
|
if (encryption != null && myField != null)
|
||||||
|
{
|
||||||
|
Pair pair = encryption.getField(myField);
|
||||||
|
InstructionContext ctx = value.getPushed();
|
||||||
|
if (ctx.getInstruction() instanceof IAdd && pair != null)
|
||||||
|
{
|
||||||
|
// field += constant * crap;
|
||||||
|
// in bytecode is really
|
||||||
|
// field = field + constant * crap
|
||||||
|
|
||||||
|
List<StackContext> pops = ctx.getPops();
|
||||||
|
|
||||||
|
if (pops.get(0).getPushed().getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
|
ctx = pops.get(0).getPushed();
|
||||||
|
}
|
||||||
|
else if (pops.get(1).getPushed().getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
|
ctx = pops.get(1).getPushed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctx.getInstruction() instanceof PushConstantInstruction && pair != null)
|
||||||
|
{
|
||||||
|
// field = encryptedvalue
|
||||||
|
// decrypt value by * getter
|
||||||
|
|
||||||
|
PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction();
|
||||||
|
int v = (int) pci.getConstant().getObject();
|
||||||
|
|
||||||
|
if (v != 0 && v != 1)
|
||||||
|
{
|
||||||
|
v = v * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctx.getInstruction() instanceof ISub)
|
||||||
|
{
|
||||||
|
List<StackContext> stackCtx = ctx.getPops();
|
||||||
|
|
||||||
|
StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
||||||
|
|
||||||
|
if (one.getPushed().getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
|
ctx = one.getPushed();
|
||||||
|
}
|
||||||
|
else if (two.getPushed().getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
|
ctx = two.getPushed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctx.getInstruction() instanceof IMul && pair != null)
|
||||||
|
{
|
||||||
|
List<StackContext> stackCtx = ctx.getPops();
|
||||||
|
|
||||||
|
StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
||||||
|
|
||||||
|
StackContext magicStack = PutStatic.findMagic(one, two);
|
||||||
|
|
||||||
|
if (magicStack != null)
|
||||||
|
{
|
||||||
|
PushConstantInstruction pci = (PushConstantInstruction) magicStack.getPushed().getInstruction();
|
||||||
|
int v = (int) pci.getConstant().getObject();
|
||||||
|
|
||||||
|
// field is encrypted with pair
|
||||||
|
// divide value by setter
|
||||||
|
|
||||||
|
if (v != 0 && v != 1)
|
||||||
|
{
|
||||||
|
v = v * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
out.writeShort(this.getPool().make(field));
|
out.writeShort(this.getPool().make(field));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StackContext findMagic(StackContext one, StackContext two)
|
protected static StackContext findMagic(StackContext one, StackContext two)
|
||||||
{
|
{
|
||||||
if (one.getPushed().getInstruction() instanceof PushConstantInstruction)
|
if (one.getPushed().getInstruction() instanceof PushConstantInstruction)
|
||||||
{
|
{
|
||||||
@@ -69,6 +69,44 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean translate(Encryption encryption, Pair pair, InstructionContext ctx)
|
||||||
|
{
|
||||||
|
if (ctx.getInstruction() instanceof LDC_W)
|
||||||
|
{
|
||||||
|
LDC_W pci = (LDC_W) ctx.getInstruction();
|
||||||
|
int value = (int) pci.getConstant().getObject();
|
||||||
|
|
||||||
|
if (encryption.hasChange(pci))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (value != 0 && value != 1)
|
||||||
|
{
|
||||||
|
value = value * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean multipleBranches = ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub;
|
||||||
|
boolean retVal = false;
|
||||||
|
|
||||||
|
for (StackContext sctx : ctx.getPops())
|
||||||
|
{
|
||||||
|
InstructionContext i = sctx.getPushed();
|
||||||
|
|
||||||
|
if (translate(encryption, pair, i))
|
||||||
|
{
|
||||||
|
retVal = true;
|
||||||
|
if (!multipleBranches)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Frame frame)
|
public void execute(Frame frame)
|
||||||
{
|
{
|
||||||
@@ -83,68 +121,33 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
if (encryption != null && myField != null)
|
if (encryption != null && myField != null)
|
||||||
{
|
{
|
||||||
Pair pair = encryption.getField(myField);
|
Pair pair = encryption.getField(myField);
|
||||||
InstructionContext ctx = object.getPushed();
|
if (pair != null)
|
||||||
if (ctx.getInstruction() instanceof PushConstantInstruction && pair != null)
|
translate(encryption, pair, ins);
|
||||||
{
|
// InstructionContext ctx = object.getPushed();
|
||||||
// field = encryptedvalue
|
// if (ctx.getInstruction() instanceof IAdd && pair != null)
|
||||||
// decrypt value by * getter
|
|
||||||
|
|
||||||
PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction();
|
|
||||||
int value = (int) pci.getConstant().getObject();
|
|
||||||
|
|
||||||
if (value != 0 && value != 1)
|
|
||||||
{
|
|
||||||
value = value * pair.getter;
|
|
||||||
|
|
||||||
encryption.change(pci, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ctx.getInstruction() instanceof ISub)
|
|
||||||
{
|
|
||||||
List<StackContext> stackCtx = ctx.getPops();
|
|
||||||
|
|
||||||
StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
|
||||||
|
|
||||||
if (one.getPushed().getInstruction() instanceof IMul)
|
|
||||||
{
|
|
||||||
ctx = one.getPushed();
|
|
||||||
}
|
|
||||||
else if (two.getPushed().getInstruction() instanceof IMul)
|
|
||||||
{
|
|
||||||
ctx = two.getPushed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ctx.getInstruction() instanceof IMul && pair != null)
|
|
||||||
{
|
|
||||||
List<StackContext> stackCtx = ctx.getPops();
|
|
||||||
|
|
||||||
StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
|
||||||
|
|
||||||
StackContext magicStack = findMagic(one, two);
|
|
||||||
|
|
||||||
if (magicStack != null)
|
|
||||||
{
|
|
||||||
PushConstantInstruction pci = (PushConstantInstruction) magicStack.getPushed().getInstruction();
|
|
||||||
int value = (int) pci.getConstant().getObject();
|
|
||||||
|
|
||||||
// field is encrypted with pair
|
|
||||||
// divide value by setter
|
|
||||||
|
|
||||||
if (value != 0 && value != 1)
|
|
||||||
{
|
|
||||||
value = value * pair.getter;
|
|
||||||
|
|
||||||
encryption.change(pci, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (one.getPushed().getInstruction() instanceof PushConstantInstruction)
|
|
||||||
// {
|
// {
|
||||||
// PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction();
|
// // field += constant * crap;
|
||||||
// int value = (int) pci.getConstant().getObject();
|
// // in bytecode is really
|
||||||
|
// // field = field + constant * crap
|
||||||
//
|
//
|
||||||
// // field is encrypted with pair
|
// List<StackContext> pops = ctx.getPops();
|
||||||
// // divide value by setter
|
//
|
||||||
|
// if (pops.get(0).getPushed().getInstruction() instanceof IMul)
|
||||||
|
// {
|
||||||
|
// ctx = pops.get(0).getPushed();
|
||||||
|
// }
|
||||||
|
// else if (pops.get(1).getPushed().getInstruction() instanceof IMul)
|
||||||
|
// {
|
||||||
|
// ctx = pops.get(1).getPushed();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (ctx.getInstruction() instanceof PushConstantInstruction && pair != null)
|
||||||
|
// {
|
||||||
|
// // field = encryptedvalue
|
||||||
|
// // decrypt value by * getter
|
||||||
|
//
|
||||||
|
// PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction();
|
||||||
|
// int value = (int) pci.getConstant().getObject();
|
||||||
//
|
//
|
||||||
// if (value != 0 && value != 1)
|
// if (value != 0 && value != 1)
|
||||||
// {
|
// {
|
||||||
@@ -152,11 +155,33 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
//
|
//
|
||||||
// encryption.change(pci, value);
|
// encryption.change(pci, value);
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// }
|
// }
|
||||||
// else if (two.getPushed().getInstruction() instanceof PushConstantInstruction)
|
// if (ctx.getInstruction() instanceof ISub)
|
||||||
// {
|
// {
|
||||||
// PushConstantInstruction pci = (PushConstantInstruction) two.getPushed().getInstruction();
|
// List<StackContext> stackCtx = ctx.getPops();
|
||||||
|
//
|
||||||
|
// StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
||||||
|
//
|
||||||
|
// if (one.getPushed().getInstruction() instanceof IMul)
|
||||||
|
// {
|
||||||
|
// ctx = one.getPushed();
|
||||||
|
// }
|
||||||
|
// else if (two.getPushed().getInstruction() instanceof IMul)
|
||||||
|
// {
|
||||||
|
// ctx = two.getPushed();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (ctx.getInstruction() instanceof IMul && pair != null)
|
||||||
|
// {
|
||||||
|
// List<StackContext> stackCtx = ctx.getPops();
|
||||||
|
//
|
||||||
|
// StackContext one = stackCtx.get(0), two = stackCtx.get(1);
|
||||||
|
//
|
||||||
|
// StackContext magicStack = findMagic(one, two);
|
||||||
|
//
|
||||||
|
// if (magicStack != null)
|
||||||
|
// {
|
||||||
|
// PushConstantInstruction pci = (PushConstantInstruction) magicStack.getPushed().getInstruction();
|
||||||
// int value = (int) pci.getConstant().getObject();
|
// int value = (int) pci.getConstant().getObject();
|
||||||
//
|
//
|
||||||
// // field is encrypted with pair
|
// // field is encrypted with pair
|
||||||
@@ -169,9 +194,7 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
// encryption.change(pci, value);
|
// encryption.change(pci, value);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// else
|
// }
|
||||||
// assert false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import net.runelite.deob.Field;
|
import net.runelite.deob.Field;
|
||||||
import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction;
|
import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction;
|
||||||
import net.runelite.deob.attributes.code.instructions.SiPush;
|
|
||||||
|
|
||||||
public class Encryption
|
public class Encryption
|
||||||
{
|
{
|
||||||
@@ -19,34 +18,16 @@ public class Encryption
|
|||||||
|
|
||||||
public Pair getField(Field field)
|
public Pair getField(Field field)
|
||||||
{
|
{
|
||||||
// if (i == 0 && field.getName().equals("field1170"))
|
|
||||||
// {
|
|
||||||
// Pair p = new Pair();
|
|
||||||
// p.field = field;
|
|
||||||
// p.getter = -1570098313;
|
|
||||||
// p.setter = DMath.modInverse(p.getter);
|
|
||||||
// assert p.setter == 1237096007;
|
|
||||||
// return p;
|
|
||||||
// }
|
|
||||||
// if (i == 1 && field.getName().equals("field700"))
|
|
||||||
// {
|
|
||||||
// Pair p = new Pair();
|
|
||||||
// p.field = field;
|
|
||||||
// p.getter = -478315765;
|
|
||||||
// p.setter = DMath.modInverse(p.getter);
|
|
||||||
// //assert p.setter ==
|
|
||||||
// return p;
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
return fields.get(field);
|
return fields.get(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasChange(PushConstantInstruction pci)
|
||||||
|
{
|
||||||
|
return changes.containsKey(pci);
|
||||||
|
}
|
||||||
|
|
||||||
public void change(PushConstantInstruction pci, int value)
|
public void change(PushConstantInstruction pci, int value)
|
||||||
{
|
{
|
||||||
if (pci instanceof SiPush)
|
|
||||||
{
|
|
||||||
int i =5;
|
|
||||||
}
|
|
||||||
assert !changes.containsKey(pci) || changes.get(pci) == value;
|
assert !changes.containsKey(pci) || changes.get(pci) == value;
|
||||||
changes.put(pci, value);
|
changes.put(pci, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ package net.runelite.deob.deobfuscators.arithmetic;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import net.runelite.deob.ClassFile;
|
||||||
import net.runelite.deob.ClassGroup;
|
import net.runelite.deob.ClassGroup;
|
||||||
import net.runelite.deob.Deobfuscator;
|
import net.runelite.deob.Deobfuscator;
|
||||||
import net.runelite.deob.Field;
|
import net.runelite.deob.Field;
|
||||||
@@ -21,7 +20,6 @@ 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.StackContext;
|
import net.runelite.deob.execution.StackContext;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.apache.commons.collections4.map.MultiValueMap;
|
import org.apache.commons.collections4.map.MultiValueMap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -32,20 +30,12 @@ public class ModArith implements Deobfuscator
|
|||||||
{
|
{
|
||||||
private ClassGroup group;
|
private ClassGroup group;
|
||||||
private Execution execution;
|
private Execution execution;
|
||||||
private MultiValueMap<Field, Integer> constants = new MultiValueMap<>();
|
private MultiValueMap<Field, Integer> constantGetters = new MultiValueMap<>(),
|
||||||
//private MultiValueMap<Field, InstructionContext> fieldIns = new MultiValueMap<>();
|
constantSetters = new MultiValueMap<>();
|
||||||
|
private List<Pair> pairs = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
// private void findGetField(InstructionContext ctx)
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void findUses()
|
private void findUses()
|
||||||
{
|
{
|
||||||
//List<InstructionContext> list = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Frame f : execution.processedFrames)
|
for (Frame f : execution.processedFrames)
|
||||||
for (InstructionContext ctx : f.getInstructions())
|
for (InstructionContext ctx : f.getInstructions())
|
||||||
{
|
{
|
||||||
@@ -71,9 +61,12 @@ public class ModArith implements Deobfuscator
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Field field = gf.getMyField();
|
Field field = gf.getMyField();
|
||||||
|
if (field == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
int value = (int) pc.getConstant().getObject();
|
int value = (int) pc.getConstant().getObject();
|
||||||
|
|
||||||
constants.put(field, value);
|
constantGetters.put(field, value);
|
||||||
}
|
}
|
||||||
else if (ctx.getInstruction() instanceof SetFieldInstruction)
|
else if (ctx.getInstruction() instanceof SetFieldInstruction)
|
||||||
{
|
{
|
||||||
@@ -103,67 +96,113 @@ public class ModArith implements Deobfuscator
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Field field = sf.getMyField();
|
Field field = sf.getMyField();
|
||||||
|
if (field == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
int value2 = (int) pc.getConstant().getObject();
|
int value2 = (int) pc.getConstant().getObject();
|
||||||
|
|
||||||
constants.put(field, value2);
|
constantSetters.put(field, value2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Pair reduce(Collection<Integer> getters, Collection<Integer> setters)
|
||||||
|
{
|
||||||
|
Pair p = null;
|
||||||
|
|
||||||
|
for (Integer i : getters)
|
||||||
|
{
|
||||||
|
Integer inverse;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inverse = DMath.modInverse(i);
|
||||||
|
}
|
||||||
|
catch (ArithmeticException ex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setters.contains(inverse))
|
||||||
|
{
|
||||||
|
if (p != null && p.getter != i)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (p == null)
|
||||||
|
{
|
||||||
|
p = new Pair();
|
||||||
|
p.getter = i;
|
||||||
|
p.setter = inverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Integer i : setters)
|
||||||
|
{
|
||||||
|
Integer inverse;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inverse = DMath.modInverse(i);
|
||||||
|
}
|
||||||
|
catch (ArithmeticException ex)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getters.contains(inverse))
|
||||||
|
{
|
||||||
|
if (p != null && p.setter != i)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (p == null)
|
||||||
|
{
|
||||||
|
p = new Pair();
|
||||||
|
p.setter = i;
|
||||||
|
p.getter = inverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
private void reduce()
|
private void reduce()
|
||||||
{
|
{
|
||||||
MultiValueMap<Field, Integer> values = constants;
|
for (ClassFile cf : group.getClasses())
|
||||||
constants = new MultiValueMap<>();
|
for (Field f : cf.getFields().getFields())
|
||||||
|
|
||||||
for (Field field : values.keySet())
|
|
||||||
{
|
{
|
||||||
Collection<Integer> col = values.getCollection(field);
|
Collection<Integer> getters = constantGetters.getCollection(f),
|
||||||
|
setters = constantSetters.getCollection(f);
|
||||||
|
|
||||||
Map<Integer, Integer> map = CollectionUtils.getCardinalityMap(col);
|
if (getters == null || setters == null)
|
||||||
int max = Collections.max(map.values());
|
continue;
|
||||||
|
|
||||||
for (final Map.Entry<Integer, Integer> entry : map.entrySet()) {
|
Pair answer = reduce(getters, setters);
|
||||||
if (max == entry.getValue()) {
|
if (answer == null)
|
||||||
int constant = entry.getKey();
|
continue;
|
||||||
|
|
||||||
constants.put(field, constant);
|
answer.field = f;
|
||||||
break;
|
pairs.add(answer);
|
||||||
}
|
}
|
||||||
}
|
// MultiValueMap<Field, Integer> values = constants;
|
||||||
}
|
// constants = new MultiValueMap<>();
|
||||||
}
|
|
||||||
|
|
||||||
// public void calculate(Field field)
|
|
||||||
// {
|
|
||||||
// Collection<InstructionContext> c = fieldIns.getCollection(field);
|
|
||||||
// if (c == null)
|
|
||||||
// return;
|
|
||||||
//
|
//
|
||||||
// List<Integer> constants = new ArrayList<>();
|
// for (Field field : values.keySet())
|
||||||
// for (InstructionContext ctx : c)
|
|
||||||
// {
|
// {
|
||||||
// if (ctx.getInstruction() instanceof GetFieldInstruction)
|
// Collection<Integer> col = values.getCollection(field);
|
||||||
// {
|
|
||||||
// List<Field> fields = getFieldsInExpression(ctx, constants);
|
|
||||||
// if (fields.size() == 1)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// Map<Integer, Integer> map = CollectionUtils.getCardinalityMap(constants);
|
// Map<Integer, Integer> map = CollectionUtils.getCardinalityMap(col);
|
||||||
// int max = Collections.max(map.values());
|
// int max = Collections.max(map.values());
|
||||||
//
|
//
|
||||||
// for (final Map.Entry<Integer, Integer> entry : map.entrySet()) {
|
// for (final Map.Entry<Integer, Integer> entry : map.entrySet()) {
|
||||||
// if (max == entry.getValue()) {
|
// if (max == entry.getValue()) {
|
||||||
// int constant = entry.getKey();
|
// int constant = entry.getKey();
|
||||||
//
|
//
|
||||||
// System.out.println(constant);
|
// constants.put(field, constant);
|
||||||
// assert DMath.isInversable(constant);
|
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
private List<Field> getFieldsInExpression(InstructionContext ctx, List<Integer> constants)
|
private List<Field> getFieldsInExpression(InstructionContext ctx, List<Integer> constants)
|
||||||
{
|
{
|
||||||
@@ -234,19 +273,14 @@ public class ModArith implements Deobfuscator
|
|||||||
reduce();
|
reduce();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Field field : constants.keySet())
|
for (Pair pair : pairs)
|
||||||
{
|
{
|
||||||
System.out.println("Processing " + field.getName());
|
Field field = pair.field;
|
||||||
int getter = constants.getCollection(field).iterator().next();
|
System.out.println("Processing " + field.getName() + " getter " + pair.getter + " setter " + pair.setter);
|
||||||
|
|
||||||
if (i > 50)
|
if (i > 10) // 25
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Pair pair = new Pair();
|
|
||||||
pair.field = field;
|
|
||||||
pair.getter = getter;
|
|
||||||
pair.setter = DMath.modInverse(getter);
|
|
||||||
|
|
||||||
Encryption encr = new Encryption();
|
Encryption encr = new Encryption();
|
||||||
encr.addPair(pair);
|
encr.addPair(pair);
|
||||||
|
|
||||||
@@ -260,7 +294,7 @@ public class ModArith implements Deobfuscator
|
|||||||
}
|
}
|
||||||
|
|
||||||
Encryption encr = new Encryption();
|
Encryption encr = new Encryption();
|
||||||
System.out.println(constants);
|
System.out.println(pairs);
|
||||||
|
|
||||||
// execution = new Execution(group);
|
// execution = new Execution(group);
|
||||||
// execution.populateInitialMethods();
|
// execution.populateInitialMethods();
|
||||||
|
|||||||
Reference in New Issue
Block a user