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
if (other != 1 && other != 0)
{
int o = other * DMath.modInverse(one.encryption); int o = other * DMath.modInverse(one.encryption);
System.out.println(other + " -> " + o); System.out.println(other + " -> " + o);
encryption.change(pci, o); encryption.change(pci, o);
}
// if (one.encryption == other) // if (one.encryption == other)
// { // {
@@ -57,6 +60,8 @@ 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();
if (other != 1 && other != 0)
{
int o = other * DMath.modInverse(two.encryption); int o = other * DMath.modInverse(two.encryption);
System.out.println(other + " -> " + o); System.out.println(other + " -> " + o);
@@ -64,6 +69,7 @@ public class IMul extends Instruction
encryption.change(pci, o); encryption.change(pci, o);
} }
} }
}
StackContext ctx = new StackContext(ins, int.class); StackContext ctx = new StackContext(ins, int.class);
stack.push(ctx); stack.push(ctx);

View File

@@ -64,10 +64,13 @@ 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();
if (value != 0 && value != 1)
{
value = value * pair.getter; value = value * pair.getter;
encryption.change(pci, value); encryption.change(pci, value);
} }
}
if (ctx.getInstruction() instanceof ISub) if (ctx.getInstruction() instanceof ISub)
{ {
List<StackContext> stackCtx = ctx.getPops(); List<StackContext> stackCtx = ctx.getPops();
@@ -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
if (value != 0 && value != 1)
{
value = value * pair.getter; value = value * pair.getter;
encryption.change(pci, value); encryption.change(pci, value);
}
} }
else if (two.getPushed().getInstruction() instanceof PushConstantInstruction) else if (two.getPushed().getInstruction() instanceof PushConstantInstruction)
@@ -110,10 +116,13 @@ 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
if (value != 0 && value != 1)
{
value = value * pair.getter; value = value * pair.getter;
encryption.change(pci, value); 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,64 +49,121 @@ 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)
{
Instruction one = ctx.getPops().get(0).getPushed().getInstruction();
Instruction two = ctx.getPops().get(1).getPushed().getInstruction();
if (!(i instanceof FieldInstruction)) PushConstantInstruction pc = null;
GetFieldInstruction gf = null;
if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction)
{
pc = (PushConstantInstruction) one;
gf = (GetFieldInstruction) two;
}
else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction)
{
pc = (PushConstantInstruction) two;
gf = (GetFieldInstruction) one;
}
if (pc == null)
continue; continue;
FieldInstruction fi = (FieldInstruction) i; Field field = gf.getMyField();
int value = (int) pc.getConstant().getObject();
Field fifield = fi.getMyField(); constants.put(field, value);
}
else if (ctx.getInstruction() instanceof SetFieldInstruction)
{
SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction();
if (fifield == null) StackContext value = ctx.getPops().get(0); // what setfield pops as value
if (!(value.getPushed().getInstruction() instanceof IMul))
continue; continue;
fieldIns.put(fifield, ctx); Instruction one = value.getPushed().getPops().get(0).getPushed().getInstruction();
// if (i instanceof GetFieldInstruction) Instruction two = value.getPushed().getPops().get(1).getPushed().getInstruction();
// {
// findGetField(ctx); 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;
} }
//return list; if (pc == null)
// for (ClassFile cf : group.getClasses()) continue;
// for (Field f : cf.getFields().getFields())
// {
//
// }
}
public void calculate(Field field) Field field = sf.getMyField();
{ int value2 = (int) pc.getConstant().getObject();
Collection<InstructionContext> c = fieldIns.getCollection(field);
if (c == null)
return;
List<Integer> constants = new ArrayList<>(); constants.put(field, value2);
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); 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()); 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;
} }
} }
} }
}
// 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)
{ {
@@ -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 = new Execution(group);
execution.populateInitialMethods(); execution.populateInitialMethods();
encr = new Encryption(1);
execution.setEncryption(encr); execution.setEncryption(encr);
execution.run(); execution.run();
encr.doChange(); encr.doChange();
System.out.println("Changed" + ++i);
}
Encryption encr = new Encryption();
System.out.println(constants);
// execution = new Execution(group);
// execution.populateInitialMethods();
//
// Encryption encr = new Encryption(0);
// execution.setEncryption(encr);
//
// execution.run();
//
// encr.doChange();
//
//
// execution = new Execution(group);
// execution.populateInitialMethods();
//
// encr = new Encryption(1);
// execution.setEncryption(encr);
//
// execution.run();
//
// encr.doChange();
// findUses(); // findUses();
// //