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