use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class ExprArgOrder method hash.
private static void hash(Method method, MessageDigest sha256, InstructionContext ic) {
Instruction i = ic.getInstruction();
// this relies on all push constants are converted to ldc..
sha256.update((byte) i.getType().getCode());
if (i instanceof PushConstantInstruction) {
PushConstantInstruction pci = (PushConstantInstruction) i;
Object constant = pci.getConstant();
if (constant instanceof Number) {
long l = ((Number) constant).longValue();
sha256.update(Longs.toByteArray(l));
}
} else if (i instanceof LVTInstruction) {
int idx = ((LVTInstruction) i).getVariableIndex();
Signature signature = method.getDescriptor();
int lvt = method.isStatic() ? 0 : 1;
for (Type type : signature.getArguments()) {
if (idx == lvt) {
// Accessing a method parameter
sha256.update(Ints.toByteArray(idx));
break;
}
lvt += type.getSize();
}
}
for (StackContext sctx : ic.getPops()) {
hash(method, sha256, sctx.getPushed());
}
}
use of net.runelite.asm.execution.StackContext 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;
}
use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class InjectHook method run.
public void run() {
Execution e = new Execution(inject.getVanilla());
e.populateInitialMethods();
Set<Instruction> done = new HashSet<>();
Set<Instruction> doneIh = new HashSet<>();
e.addExecutionVisitor((InstructionContext ic) -> {
Instruction i = ic.getInstruction();
Instructions ins = i.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
if (method.getName().equals(CLINIT)) {
return;
}
if (!(i instanceof SetFieldInstruction)) {
return;
}
if (!done.add(i)) {
return;
}
SetFieldInstruction sfi = (SetFieldInstruction) i;
Field fieldBeingSet = sfi.getMyField();
if (fieldBeingSet == null) {
return;
}
HookInfo hookInfo = hooked.get(fieldBeingSet);
if (hookInfo == null) {
return;
}
String hookName = hookInfo.fieldName;
assert hookName != null;
logger.trace("Found injection location for hook {} at instruction {}", hookName, sfi);
++injectedHooks;
Instruction objectInstruction = new AConstNull(ins);
StackContext objectStackContext = null;
if (sfi instanceof PutField) {
// Object being set on
StackContext objectStack = ic.getPops().get(1);
objectStackContext = objectStack;
}
int idx = ins.getInstructions().indexOf(sfi);
assert idx != -1;
try {
// idx + 1 to insert after the set
injectCallback(ins, idx + 1, hookInfo, null, objectStackContext);
} catch (InjectionException ex) {
throw new RuntimeException(ex);
}
});
// these look like:
// getfield
// iload_0
// iconst_0
// iastore
e.addExecutionVisitor((InstructionContext ic) -> {
Instruction i = ic.getInstruction();
Instructions ins = i.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
if (method.getName().equals(CLINIT)) {
return;
}
if (!(i instanceof ArrayStore)) {
return;
}
if (!doneIh.add(i)) {
return;
}
ArrayStore as = (ArrayStore) i;
Field fieldBeingSet = as.getMyField(ic);
if (fieldBeingSet == null) {
return;
}
HookInfo hookInfo = hooked.get(fieldBeingSet);
if (hookInfo == null) {
return;
}
String hookName = hookInfo.fieldName;
// assume this is always at index 1
StackContext index = ic.getPops().get(1);
StackContext arrayReference = ic.getPops().get(2);
InstructionContext arrayReferencePushed = arrayReference.getPushed();
StackContext objectStackContext = null;
if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD) {
StackContext objectReference = arrayReferencePushed.getPops().get(0);
objectStackContext = objectReference;
}
// inject hook after 'i'
logger.info("Found array injection location for hook {} at instruction {}", hookName, i);
++injectedHooks;
int idx = ins.getInstructions().indexOf(i);
assert idx != -1;
try {
injectCallback(ins, idx + 1, hookInfo, index, objectStackContext);
} catch (InjectionException ex) {
throw new RuntimeException(ex);
}
});
e.run();
}
use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class PutField method isSame.
@Override
public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) {
if (thisIc.getInstruction().getClass() != otherIc.getInstruction().getClass()) {
return false;
}
PutField thisPf = (PutField) thisIc.getInstruction(), otherPf = (PutField) otherIc.getInstruction();
net.runelite.asm.Field f1 = thisPf.getMyField();
net.runelite.asm.Field f2 = otherPf.getMyField();
if ((f1 != null) != (f2 != null)) {
return false;
}
if (!MappingExecutorUtil.isMaybeEqual(f1.getClassFile(), f2.getClassFile()) || !MappingExecutorUtil.isMaybeEqual(f1.getType(), f2.getType())) {
return false;
}
// check assignment
StackContext object1 = thisIc.getPops().get(1), object2 = otherIc.getPops().get(1);
InstructionContext base1 = MappingExecutorUtil.resolve(object1.getPushed(), object1);
InstructionContext base2 = MappingExecutorUtil.resolve(object2.getPushed(), object2);
if (!isMaybeEqual(base1, base2)) {
return false;
}
// check value
object1 = thisIc.getPops().get(0);
object2 = otherIc.getPops().get(0);
base1 = MappingExecutorUtil.resolve(object1.getPushed(), object1);
base2 = MappingExecutorUtil.resolve(object2.getPushed(), object2);
if (!isMaybeEqual(base1, base2)) {
return false;
}
return true;
}
use of net.runelite.asm.execution.StackContext in project runelite by runelite.
the class Return 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);
frame.stop();
return ins;
}
Aggregations