use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class AdditionInstruction method map.
@Override
default void map(ParallelExecutorMapping mappings, InstructionContext ctx, InstructionContext other) {
/* lhs/rhs of addition instructions are randomally swapped, but
* we still map if each side is recognizable
*
* N.B. since the lhs/rhs of nested iadds can be swapped, and
* the mapper maps the first that it encounters, this can certainly
* attempt to map the wrong instructions even when mapping the correct
* method, so be careful.
*/
StackContext ctx1 = ctx.getPops().get(0);
StackContext ctx2 = ctx.getPops().get(1);
StackContext other1 = other.getPops().get(0);
StackContext other2 = other.getPops().get(1);
InstructionContext rc1 = ctx1.getPushed().resolve(ctx1);
// iaload
InstructionContext rc2 = ctx2.getPushed().resolve(ctx2);
InstructionContext ro1 = other1.getPushed().resolve(other1);
// iaload
InstructionContext ro2 = other2.getPushed().resolve(other2);
// There are a couple static final arrays that are only ever read from 1 or 2 places.. and never written
InstructionContext al1 = findArrayLoad(rc1, rc2);
InstructionContext al2 = findArrayLoad(ro1, ro2);
if (al1 == null || al2 == null) {
return;
}
StackContext array1 = al1.getPops().get(1);
StackContext array2 = al2.getPops().get(1);
InstructionContext field1 = array1.getPushed().resolve(array1);
InstructionContext field2 = array2.getPushed().resolve(array2);
if (!(field1.getInstruction() instanceof GetFieldInstruction) || !(field2.getInstruction() instanceof GetFieldInstruction)) {
return;
}
GetFieldInstruction gf1 = (GetFieldInstruction) field1.getInstruction();
GetFieldInstruction gf2 = (GetFieldInstruction) field2.getInstruction();
Field f1 = gf1.getMyField();
Field f2 = gf2.getMyField();
if (f1 == null || f2 == null || !MappingExecutorUtil.isMaybeEqual(f1, f2)) {
return;
}
mappings.map((Instruction) this, f1, f2);
}
use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class PacketWriteDeobfuscator method insert.
private void insert(Instructions ins, InstructionContext ic, Instruction before) {
List<StackContext> pops = new ArrayList<>(ic.getPops());
Collections.reverse(pops);
for (StackContext sc : pops) {
insert(ins, sc.getPushed(), before);
}
Instruction i = ic.getInstruction().clone();
i = translate(i);
assert i.getInstructions() == ins;
int idx = ins.getInstructions().indexOf(before);
assert idx != -1;
ins.addInstruction(idx, i);
}
use of net.runelite.asm.execution.StackContext 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.execution.StackContext in project runelite by runelite.
the class FSub method execute.
@Override
public InstructionContext execute(Frame frame) {
InstructionContext ins = new InstructionContext(this, frame);
Stack stack = frame.getStack();
StackContext two = stack.pop();
StackContext one = stack.pop();
ins.pop(two, one);
Value result = Value.UNKNOWN;
if (!two.getValue().isUnknownOrNull() && !one.getValue().isUnknownOrNull()) {
float f2 = (float) two.getValue().getValue(), f1 = (float) one.getValue().getValue();
result = new Value(f1 - f2);
}
StackContext ctx = new StackContext(ins, Type.FLOAT, result);
stack.push(ctx);
ins.push(ctx);
return ins;
}
use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class I2F method execute.
@Override
public InstructionContext execute(Frame frame) {
InstructionContext ins = new InstructionContext(this, frame);
Stack stack = frame.getStack();
StackContext object = stack.pop();
ins.pop(object);
StackContext ctx = new StackContext(ins, Type.FLOAT, object.getValue().cast(float.class));
stack.push(ctx);
ins.push(ctx);
return ins;
}
Aggregations