use of net.runelite.asm.attributes.code.instruction.types.DupInstruction in project runelite by runelite.
the class MappingExecutorUtil method resolve.
public static InstructionContext resolve(InstructionContext ctx, // pushed from ctx
StackContext from) {
if (ctx.getInstruction() instanceof SetFieldInstruction) {
StackContext s = ctx.getPops().get(0);
return resolve(s.getPushed(), s);
}
if (ctx.getInstruction() instanceof ConversionInstruction) {
// assume it pops one and pushes one
StackContext s = ctx.getPops().get(0);
return resolve(s.getPushed(), s);
}
if (ctx.getInstruction() instanceof DupInstruction) {
DupInstruction d = (DupInstruction) ctx.getInstruction();
StackContext s = d.getOriginal(from);
return resolve(s.getPushed(), s);
}
if (ctx.getInstruction() instanceof ArrayLoad) {
// might be multidimensional array
// the array
StackContext s = ctx.getPops().get(1);
return resolve(s.getPushed(), s);
}
if (ctx.getInstruction() instanceof LVTInstruction) {
LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
Variables variables = ctx.getVariables();
if (lvt.store()) {
// is this right?
StackContext s = ctx.getPops().get(0);
return resolve(s.getPushed(), s);
} else {
// variable being loaded
VariableContext vctx = variables.get(lvt.getVariableIndex());
assert vctx != null;
InstructionContext storedCtx = vctx.getInstructionWhichStored();
if (storedCtx == null)
// initial parameter
return ctx;
if (vctx.isIsParameter()) {
// this storedCtx is the invoke instruction which called this method.
assert storedCtx.getInstruction() instanceof InvokeInstruction;
// In PME non static functions are never stepped into/aren't inline obfuscated
assert storedCtx.getInstruction() instanceof InvokeStatic;
// Figure out parameter index from variable index.
// signature of current method
Signature sig = ctx.getFrame().getMethod().getDescriptor();
int paramIndex = 0;
for (int lvtIndex = 0; /* static */
paramIndex < sig.size(); lvtIndex += sig.getTypeOfArg(paramIndex++).getSize()) if (lvtIndex == lvt.getVariableIndex())
break;
assert paramIndex < sig.size();
// Get stack context that was popped by the invoke
// pops[0] is the first thing popped, which is the last parameter.
StackContext sctx = storedCtx.getPops().get(sig.size() - 1 - paramIndex);
return resolve(sctx.getPushed(), sctx);
}
return resolve(storedCtx, null);
}
}
if (ctx.getInstruction() instanceof InvokeStatic) {
if (from.returnSource != null) {
return resolve(from.returnSource.getPushed(), from.returnSource);
}
}
return ctx;
}
use of net.runelite.asm.attributes.code.instruction.types.DupInstruction 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.attributes.code.instruction.types.DupInstruction in project runelite by runelite.
the class DupDeobfuscator method copy.
/**
* copy the instruction which pushed sctx and insert into instructions
* starting at index idx
*/
private int copy(StackContext sctx, Instructions instructions, int idx) {
InstructionContext ictx = sctx.getPushed();
if (ictx.getInstruction() instanceof DupInstruction) {
// we only care about one path
DupInstruction di = (DupInstruction) ictx.getInstruction();
sctx = di.getOriginal(sctx);
ictx = sctx.getPushed();
}
// the first thing popped was pushed last, so reverse
for (StackContext s : Lists.reverse(ictx.getPops())) {
idx = copy(s, instructions, idx);
}
// copy instruction
Instruction i = ictx.getInstruction();
logger.debug("Duplicating instruction {} at index {}", i, idx);
i = i.clone();
instructions.addInstruction(idx, i);
// move on to next instruction
return idx + 1;
}
use of net.runelite.asm.attributes.code.instruction.types.DupInstruction in project runelite by runelite.
the class InstructionContext method resolve.
public InstructionContext resolve(// pushed from this
StackContext from) {
InstructionContext ctx = this;
if (ctx.getInstruction() instanceof SetFieldInstruction) {
StackContext s = ctx.getPops().get(0);
return s.getPushed().resolve(s);
}
if (ctx.getInstruction() instanceof DupInstruction) {
DupInstruction d = (DupInstruction) ctx.getInstruction();
StackContext s = d.getOriginal(from);
return s.getPushed().resolve(s);
}
if (ctx.getInstruction() instanceof LVTInstruction) {
LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
Variables variables = ctx.getVariables();
if (lvt.store()) {
// is this right?
StackContext s = ctx.getPops().get(0);
return s.getPushed().resolve(s);
} else {
// variable being loaded
VariableContext vctx = variables.get(lvt.getVariableIndex());
assert vctx != null;
InstructionContext storedCtx = vctx.getInstructionWhichStored();
if (storedCtx == null)
// initial parameter
return ctx;
if (vctx.isIsParameter())
// parameter (storedCtx is invoking instruction in another frame). this lvt index is fixed.
return ctx;
return storedCtx.resolve(null);
}
}
if (ctx.getInstruction() instanceof Swap) {
Swap swap = (Swap) ctx.getInstruction();
StackContext s = swap.getOriginal(from);
return s.getPushed().resolve(s);
}
return ctx;
}
use of net.runelite.asm.attributes.code.instruction.types.DupInstruction in project runelite by runelite.
the class InjectHook method recursivelyPush.
private int recursivelyPush(Instructions ins, int idx, StackContext sctx) {
InstructionContext ctx = sctx.getPushed();
if (ctx.getInstruction() instanceof DupInstruction) {
DupInstruction dupInstruction = (DupInstruction) ctx.getInstruction();
sctx = dupInstruction.getOriginal(sctx);
ctx = sctx.getPushed();
}
for (StackContext s : Lists.reverse(ctx.getPops())) {
idx = recursivelyPush(ins, idx, s);
}
ins.getInstructions().add(idx++, ctx.getInstruction().clone());
return idx;
}
Aggregations