class172/field2976 passed to invoke is not simplified
This commit is contained in:
@@ -9,6 +9,7 @@ import java.io.DataOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import net.runelite.deob.pool.NameAndType;
|
||||||
|
|
||||||
public class Field
|
public class Field
|
||||||
{
|
{
|
||||||
@@ -41,6 +42,15 @@ public class Field
|
|||||||
attributes = new Attributes(this, is);
|
attributes = new Attributes(this, is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Field(Fields fields, String name, Type type)
|
||||||
|
{
|
||||||
|
this.fields = fields;
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
|
attributes = new Attributes(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void write(DataOutputStream out) throws IOException
|
public void write(DataOutputStream out) throws IOException
|
||||||
{
|
{
|
||||||
ConstantPool pool = fields.getClassFile().getPool();
|
ConstantPool pool = fields.getClassFile().getPool();
|
||||||
@@ -70,6 +80,11 @@ public class Field
|
|||||||
{
|
{
|
||||||
return (accessFlags & ACC_STATIC) != 0;
|
return (accessFlags & ACC_STATIC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStatic()
|
||||||
|
{
|
||||||
|
accessFlags |= ACC_STATIC;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
@@ -95,6 +110,14 @@ public class Field
|
|||||||
{
|
{
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public net.runelite.deob.pool.Field getPoolField()
|
||||||
|
{
|
||||||
|
return new net.runelite.deob.pool.Field(
|
||||||
|
new net.runelite.deob.pool.Class(this.getFields().getClassFile().getName()),
|
||||||
|
new NameAndType(this.getName(), this.getType())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class Fields
|
|||||||
{
|
{
|
||||||
return classFile;
|
return classFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addField(Field field)
|
||||||
|
{
|
||||||
|
fields.add(field);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Field> getFields()
|
public List<Field> getFields()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -145,5 +145,13 @@ public class Method
|
|||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public net.runelite.deob.pool.Method getPoolMethod()
|
||||||
|
{
|
||||||
|
return new net.runelite.deob.pool.Method(
|
||||||
|
new net.runelite.deob.pool.Class(this.getMethods().getClassFile().getName()),
|
||||||
|
new NameAndType(this.getName(), this.getDescriptor())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public class Attributes
|
|||||||
|
|
||||||
load(is);
|
load(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Attributes(Field f)
|
||||||
|
{
|
||||||
|
field = f;
|
||||||
|
}
|
||||||
|
|
||||||
public Attributes(Method m)
|
public Attributes(Method m)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ public class GetStatic extends Instruction implements GetFieldInstruction
|
|||||||
super(instructions, type, pc);
|
super(instructions, type, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GetStatic(Instructions instructions, Field field)
|
||||||
|
{
|
||||||
|
super(instructions, InstructionType.GETSTATIC, -1);
|
||||||
|
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(DataInputStream is) throws IOException
|
public void load(DataInputStream is) throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
super(instructions, type, pc);
|
super(instructions, type, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InvokeStatic(Instructions instructions, Method method)
|
||||||
|
{
|
||||||
|
super(instructions, InstructionType.INVOKESTATIC, -1);
|
||||||
|
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(DataInputStream is) throws IOException
|
public void load(DataInputStream is) throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ public class DMath
|
|||||||
|
|
||||||
public static boolean isBig(int val)
|
public static boolean isBig(int val)
|
||||||
{
|
{
|
||||||
return (val & 0xFFF00000) != 0;
|
if ((val & 0x80000000) != 0)
|
||||||
|
val = ~val + 1;
|
||||||
|
|
||||||
|
return (val & 0x7FF00000) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,76 @@ public class ModArith implements Deobfuscator
|
|||||||
private List<Pair> pairs = new ArrayList<>();
|
private List<Pair> pairs = new ArrayList<>();
|
||||||
private Set<Field> deobfuscatedFields = new HashSet<>();
|
private Set<Field> deobfuscatedFields = new HashSet<>();
|
||||||
|
|
||||||
|
private List<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set)
|
||||||
|
{
|
||||||
|
List<InstructionContext> l = new ArrayList<>();
|
||||||
|
|
||||||
|
if (ctx == null || set.contains(ctx.getInstruction()))
|
||||||
|
return l;
|
||||||
|
|
||||||
|
set.add(ctx.getInstruction());
|
||||||
|
|
||||||
|
l.add(ctx);
|
||||||
|
|
||||||
|
for (StackContext s : ctx.getPops())
|
||||||
|
l.addAll(getInsInExpr(s.getPushed(), set));
|
||||||
|
for (StackContext s : ctx.getPushes())
|
||||||
|
for (InstructionContext i : s.getPopped())
|
||||||
|
l.addAll(getInsInExpr(i, set));
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFieldObfuscated(Execution e, Field field)
|
||||||
|
{
|
||||||
|
// field isn't obfuscated if there are no usages with big constants and no other fields
|
||||||
|
|
||||||
|
for (Frame f : execution.processedFrames)
|
||||||
|
outer:
|
||||||
|
for (InstructionContext ctx : f.getInstructions())
|
||||||
|
{
|
||||||
|
if (!(ctx.getInstruction() instanceof FieldInstruction))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FieldInstruction fi = (FieldInstruction) ctx.getInstruction();
|
||||||
|
|
||||||
|
if (fi.getMyField() != field)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
List<InstructionContext> ins = getInsInExpr(ctx, new HashSet());
|
||||||
|
|
||||||
|
// continue if expr contains another ins
|
||||||
|
for (InstructionContext i : ins)
|
||||||
|
{
|
||||||
|
if (i.getInstruction() instanceof FieldInstruction)
|
||||||
|
{
|
||||||
|
FieldInstruction ifi = (FieldInstruction) i.getInstruction();
|
||||||
|
|
||||||
|
if (ifi.getMyField() != field)
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find big constant
|
||||||
|
for (InstructionContext i : ins)
|
||||||
|
{
|
||||||
|
if (i.getInstruction() instanceof LDC_W)
|
||||||
|
{
|
||||||
|
LDC_W ldc = (LDC_W) i.getInstruction();
|
||||||
|
if (ldc.getConstant().getObject() instanceof Integer)
|
||||||
|
{
|
||||||
|
int value = ldc.getConstantAsInt();
|
||||||
|
|
||||||
|
if (DMath.isBig(value))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private List<Integer> findAssocConstants(Field field, InstructionContext ctx) throws OtherFieldException
|
private List<Integer> findAssocConstants(Field field, InstructionContext ctx) throws OtherFieldException
|
||||||
{
|
{
|
||||||
// starts with ctx = setfield
|
// starts with ctx = setfield
|
||||||
@@ -97,11 +167,6 @@ public class ModArith implements Deobfuscator
|
|||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (field.getName().equals("field2201"))
|
|
||||||
{
|
|
||||||
int k=7;
|
|
||||||
}
|
|
||||||
|
|
||||||
int value = (int) pc.getConstant().getObject();
|
int value = (int) pc.getConstant().getObject();
|
||||||
|
|
||||||
if (value == 1 || value == 0)
|
if (value == 1 || value == 0)
|
||||||
@@ -302,7 +367,7 @@ public class ModArith implements Deobfuscator
|
|||||||
Collection<Integer> getters = constantGetters.getCollection(f),
|
Collection<Integer> getters = constantGetters.getCollection(f),
|
||||||
setters = constantSetters.getCollection(f);
|
setters = constantSetters.getCollection(f);
|
||||||
|
|
||||||
if (f.getName().equals("field551"))
|
if (f.getName().equals("field2976"))
|
||||||
{
|
{
|
||||||
int k=5;
|
int k=5;
|
||||||
}
|
}
|
||||||
@@ -322,6 +387,12 @@ public class ModArith implements Deobfuscator
|
|||||||
if (answer == null)
|
if (answer == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!this.isFieldObfuscated(execution, f))
|
||||||
|
{
|
||||||
|
System.out.println("Skipping field " + f.getName() + " which isnt obfuscated");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
answer.field = f;
|
answer.field = f;
|
||||||
pairs.add(answer);
|
pairs.add(answer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package net.runelite.deob;
|
|||||||
|
|
||||||
import net.runelite.deob.attributes.Attributes;
|
import net.runelite.deob.attributes.Attributes;
|
||||||
import net.runelite.deob.attributes.Code;
|
import net.runelite.deob.attributes.Code;
|
||||||
|
import net.runelite.deob.attributes.code.Instructions;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.VReturn;
|
||||||
import net.runelite.deob.signature.Signature;
|
import net.runelite.deob.signature.Signature;
|
||||||
|
import net.runelite.deob.signature.Type;
|
||||||
|
|
||||||
public class ClassGroupFactory
|
public class ClassGroupFactory
|
||||||
{
|
{
|
||||||
@@ -15,6 +18,11 @@ public class ClassGroupFactory
|
|||||||
cf.setSuperName("java/lang/Object");
|
cf.setSuperName("java/lang/Object");
|
||||||
group.addClass(cf);
|
group.addClass(cf);
|
||||||
|
|
||||||
|
Fields fields = cf.getFields();
|
||||||
|
Field field = new Field(fields, "field", new Type("I"));
|
||||||
|
field.setStatic();
|
||||||
|
fields.addField(field);
|
||||||
|
|
||||||
Methods methods = cf.getMethods();
|
Methods methods = cf.getMethods();
|
||||||
Method method = new Method(methods, "func", new Signature("()V"));
|
Method method = new Method(methods, "func", new Signature("()V"));
|
||||||
method.setStatic();
|
method.setStatic();
|
||||||
@@ -25,6 +33,18 @@ public class ClassGroupFactory
|
|||||||
Code code = new Code(methodAttributes);
|
Code code = new Code(methodAttributes);
|
||||||
methodAttributes.addAttribute(code);
|
methodAttributes.addAttribute(code);
|
||||||
|
|
||||||
|
method = new Method(methods, "func2", new Signature("(III)V"));
|
||||||
|
method.setStatic();
|
||||||
|
methods.addMethod(method);
|
||||||
|
|
||||||
|
methodAttributes = method.getAttributes();
|
||||||
|
|
||||||
|
code = new Code(methodAttributes);
|
||||||
|
methodAttributes.addAttribute(code);
|
||||||
|
|
||||||
|
Instructions ins = code.getInstructions();
|
||||||
|
ins.addInstruction(new VReturn(ins));
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ import java.util.Collection;
|
|||||||
import net.runelite.deob.ClassGroup;
|
import net.runelite.deob.ClassGroup;
|
||||||
import net.runelite.deob.ClassGroupFactory;
|
import net.runelite.deob.ClassGroupFactory;
|
||||||
import net.runelite.deob.Deobfuscator;
|
import net.runelite.deob.Deobfuscator;
|
||||||
|
import net.runelite.deob.Field;
|
||||||
import net.runelite.deob.attributes.Code;
|
import net.runelite.deob.attributes.Code;
|
||||||
import net.runelite.deob.attributes.code.Instruction;
|
import net.runelite.deob.attributes.code.Instruction;
|
||||||
import net.runelite.deob.attributes.code.Instructions;
|
import net.runelite.deob.attributes.code.Instructions;
|
||||||
import net.runelite.deob.attributes.code.instructions.Dup_X1;
|
import net.runelite.deob.attributes.code.instructions.Dup_X1;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.GetStatic;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.Goto;
|
||||||
import net.runelite.deob.attributes.code.instructions.IAdd;
|
import net.runelite.deob.attributes.code.instructions.IAdd;
|
||||||
import net.runelite.deob.attributes.code.instructions.IConst_0;
|
import net.runelite.deob.attributes.code.instructions.IConst_0;
|
||||||
import net.runelite.deob.attributes.code.instructions.IConst_1;
|
import net.runelite.deob.attributes.code.instructions.IConst_1;
|
||||||
@@ -20,6 +23,7 @@ import net.runelite.deob.attributes.code.instructions.IMul;
|
|||||||
import net.runelite.deob.attributes.code.instructions.IStore;
|
import net.runelite.deob.attributes.code.instructions.IStore;
|
||||||
import net.runelite.deob.attributes.code.instructions.IStore_0;
|
import net.runelite.deob.attributes.code.instructions.IStore_0;
|
||||||
import net.runelite.deob.attributes.code.instructions.If0;
|
import net.runelite.deob.attributes.code.instructions.If0;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.deob.attributes.code.instructions.LDC_W;
|
import net.runelite.deob.attributes.code.instructions.LDC_W;
|
||||||
import net.runelite.deob.attributes.code.instructions.NOP;
|
import net.runelite.deob.attributes.code.instructions.NOP;
|
||||||
import net.runelite.deob.attributes.code.instructions.Pop;
|
import net.runelite.deob.attributes.code.instructions.Pop;
|
||||||
@@ -43,7 +47,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
// imul
|
// imul
|
||||||
// putstatic class29/field949 I
|
// putstatic class29/field949 I
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_1()
|
public void test1()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -113,7 +117,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
// ldc 561453169
|
// ldc 561453169
|
||||||
// imul
|
// imul
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_2()
|
public void test2()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -172,7 +176,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_3()
|
public void test3()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -244,7 +248,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_4()
|
public void test4()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -301,7 +305,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_5()
|
public void test5()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -361,7 +365,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_6()
|
public void test6()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -413,7 +417,7 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDupX1_7()
|
public void test7()
|
||||||
{
|
{
|
||||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
Code code = group.findClass("test").findMethod("func").getCode();
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
@@ -461,4 +465,73 @@ public class MultiplicationDeobfuscatorTest
|
|||||||
Assert.assertEquals(-1, constant2.getConstantAsInt());
|
Assert.assertEquals(-1, constant2.getConstantAsInt());
|
||||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test8()
|
||||||
|
{
|
||||||
|
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||||
|
Code code = group.findClass("test").findMethod("func").getCode();
|
||||||
|
Code code2 = group.findClass("test").findMethod("func2").getCode();
|
||||||
|
Field field = group.findClass("test").findField("field");
|
||||||
|
Instructions ins = code.getInstructions();
|
||||||
|
|
||||||
|
code.setMaxStack(2);
|
||||||
|
|
||||||
|
Instruction[] prepareVariables = {
|
||||||
|
new IConst_3(ins),
|
||||||
|
new IStore_0(ins)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Instruction i : prepareVariables)
|
||||||
|
ins.addInstruction(i);
|
||||||
|
|
||||||
|
LDC_W constant1 = new LDC_W(ins, -1616202347),
|
||||||
|
constant2 = new LDC_W(ins, 2747837);
|
||||||
|
|
||||||
|
NOP label1 = new NOP(ins),
|
||||||
|
label2 = new NOP(ins),
|
||||||
|
label3 = new NOP(ins);
|
||||||
|
|
||||||
|
Instruction body[] = {
|
||||||
|
new GetStatic(ins, field.getPoolField()),
|
||||||
|
constant1,
|
||||||
|
new IMul(ins),
|
||||||
|
constant2,
|
||||||
|
new IMul(ins),
|
||||||
|
|
||||||
|
new ILoad(ins, 0),
|
||||||
|
|
||||||
|
new LDC_W(ins, 42),
|
||||||
|
new If0(ins, label1),
|
||||||
|
new Goto(ins, label2),
|
||||||
|
|
||||||
|
label1,
|
||||||
|
new IConst_M1(ins),
|
||||||
|
new Goto(ins, label3),
|
||||||
|
|
||||||
|
label2,
|
||||||
|
new IConst_0(ins),
|
||||||
|
new Goto(ins, label3),
|
||||||
|
|
||||||
|
label3,
|
||||||
|
new InvokeStatic(ins, group.findClass("test").findMethod("func2").getPoolMethod()),
|
||||||
|
|
||||||
|
new VReturn(ins)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (Instruction i : body)
|
||||||
|
ins.addInstruction(i);
|
||||||
|
|
||||||
|
Execution e = new Execution(group);
|
||||||
|
e.populateInitialMethods();
|
||||||
|
e.run();
|
||||||
|
|
||||||
|
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||||
|
|
||||||
|
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||||
|
d.run(group);
|
||||||
|
|
||||||
|
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||||
|
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user