Some detecting getters, not totally right. Cap at 5.

This commit is contained in:
Adam
2015-08-24 18:27:13 -04:00
parent 4143a59d9d
commit 1fd79174ea
5 changed files with 221 additions and 110 deletions

View File

@@ -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)

View File

@@ -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);
}
} }
} }

View File

@@ -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;

View File

@@ -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)

View File

@@ -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();
// //