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();
net.runelite.deob.Field f = getMyField();
if (f != null)
if (f != null && encryption != null)
{
Pair pair = encryption.getField(f);
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
int o = other * DMath.modInverse(one.encryption);
System.out.println(other + " -> " + o);
encryption.change(pci, o);
if (other != 1 && other != 0)
{
int o = other * DMath.modInverse(one.encryption);
System.out.println(other + " -> " + o);
encryption.change(pci, o);
}
// if (one.encryption == other)
// {
@@ -57,11 +60,14 @@ public class IMul extends Instruction
PushConstantInstruction pci = (PushConstantInstruction) one.getPushed().getInstruction();
int other = (int) pci.getConstant().getObject();
int o = other * DMath.modInverse(two.encryption);
System.out.println(other + " -> " + o);
encryption.change(pci, o);
if (other != 1 && other != 0)
{
int o = other * DMath.modInverse(two.encryption);
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();
int value = (int) pci.getConstant().getObject();
value = value * pair.getter;
encryption.change(pci, value);
if (value != 0 && value != 1)
{
value = value * pair.getter;
encryption.change(pci, value);
}
}
if (ctx.getInstruction() instanceof ISub)
{
@@ -97,9 +100,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction
// field is encrypted with pair
// divide value by setter
value = value * pair.getter;
encryption.change(pci, value);
if (value != 0 && value != 1)
{
value = value * pair.getter;
encryption.change(pci, value);
}
}
else if (two.getPushed().getInstruction() instanceof PushConstantInstruction)
@@ -110,9 +116,12 @@ public class PutStatic extends Instruction implements SetFieldInstruction
// field is encrypted with pair
// divide value by setter
value = value * pair.getter;
encryption.change(pci, value);
if (value != 0 && value != 1)
{
value = value * pair.getter;
encryption.change(pci, value);
}
}
else
assert false;

View File

@@ -10,36 +10,34 @@ public class Encryption
{
private Map<Field, Pair> fields = 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)
{
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);
// 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 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.InvokeInstruction;
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.Frame;
import net.runelite.deob.execution.InstructionContext;
@@ -30,12 +32,15 @@ public class ModArith implements Deobfuscator
{
private ClassGroup group;
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()
{
@@ -44,65 +49,122 @@ public class ModArith implements Deobfuscator
for (Frame f : execution.processedFrames)
for (InstructionContext ctx : f.getInstructions())
{
Instruction i = ctx.getInstruction();
if (!(i instanceof FieldInstruction))
continue;
FieldInstruction fi = (FieldInstruction) i;
Field fifield = fi.getMyField();
if (fifield == null)
continue;
fieldIns.put(fifield, ctx);
// if (i instanceof GetFieldInstruction)
// {
// findGetField(ctx);
// }
if (ctx.getInstruction() instanceof IMul)
{
Instruction one = ctx.getPops().get(0).getPushed().getInstruction();
Instruction two = ctx.getPops().get(1).getPushed().getInstruction();
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;
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);
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;
}
}
}
// 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)
{
return check(ctx, new HashSet<InstructionContext>(), constants);
@@ -166,24 +228,60 @@ public class ModArith implements Deobfuscator
execution = new Execution(group);
execution.populateInitialMethods();
Encryption encr = new Encryption(0);
execution.setEncryption(encr);
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);
execution.populateInitialMethods();
Encryption encr = new Encryption();
System.out.println(constants);
encr = new Encryption(1);
execution.setEncryption(encr);
execution.run();
encr.doChange();
// 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();
//