Some detecting getters, not totally right. Cap at 5.
This commit is contained in:
@@ -50,7 +50,7 @@ public class GetStatic extends Instruction implements GetFieldInstruction
|
|||||||
|
|
||||||
Encryption encryption = frame.getExecution().getEncryption();
|
Encryption encryption = frame.getExecution().getEncryption();
|
||||||
net.runelite.deob.Field f = getMyField();
|
net.runelite.deob.Field f = getMyField();
|
||||||
if (f != null)
|
if (f != null && encryption != null)
|
||||||
{
|
{
|
||||||
Pair pair = encryption.getField(f);
|
Pair pair = encryption.getField(f);
|
||||||
if (pair != null)
|
if (pair != null)
|
||||||
|
|||||||
@@ -41,11 +41,14 @@ public class IMul extends Instruction
|
|||||||
|
|
||||||
// 'one' is encrypted and we want to decrypt it by dividing by one.encryption
|
// 'one' is encrypted and we want to decrypt it by dividing by one.encryption
|
||||||
|
|
||||||
int o = other * DMath.modInverse(one.encryption);
|
if (other != 1 && other != 0)
|
||||||
|
{
|
||||||
System.out.println(other + " -> " + o);
|
int o = other * DMath.modInverse(one.encryption);
|
||||||
|
|
||||||
encryption.change(pci, o);
|
System.out.println(other + " -> " + o);
|
||||||
|
|
||||||
|
encryption.change(pci, o);
|
||||||
|
}
|
||||||
|
|
||||||
// if (one.encryption == other)
|
// if (one.encryption == other)
|
||||||
// {
|
// {
|
||||||
@@ -57,11 +60,14 @@ public class IMul extends Instruction
|
|||||||
PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction();
|
PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction();
|
||||||
int other = (int) pci.getConstant().getObject();
|
int other = (int) pci.getConstant().getObject();
|
||||||
|
|
||||||
int o = other * DMath.modInverse(two.encryption);
|
if (other != 1 && other != 0)
|
||||||
|
{
|
||||||
System.out.println(other + " -> " + o);
|
int o = other * DMath.modInverse(two.encryption);
|
||||||
|
|
||||||
encryption.change(pci, o);
|
System.out.println(other + " -> " + o);
|
||||||
|
|
||||||
|
encryption.change(pci, o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,9 +64,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction();
|
PushConstantInstruction pci = (PushConstantInstruction) ctx.getInstruction();
|
||||||
int value = (int) pci.getConstant().getObject();
|
int value = (int) pci.getConstant().getObject();
|
||||||
|
|
||||||
value = value * pair.getter;
|
if (value != 0 && value != 1)
|
||||||
|
{
|
||||||
encryption.change(pci, value);
|
value = value * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ctx.getInstruction() instanceof ISub)
|
if (ctx.getInstruction() instanceof ISub)
|
||||||
{
|
{
|
||||||
@@ -97,9 +100,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
// field is encrypted with pair
|
// field is encrypted with pair
|
||||||
// divide value by setter
|
// divide value by setter
|
||||||
|
|
||||||
value = value * pair.getter;
|
if (value != 0 && value != 1)
|
||||||
|
{
|
||||||
encryption.change(pci, value);
|
value = value * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (two.getPushed().getInstruction() instanceof PushConstantInstruction)
|
else if (two.getPushed().getInstruction() instanceof PushConstantInstruction)
|
||||||
@@ -110,9 +116,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction
|
|||||||
// field is encrypted with pair
|
// field is encrypted with pair
|
||||||
// divide value by setter
|
// divide value by setter
|
||||||
|
|
||||||
value = value * pair.getter;
|
if (value != 0 && value != 1)
|
||||||
|
{
|
||||||
encryption.change(pci, value);
|
value = value * pair.getter;
|
||||||
|
|
||||||
|
encryption.change(pci, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert false;
|
assert false;
|
||||||
|
|||||||
@@ -10,36 +10,34 @@ public class Encryption
|
|||||||
{
|
{
|
||||||
private Map<Field, Pair> fields = new HashMap<>();
|
private Map<Field, Pair> fields = new HashMap<>();
|
||||||
private Map<PushConstantInstruction, Integer> changes = new HashMap<>();
|
private Map<PushConstantInstruction, Integer> changes = new HashMap<>();
|
||||||
int i;
|
|
||||||
private Pair p;
|
|
||||||
|
|
||||||
public Encryption(int i)
|
public void addPair(Pair pair)
|
||||||
{
|
{
|
||||||
this.i = i;
|
fields.put(pair.field, pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair getField(Field field)
|
public Pair getField(Field field)
|
||||||
{
|
{
|
||||||
if (i == 0 && field.getName().equals("field1170"))
|
// if (i == 0 && field.getName().equals("field1170"))
|
||||||
{
|
// {
|
||||||
Pair p = new Pair();
|
// Pair p = new Pair();
|
||||||
p.field = field;
|
// p.field = field;
|
||||||
p.getter = -1570098313;
|
// p.getter = -1570098313;
|
||||||
p.setter = DMath.modInverse(p.getter);
|
// p.setter = DMath.modInverse(p.getter);
|
||||||
assert p.setter == 1237096007;
|
// assert p.setter == 1237096007;
|
||||||
return p;
|
// return p;
|
||||||
}
|
// }
|
||||||
if (i == 1 && field.getName().equals("field700"))
|
// if (i == 1 && field.getName().equals("field700"))
|
||||||
{
|
// {
|
||||||
Pair p = new Pair();
|
// Pair p = new Pair();
|
||||||
p.field = field;
|
// p.field = field;
|
||||||
p.getter = -478315765;
|
// p.getter = -478315765;
|
||||||
p.setter = DMath.modInverse(p.getter);
|
// p.setter = DMath.modInverse(p.getter);
|
||||||
//assert p.setter ==
|
// //assert p.setter ==
|
||||||
return p;
|
// return p;
|
||||||
}
|
// }
|
||||||
return null;
|
// return null;
|
||||||
//return fields.get(field);
|
return fields.get(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void change(PushConstantInstruction pci, int value)
|
public void change(PushConstantInstruction pci, int value)
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import net.runelite.deob.attributes.code.instruction.types.FieldInstruction;
|
|||||||
import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction;
|
import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction;
|
||||||
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
|
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.instructions.IMul;
|
||||||
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;
|
||||||
@@ -30,12 +32,15 @@ public class ModArith implements Deobfuscator
|
|||||||
{
|
{
|
||||||
private ClassGroup group;
|
private ClassGroup group;
|
||||||
private Execution execution;
|
private Execution execution;
|
||||||
private MultiValueMap<Field, InstructionContext> fieldIns = new MultiValueMap<>();
|
private MultiValueMap<Field, Integer> constants = new MultiValueMap<>();
|
||||||
|
//private MultiValueMap<Field, InstructionContext> fieldIns = new MultiValueMap<>();
|
||||||
|
|
||||||
private void findGetField(InstructionContext ctx)
|
|
||||||
{
|
|
||||||
|
// private void findGetField(InstructionContext ctx)
|
||||||
}
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
private void findUses()
|
private void findUses()
|
||||||
{
|
{
|
||||||
@@ -44,65 +49,122 @@ public class ModArith implements Deobfuscator
|
|||||||
for (Frame f : execution.processedFrames)
|
for (Frame f : execution.processedFrames)
|
||||||
for (InstructionContext ctx : f.getInstructions())
|
for (InstructionContext ctx : f.getInstructions())
|
||||||
{
|
{
|
||||||
Instruction i = ctx.getInstruction();
|
if (ctx.getInstruction() instanceof IMul)
|
||||||
|
{
|
||||||
if (!(i instanceof FieldInstruction))
|
Instruction one = ctx.getPops().get(0).getPushed().getInstruction();
|
||||||
continue;
|
Instruction two = ctx.getPops().get(1).getPushed().getInstruction();
|
||||||
|
|
||||||
FieldInstruction fi = (FieldInstruction) i;
|
PushConstantInstruction pc = null;
|
||||||
|
GetFieldInstruction gf = null;
|
||||||
Field fifield = fi.getMyField();
|
if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction)
|
||||||
|
{
|
||||||
if (fifield == null)
|
pc = (PushConstantInstruction) one;
|
||||||
continue;
|
gf = (GetFieldInstruction) two;
|
||||||
|
}
|
||||||
fieldIns.put(fifield, ctx);
|
else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction)
|
||||||
// if (i instanceof GetFieldInstruction)
|
{
|
||||||
// {
|
pc = (PushConstantInstruction) two;
|
||||||
// findGetField(ctx);
|
gf = (GetFieldInstruction) one;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
if (pc == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Field field = gf.getMyField();
|
||||||
|
int value = (int) pc.getConstant().getObject();
|
||||||
|
|
||||||
|
constants.put(field, value);
|
||||||
|
}
|
||||||
|
else if (ctx.getInstruction() instanceof SetFieldInstruction)
|
||||||
|
{
|
||||||
|
SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction();
|
||||||
|
|
||||||
|
StackContext value = ctx.getPops().get(0); // what setfield pops as value
|
||||||
|
if (!(value.getPushed().getInstruction() instanceof IMul))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Instruction one = value.getPushed().getPops().get(0).getPushed().getInstruction();
|
||||||
|
Instruction two = value.getPushed().getPops().get(1).getPushed().getInstruction();
|
||||||
|
|
||||||
|
PushConstantInstruction pc = null;
|
||||||
|
Instruction other = null;
|
||||||
|
if (one instanceof PushConstantInstruction)
|
||||||
|
{
|
||||||
|
pc = (PushConstantInstruction) one;
|
||||||
|
other = two;
|
||||||
|
}
|
||||||
|
else if (two instanceof PushConstantInstruction)
|
||||||
|
{
|
||||||
|
pc = (PushConstantInstruction) two;
|
||||||
|
other = one;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Field field = sf.getMyField();
|
||||||
|
int value2 = (int) pc.getConstant().getObject();
|
||||||
|
|
||||||
|
constants.put(field, value2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//return list;
|
|
||||||
// for (ClassFile cf : group.getClasses())
|
|
||||||
// for (Field f : cf.getFields().getFields())
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calculate(Field field)
|
private void reduce()
|
||||||
{
|
{
|
||||||
Collection<InstructionContext> c = fieldIns.getCollection(field);
|
MultiValueMap<Field, Integer> values = constants;
|
||||||
if (c == null)
|
constants = new MultiValueMap<>();
|
||||||
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);
|
Map<Integer, Integer> map = CollectionUtils.getCardinalityMap(col);
|
||||||
if (fields.size() == 1)
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void calculate(Field field)
|
||||||
|
// {
|
||||||
|
// Collection<InstructionContext> c = fieldIns.getCollection(field);
|
||||||
|
// if (c == null)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// List<Integer> constants = new ArrayList<>();
|
||||||
|
// for (InstructionContext ctx : c)
|
||||||
|
// {
|
||||||
|
// if (ctx.getInstruction() instanceof GetFieldInstruction)
|
||||||
|
// {
|
||||||
|
// List<Field> fields = getFieldsInExpression(ctx, constants);
|
||||||
|
// if (fields.size() == 1)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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)
|
private List<Field> getFieldsInExpression(InstructionContext ctx, List<Integer> constants)
|
||||||
{
|
{
|
||||||
return check(ctx, new HashSet<InstructionContext>(), constants);
|
return check(ctx, new HashSet<InstructionContext>(), constants);
|
||||||
@@ -166,24 +228,60 @@ public class ModArith implements Deobfuscator
|
|||||||
|
|
||||||
execution = new Execution(group);
|
execution = new Execution(group);
|
||||||
execution.populateInitialMethods();
|
execution.populateInitialMethods();
|
||||||
|
|
||||||
Encryption encr = new Encryption(0);
|
|
||||||
execution.setEncryption(encr);
|
|
||||||
|
|
||||||
execution.run();
|
execution.run();
|
||||||
|
|
||||||
encr.doChange();
|
findUses();
|
||||||
|
reduce();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (Field field : constants.keySet())
|
||||||
|
{
|
||||||
|
System.out.println("Processing " + field.getName());
|
||||||
|
int getter = constants.getCollection(field).iterator().next();
|
||||||
|
|
||||||
|
if (i > 5)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Pair pair = new Pair();
|
||||||
|
pair.field = field;
|
||||||
|
pair.getter = getter;
|
||||||
|
pair.setter = DMath.modInverse(getter);
|
||||||
|
|
||||||
|
Encryption encr = new Encryption();
|
||||||
|
encr.addPair(pair);
|
||||||
|
|
||||||
|
execution = new Execution(group);
|
||||||
|
execution.populateInitialMethods();
|
||||||
|
execution.setEncryption(encr);
|
||||||
|
execution.run();
|
||||||
|
|
||||||
|
encr.doChange();
|
||||||
|
System.out.println("Changed" + ++i);
|
||||||
|
}
|
||||||
|
|
||||||
execution = new Execution(group);
|
Encryption encr = new Encryption();
|
||||||
execution.populateInitialMethods();
|
System.out.println(constants);
|
||||||
|
|
||||||
encr = new Encryption(1);
|
// execution = new Execution(group);
|
||||||
execution.setEncryption(encr);
|
// execution.populateInitialMethods();
|
||||||
|
//
|
||||||
execution.run();
|
// Encryption encr = new Encryption(0);
|
||||||
|
// execution.setEncryption(encr);
|
||||||
encr.doChange();
|
//
|
||||||
|
// execution.run();
|
||||||
|
//
|
||||||
|
// encr.doChange();
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// execution = new Execution(group);
|
||||||
|
// execution.populateInitialMethods();
|
||||||
|
//
|
||||||
|
// encr = new Encryption(1);
|
||||||
|
// execution.setEncryption(encr);
|
||||||
|
//
|
||||||
|
// execution.run();
|
||||||
|
//
|
||||||
|
// encr.doChange();
|
||||||
|
|
||||||
// findUses();
|
// findUses();
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user