public static boolean methodDescsCloseEnough(String mightHaveVMState, String desc) { Type[] d1 = Type.getArgumentTypes(mightHaveVMState); Type[] d2 = Type.getArgumentTypes(desc); if (Arrays.deepEquals(d1, d2)) return true; if (d1[d1.length - 1].getInternalName().equals(Type.getInternalName(VMState.class))) { if (d1.length - 1 != d2.length) return false; for (int i = 0; i < d1.length - 1; i++) if (!d1[i].equals(d2[i])) return false; return true; } return false; }
// private static Logger log = Logger.getLogger(InvivoAdapter.class); public InvivoAdapter( int api, MethodVisitor mv, int access, String name, String desc, String className, boolean generateReverseStub) { // super(api, mv, access, name, desc); super(mv); this.access = access; this.name = name; this.desc = desc; this.className = className; Type[] args = Type.getArgumentTypes(desc); firstLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; for (int i = 0; i < args.length; i++) { firstLocal += args[i].getSize(); } sandboxVar = isMain() || isClinit() ? getFirstLocal() : getFirstLocal() - 1; if (generateReverseStub) { GeneratorAdapter gv = new GeneratorAdapter(mv, access, name, desc); gv.visitCode(); gv.loadThis(); for (int i = 0; i < args.length - 1; i++) { gv.loadArg(i); } Type[] args2 = new Type[args.length - 1]; System.arraycopy(args, 0, args2, 0, args.length - 1); gv.visitMethodInsn( INVOKEVIRTUAL, className, name.substring(1), Type.getMethodDescriptor(Type.getReturnType(desc), args2), false); // switch(Type.getReturnType(desc).getSort()) // { // case Type.ARRAY: // case Type.OBJECT: // gv.visitLdcInsn(null); // break; // case Type.VOID: // break; // default: // gv.push(0); // } gv.returnValue(); gv.visitMaxs(0, 0); // mv.visitEnd(); } }
@Override public SourceValue newValue(final Type type) { if (type == Type.VOID_TYPE) { return null; } return new SourceValue(type == null ? 1 : type.getSize()); }
@Override public SourceValue naryOperation( final AbstractInsnNode insn, final List<? extends SourceValue> values) { int size; int opcode = insn.getOpcode(); if (opcode == MULTIANEWARRAY) { size = 1; } else { String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc; size = Type.getReturnType(desc).getSize(); } return new SourceValue(size, insn); }
@Override public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value) { int size; switch (insn.getOpcode()) { case LNEG: case DNEG: case I2L: case I2D: case L2D: case F2L: case F2D: case D2L: size = 2; break; case GETFIELD: size = Type.getType(((FieldInsnNode) insn).desc).getSize(); break; default: size = 1; } return new SourceValue(size, insn); }
@Override public SourceValue newOperation(final AbstractInsnNode insn) { int size; switch (insn.getOpcode()) { case LCONST_0: case LCONST_1: case DCONST_0: case DCONST_1: size = 2; break; case LDC: Object cst = ((LdcInsnNode) insn).cst; size = cst instanceof Long || cst instanceof Double ? 2 : 1; break; case GETSTATIC: size = Type.getType(((FieldInsnNode) insn).desc).getSize(); break; default: size = 1; } return new SourceValue(size, insn); }
private void visitVMVMLocalVariable() { if (sandboxVar >= 0 && !sandboxVarVisited && isRegularClass()) { try { sandboxVarVisited = true; super.visitLocalVariable( "secretVMVMD4t4z", Type.getDescriptor(VMState.class), null, start, end, sandboxVar); } catch (NullPointerException ex) { System.err.println( "Unable to visit local variable vmvmSandboxIndx (num " + sandboxVar + ") [labels=" + start + "; " + end + "]" + "[method = " + this.className + "." + this.name + this.desc); ex.printStackTrace(); } } }
public void cloneLocals(int whereToStop) { oldLVtoSandboxLV = new HashMap<>(); List<?> oldLocals = getLocals(); for (int i = 0; i < whereToStop; i++) { Type t = lvs.getLocalTypes().get(i); if (i == 0 && t == null && (access & ACC_STATIC) == 0) t = Type.getType("L" + className + ";"); if (i < firstLocal && t == null) { if ((Opcodes.ACC_STATIC & access) == 0) t = Type.getMethodType(this.desc).getArgumentTypes()[i - 1]; else t = Type.getMethodType(this.desc).getArgumentTypes()[i]; } if (t.getSort() == Type.OBJECT && t.getInternalName().equals("java/lang/Object")) { // Default to the type of what we cloened from for (Object o : oldLocals) { LocalVariableNode lv = (LocalVariableNode) o; if (lv.index + 1 == i) { t = Type.getType(lv.desc); break; } } } int idx = lvs.newLocal(t); oldLVtoSandboxLV.put(i, idx); newLVs.add(new LocalVariableNode("clone_" + i, t.getDescriptor(), null, null, null, idx)); load(i, t); if (t.getSort() == Type.ARRAY || t.getSort() == Type.OBJECT) cloneValAtTopOfStack(t.getDescriptor()); store(idx, t); } }
public void getSandboxFlag() { getSandboxFlagState(); super.visitMethodInsn( INVOKEVIRTUAL, Type.getInternalName(VMState.class), "getState", "()I", false); }