use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction 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);
}
}
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class ModArith method findConstants.
// find associated constants with each field
private void findConstants(MethodContext mctx) {
for (InstructionContext ctx : mctx.getInstructionContexts()) {
if (ctx.getInstruction() instanceof FieldInstruction) {
FieldInstruction fi = (FieldInstruction) ctx.getInstruction();
if (fi.getMyField() == null) {
continue;
}
if ((!fi.getField().getType().equals(Type.INT) && !fi.getField().getType().equals(Type.LONG)) || fi.getField().getType().isArray()) {
continue;
}
FieldInfo fieldInfo = getFieldInfo(fi.getMyField());
List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false);
// check if this contains another field
boolean other = false;
boolean getter = false, setter = false;
for (InstructionContext i : l) {
if (i.getInstruction() instanceof FieldInstruction) {
FieldInstruction fi2 = (FieldInstruction) i.getInstruction();
Field myField = fi2.getMyField();
if (myField != null && myField != fi.getMyField()) {
Type t = myField.getType();
if (t.equals(fi.getMyField().getType())) {
other = true;
}
} else if (myField != null && myField == fi.getMyField()) {
if (fi2 instanceof SetFieldInstruction) {
setter = true;
} else {
getter = true;
}
}
}
}
// check if this is a constant assignment
boolean constant = false;
if (fi instanceof SetFieldInstruction) {
// value being set
InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
if (pushedsfi.getInstruction() instanceof LDC) {
constant = true;
}
}
for (InstructionContext i : l) {
if (i.getInstruction() instanceof LDC) {
PushConstantInstruction w = (PushConstantInstruction) i.getInstruction();
if (w.getConstant() instanceof Integer || w.getConstant() instanceof Long) {
AssociatedConstant n = new AssociatedConstant();
n.value = (Number) w.getConstant();
n.other = other;
n.constant = constant;
n.getter = getter;
n.setter = setter;
fieldInfo.constants.add(n);
}
}
}
}
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class MultiplyOneDeobfuscator method visit.
private void visit(MethodContext mctx) {
for (InstructionContext ictx : mctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
Instructions ins = ictx.getInstruction().getInstructions();
if (ins == null) {
continue;
}
List<Instruction> ilist = ins.getInstructions();
if (!ilist.contains(ictx.getInstruction())) {
// already done
continue;
}
StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1);
StackContext other = null;
int removeIdx = -1;
if (one.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) one.getPushed().getInstruction()).getConstant(), 1)) {
removeIdx = 0;
other = two;
} else if (two.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) two.getPushed().getInstruction()).getConstant(), 1)) {
removeIdx = 1;
other = one;
}
if (removeIdx == -1) {
continue;
}
if (onlyConstants && !(other.getPushed().getInstruction() instanceof PushConstantInstruction)) {
continue;
}
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, removeIdx == 0 ? one : two)) {
continue;
}
// remove 1
ictx.removeStack(removeIdx);
// remove mul
ins.remove(instruction);
++count;
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class MultiplyZeroDeobfuscator method visit.
private void visit(MethodContext mctx) {
for (InstructionContext ictx : mctx.getInstructionContexts()) {
Instruction instruction = ictx.getInstruction();
Instructions ins = instruction.getInstructions();
if (ins == null) {
continue;
}
if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
continue;
}
List<Instruction> ilist = ins.getInstructions();
StackContext one = ictx.getPops().get(0);
StackContext two = ictx.getPops().get(1);
Instruction ione = one.getPushed().getInstruction(), itwo = two.getPushed().getInstruction();
boolean remove = false;
if (ione instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) ione;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (itwo instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) itwo;
Number value = (Number) pci.getConstant();
if (DMath.equals(value, 0)) {
remove = true;
}
}
if (remove == false) {
continue;
}
if (!ilist.contains(instruction)) {
// already done
continue;
}
if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) {
continue;
}
// remove both, remove imul, push 0
ictx.removeStack(1);
ictx.removeStack(0);
if (instruction instanceof IMul) {
ins.replace(instruction, new LDC(ins, 0));
} else if (instruction instanceof LMul) {
ins.replace(instruction, new LDC(ins, 0L));
} else {
throw new IllegalStateException();
}
++count;
}
}
use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction in project runelite by runelite.
the class ConstantParameter method findDeadParameters.
private void findDeadParameters(InstructionContext ins) {
List<ConstantMethodParameter> parameters = this.findParametersForMethod(ins.getFrame().getMethod());
for (ConstantMethodParameter parameter : parameters) {
int lvtIndex = parameter.lvtIndex;
if (parameter.invalid) {
continue;
}
if (ins.getInstruction() instanceof LVTInstruction) {
LVTInstruction lvt = (LVTInstruction) ins.getInstruction();
if (lvt.getVariableIndex() != lvtIndex) {
continue;
}
if (lvt.store() || ins.getInstruction().getType() == InstructionType.IINC) {
parameter.invalid = true;
// value changes at some point, parameter is used
continue;
}
// check what pops the parameter is a comparison
assert ins.getPushes().size() == 1;
StackContext sctx = ins.getPushes().get(0);
if (sctx.getPopped().size() != 1 || !(sctx.getPopped().get(0).getInstruction() instanceof ComparisonInstruction)) {
parameter.invalid = true;
continue;
}
}
if (!(ins.getInstruction() instanceof ComparisonInstruction)) {
continue;
}
// assume that this will always be variable index #paramIndex comp with a constant.
ComparisonInstruction comp = (ComparisonInstruction) ins.getInstruction();
StackContext one, two = null;
if (comp instanceof If0) {
one = ins.getPops().get(0);
} else if (comp instanceof If) {
one = ins.getPops().get(0);
two = ins.getPops().get(1);
} else {
throw new RuntimeException("Unknown comp ins");
}
// find if one is a lvt ins
LVTInstruction lvt = null;
StackContext other = null;
if (one.getPushed().getInstruction() instanceof LVTInstruction) {
lvt = (LVTInstruction) one.getPushed().getInstruction();
other = two;
} else if (two != null && two.getPushed().getInstruction() instanceof LVTInstruction) {
lvt = (LVTInstruction) two.getPushed().getInstruction();
other = one;
}
assert lvt == null || !lvt.store();
if (lvt == null || lvt.getVariableIndex() != lvtIndex) {
continue;
}
Number otherValue = null;
if (// two is null for if0
two != null) {
if (!(other.getPushed().getInstruction() instanceof PushConstantInstruction)) {
parameter.invalid = true;
continue;
}
PushConstantInstruction pc = (PushConstantInstruction) other.getPushed().getInstruction();
otherValue = (Number) pc.getConstant();
}
for (Number value : parameter.values) {
// the result of the comparison doesn't matter, only that it always goes the same direction for every invocation
boolean result = doLogicalComparison(value, comp, otherValue);
// not that all ifs for a specific parameter always take the same path
if (parameter.result != null && parameter.result != result) {
parameter.invalid = true;
} else {
parameter.operations.add(ins.getInstruction());
parameter.result = result;
}
}
}
}
Aggregations