use of net.runelite.asm.execution.Variables in project runelite by runelite.
the class IInc method execute.
@Override
public InstructionContext execute(Frame frame) {
InstructionContext ins = new InstructionContext(this, frame);
Variables var = frame.getVariables();
VariableContext vctx = var.get(index);
assert vctx.getType().isStackInt();
ins.read(vctx);
Value value = vctx.getValue();
if (!vctx.getValue().isUnknownOrNull()) {
int i = (int) vctx.getValue().getValue();
i += inc;
value = new Value(i);
}
vctx = new VariableContext(ins, Type.INT, value);
var.set(index, vctx);
return ins;
}
use of net.runelite.asm.execution.Variables in project runelite by runelite.
the class LLoad method execute.
@Override
public InstructionContext execute(Frame frame) {
InstructionContext ins = new InstructionContext(this, frame);
Stack stack = frame.getStack();
Variables variables = frame.getVariables();
VariableContext vctx = variables.get(index);
assert vctx.getType().equals(Type.LONG);
ins.read(vctx);
StackContext ctx = new StackContext(ins, vctx);
stack.push(ctx);
ins.push(ctx);
return ins;
}
use of net.runelite.asm.execution.Variables in project runelite by runelite.
the class LStore method execute.
@Override
public InstructionContext execute(Frame frame) {
InstructionContext ins = new InstructionContext(this, frame);
Stack stack = frame.getStack();
Variables variables = frame.getVariables();
StackContext value = stack.pop();
assert value.getType().equals(Type.LONG);
ins.pop(value);
variables.set(index, new VariableContext(ins, value));
return ins;
}
use of net.runelite.asm.execution.Variables in project runelite by runelite.
the class MultiplicationDeobfuscator method parseExpression.
public static MultiplicationExpression parseExpression(InstructionContext ctx, Class want) {
MultiplicationExpression me = new MultiplicationExpression();
if (ctx.getInstruction() instanceof LVTInstruction) {
LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
// loading a variable
if (!lvt.store()) {
// var index
int idx = lvt.getVariableIndex();
// variables at time of execution
Variables vars = ctx.getVariables();
// get the variable
VariableContext vctx = vars.get(idx);
if (// ?
vctx.getRead().size() == 1) {
// this is an istore
InstructionContext storeCtx = vctx.getInstructionWhichStored();
if (storeCtx.getInstruction() instanceof LVTInstruction) {
// invoking funcs can put stuff in lvt
LVTInstruction storelvt = (LVTInstruction) storeCtx.getInstruction();
if (storelvt instanceof IInc)
throw new IllegalStateException();
assert storelvt.store();
InstructionContext pushed = storeCtx.getPops().get(0).getPushed();
return parseExpression(pushed, want);
}
}
}
}
if (ctx.getInstruction() instanceof PushConstantInstruction) {
if (ctx.getInstruction() instanceof BiPush || ctx.getInstruction() instanceof SiPush) {
throw new IllegalStateException();
}
me.instructions.add(ctx);
return me;
}
for (StackContext sctx : ctx.getPops()) {
if (ctx.getInstruction().getClass() == want) {
if (!isOnlyPath(ctx, sctx))
continue;
}
InstructionContext i = sctx.getPushed();
// if this instruction is imul, look at pops
if (ctx.getInstruction().getClass() == want) {
if (i.getInstruction() instanceof Swap) {
logger.debug("Resolving swap");
Swap swap = (Swap) i.getInstruction();
sctx = swap.getOriginal(sctx);
i = sctx.getPushed();
}
if (i.getInstruction() instanceof PushConstantInstruction) {
// bipush/sipush are always not obfuscated
if (i.getInstruction() instanceof BiPush || i.getInstruction() instanceof SiPush)
continue;
// a constant of imul
me.instructions.add(i);
} else if (i.getInstruction().getClass() == want) {
// chained imul, append to me
try {
MultiplicationExpression other = parseExpression(i, want);
if (other.dupmagic != null) {
assert me.dupmagic == null;
me.dupmagic = other.dupmagic;
}
me.instructions.addAll(other.instructions);
me.dupedInstructions.addAll(other.dupedInstructions);
me.subexpressions.addAll(other.subexpressions);
} catch (IllegalStateException ex) {
// this is ok? just don't include it?
}
} else if (i.getInstruction() instanceof IAdd || i.getInstruction() instanceof ISub || i.getInstruction() instanceof LAdd || i.getInstruction() instanceof LSub) {
// imul using result of iadd or isub. evaluate expression
try {
MultiplicationExpression other = parseExpression(i, want);
assert other.dupmagic == null;
// subexpr
me.subexpressions.add(other);
} catch (IllegalStateException ex) {
assert me.subexpressions.isEmpty();
// subexpression is too complex. we can still simplify the top level though
}
} else if (i.getInstruction() instanceof DupInstruction) {
DupInstruction dup = (DupInstruction) i.getInstruction();
// find other branch of the dup instruction
// sctx = what dup pushed, find other
// other side of dup
StackContext otherCtx = dup.getOtherBranch(sctx);
// what popped other side of dup. is this right?
InstructionContext otherCtxI = otherCtx.getPopped().get(0);
if (otherCtxI.getInstruction().getClass() == want) {
// assert otherCtxI.getInstruction() instanceof IMul;
// other side of that imul
InstructionContext pushConstant = otherCtxI.getPops().get(0).getPushed();
assert pushConstant.getInstruction() instanceof LDC;
me.dupmagic = pushConstant;
// original
StackContext orig = dup.getOriginal(sctx);
try {
MultiplicationExpression other = parseExpression(orig.getPushed(), want);
// done to it affect that, too. so multiply it by existing values?
if (orig.getPushed().getInstruction() instanceof IAdd || orig.getPushed().getInstruction() instanceof ISub || orig.getPushed().getInstruction() instanceof LAdd || orig.getPushed().getInstruction() instanceof LSub) {
me.subexpressions.add(other);
} else {
assert other.dupmagic == null;
me.instructions.addAll(other.instructions);
me.dupedInstructions.addAll(other.instructions);
me.subexpressions.addAll(other.subexpressions);
}
} catch (IllegalStateException ex) {
assert me.subexpressions.isEmpty();
}
}
} else if (i.getInstruction() instanceof GetFieldInstruction) {
me.fieldInstructions.add(i);
// non constant, ignore
} else {
// System.out.println("imul pops something I don't know " + i.getInstruction());
}
} else // this is an iadd/sub
if (ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub || ctx.getInstruction() instanceof LAdd || ctx.getInstruction() instanceof LSub) {
// parse this side of the add/sub
MultiplicationExpression other = parseExpression(i, want);
me.subexpressions.add(other);
} else {
// System.out.println(ctx.getInstruction() + " pops something I dont know " + i.getInstruction());
}
}
if (me.instructions.isEmpty() && me.subexpressions.isEmpty())
throw new IllegalStateException();
return me;
}
use of net.runelite.asm.execution.Variables in project runelite by runelite.
the class IfICmpEqTest method testIsSame.
@Test
public void testIsSame() {
Instructions ins = mock(Instructions.class);
Frame frame = mock(Frame.class);
Stack stack = new Stack(42);
Variables variables = new Variables(42);
when(frame.getStack()).thenReturn(stack);
when(frame.getVariables()).thenReturn(variables);
IfICmpEq ifeq = new IfICmpEq(ins, InstructionType.IF_ICMPEQ);
InstructionContext ifeqCtx = new InstructionContext(ifeq, frame);
ifeqCtx.pop(new StackContext(getConstantCtx(ins, 1), INT, new Value(1)));
ifeqCtx.pop(new StackContext(getConstantCtx(ins, 1), INT, new Value(1)));
IfNe ifne = new IfNe(ins, InstructionType.IFNE);
InstructionContext ifneCtx = new InstructionContext(ifne, frame);
ifneCtx.pop(new StackContext(getConstantCtx(ins, 42), INT, new Value(42)));
assertTrue(ifeq.isSame(ifeqCtx, ifneCtx));
}
Aggregations