use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class ModArith method insertGetterSetterMuls.
private void insertGetterSetterMuls(Encryption encr) {
// before setfield insert imul * getter
for (ClassFile cf : group.getClasses()) {
for (Method m : cf.getMethods()) {
Code code = m.getCode();
if (code == null) {
continue;
}
Instructions ins = code.getInstructions();
List<Instruction> ilist = ins.getInstructions();
for (int i = 0; i < ilist.size(); ++i) {
Instruction in = ilist.get(i);
if (in instanceof SetFieldInstruction) {
SetFieldInstruction sfi = (SetFieldInstruction) in;
Field f = sfi.getMyField();
if (f == null) {
continue;
}
Pair p = encr.getField(f.getPoolField());
if (p == null) {
continue;
}
// insert imul
if (p.getType() == Integer.class) {
ilist.add(i++, new LDC(ins, (int) p.getter));
ilist.add(i++, new IMul(ins));
} else if (p.getType() == Long.class) {
ilist.add(i++, new LDC(ins, (long) p.getter));
ilist.add(i++, new LMul(ins));
} else {
throw new IllegalStateException();
}
} else if (in instanceof GetFieldInstruction) {
GetFieldInstruction sfi = (GetFieldInstruction) in;
Field f = sfi.getMyField();
if (f == null) {
continue;
}
Pair p = encr.getField(f.getPoolField());
if (p == null) {
continue;
}
// imul
if (p.getType() == Integer.class) {
ilist.add(++i, new LDC(ins, (int) p.setter));
ilist.add(++i, new IMul(ins));
} else if (p.getType() == Long.class) {
ilist.add(++i, new LDC(ins, (long) p.setter));
ilist.add(++i, new LMul(ins));
} else {
throw new IllegalStateException();
}
}
}
}
}
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class ModArith method getInsInExpr.
private static List<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set, boolean imul) {
List<InstructionContext> l = new ArrayList<>();
if (ctx == null || set.contains(ctx.getInstruction())) {
return l;
}
set.add(ctx.getInstruction());
if (imul) {
if (!(ctx.getInstruction() instanceof IMul) & !(ctx.getInstruction() instanceof LMul)) {
l.add(ctx);
return l;
}
} else {
// invoke and array store pops are unrelated to each other
if (ctx.getInstruction() instanceof InvokeInstruction || ctx.getInstruction() instanceof ArrayStoreInstruction || ctx.getInstruction() instanceof ArrayLoad || ctx.getInstruction() instanceof If || ctx.getInstruction() instanceof If0 || ctx.getInstruction() instanceof LCmp || ctx.getInstruction() instanceof DivisionInstruction || ctx.getInstruction() instanceof IShR) {
return l;
}
l.add(ctx);
}
for (StackContext s : ctx.getPops()) {
l.addAll(getInsInExpr(s.getPushed(), set, imul));
}
for (StackContext s : ctx.getPushes()) {
for (InstructionContext i : s.getPopped()) {
l.addAll(getInsInExpr(i, set, imul));
}
}
return l;
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class MultiplicationDeobfuscator method visit.
private void visit(MethodContext ctx) {
for (InstructionContext ictx : ctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
MultiplicationExpression expression;
try {
expression = parseExpression(ictx, instruction.getClass());
} catch (IllegalStateException ex) {
continue;
}
if (expression == null) {
continue;
}
if (done.contains(instruction)) {
continue;
}
done.add(instruction);
assert instruction instanceof IMul || instruction instanceof LMul;
if (instruction instanceof IMul) {
count += expression.simplify(1);
} else if (instruction instanceof LMul) {
count += expression.simplify(1L);
} else {
throw new IllegalStateException();
}
}
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class MultiplicationDeobfuscatorTest method test9.
// aload 0
// aload 0
// aload 1
// invokevirtual class226/method4078()J
// ldc2_w -81013729583719545
// lmul
// dup2_x1
// ldc2_w -6236978337732675017
// lmul
// putfield class227/field3204 J
// ldc2_w -6236978337732675017
// lmul
// putfield class227/field3196 J
@Test
public void test9() {
ClassGroup group = ClassGroupFactory.generateGroup();
Code code = group.findClass("test").findMethod("func").getCode();
Instructions ins = code.getInstructions();
code.setMaxStack(3);
Instruction[] prepareVariables = { new LDC(ins, 1L), new LStore(ins, 0) };
for (Instruction i : prepareVariables) {
ins.addInstruction(i);
}
LDC constant1 = new LDC(ins, -81013729583719545L), constant2 = new LDC(ins, -6236978337732675017L), constant3 = new LDC(ins, -6236978337732675017L);
Instruction[] body = { new LDC(ins, 0), new LLoad(ins, 0), constant1, new LMul(ins), // lmul, 0, lmul
new Dup2_X1(ins), constant2, new LMul(ins), new Pop(ins), new Pop(ins), constant3, new LMul(ins), new Pop(ins), new VReturn(ins) };
for (Instruction i : body) {
ins.addInstruction(i);
}
Execution e = new Execution(group);
e.populateInitialMethods();
e.run();
assert constant1.getConstantAsLong() * constant2.getConstantAsLong() == 1L;
Deobfuscator d = new MultiplicationDeobfuscator();
d.run(group);
Assert.assertEquals(1L, constant1.getConstantAsLong());
Assert.assertEquals(1L, constant2.getConstantAsLong());
Assert.assertEquals(1L, constant3.getConstantAsLong());
}
use of net.runelite.asm.attributes.code.instructions.LMul in project runelite by runelite.
the class ModArith method findUses.
// find potential getters/setters for each field
private void findUses(MethodContext mctx) {
for (InstructionContext ctx : mctx.getInstructionContexts()) {
if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul) {
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();
if (field == null) {
continue;
}
FieldInfo fieldInfo = getFieldInfo(field);
// parse the full multiplication expression to
// get all associated constants
List<InstructionContext> insInExpr = getInsInExpr(ctx, new HashSet(), true);
for (InstructionContext ctx2 : insInExpr) {
if (!(ctx2.getInstruction() instanceof PushConstantInstruction)) {
continue;
}
PushConstantInstruction pci3 = (PushConstantInstruction) ctx2.getInstruction();
Number value = (Number) pci3.getConstant();
// field * constant
if (value instanceof Integer || value instanceof Long) {
fieldInfo.getters.add(value);
}
}
} else if (ctx.getInstruction() instanceof SetFieldInstruction) {
SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction();
Field field = sf.getMyField();
if (field == null) {
continue;
}
FieldInfo fieldInfo = getFieldInfo(field);
// value being set
InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
if (!(pushedsfi.getInstruction() instanceof IMul) && !(pushedsfi.getInstruction() instanceof LMul) && !(pushedsfi.getInstruction() instanceof IAdd) && !(pushedsfi.getInstruction() instanceof LAdd) && !(pushedsfi.getInstruction() instanceof ISub) && !(pushedsfi.getInstruction() instanceof LSub)) {
if (pushedsfi.getInstruction() instanceof LDC) {
PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction();
if (ldc.getConstant() instanceof Integer || ldc.getConstant() instanceof Long) {
Number i = (Number) ldc.getConstant();
// field = constant
fieldInfo.setters.add(i);
}
}
continue;
}
Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction();
Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction();
// field = field + imul
if (pushedsfi.getInstruction() instanceof IAdd) {
if (one instanceof IMul && two instanceof GetFieldInstruction) {
one = pushedsfi.getPops().get(0).getPushed().getPops().get(0).getPushed().getInstruction();
two = pushedsfi.getPops().get(0).getPushed().getPops().get(1).getPushed().getInstruction();
}
}
// if both one and two are constants then one of them must not be a setter
PushConstantInstruction pc = null;
if (one instanceof PushConstantInstruction && !(two instanceof PushConstantInstruction)) {
pc = (PushConstantInstruction) one;
} else if (two instanceof PushConstantInstruction && !(one instanceof PushConstantInstruction)) {
pc = (PushConstantInstruction) two;
}
if (pc == null) {
continue;
}
Number value2 = (Number) pc.getConstant();
// field = something * constant
if (value2 instanceof Integer || value2 instanceof Long) {
fieldInfo.setters.add(value2);
}
}
}
}
Aggregations