/** * Hooks the specified method and all call-through methods * * @param from * @param to */ public void addMethodHook(HookMethod from, MethodIdItem to) { mMethodHooksExist = true; Queue<HookMethod> affectedMethods = new LinkedList<HookMethod>(); affectedMethods.add(from); do { HookMethod affected = affectedMethods.remove(); mHooks.put(affected, to); Set<String> allSubclasses = getSubclassMap().get(affected.mClasspath); if (allSubclasses == null) { continue; } for (String subclass : allSubclasses) { HookMethod possible = affected.clone(); possible.mClasspath = subclass; MethodIdItem possibleMethodInfo = getMethodMap().get(possible); if (possibleMethodInfo == null || possibleMethodInfo.isFallthrough()) { affectedMethods.add(possible); } } } while (!affectedMethods.isEmpty()); }
public HookMethod(MethodIdItem item) { mClasspath = item.getContainingClass().getTypeDescriptor(); mName = item.getMethodName().getStringValue(); TypeListItem parameters = item.getPrototype().getParameters(); if (parameters != null) { mArgs = parameters.getTypeListString(""); } mReturn = item.getPrototype().getReturnType().getTypeDescriptor(); }
private void updateInvokeType(Instruction inst, MethodIdItem newMethod) { int accessFlags = newMethod.getAccess(); int staticMask = AccessFlags.STATIC.getValue(); int privateMask = AccessFlags.PRIVATE.getValue(); int finalMask = AccessFlags.FINAL.getValue(); int constructorMask = AccessFlags.CONSTRUCTOR.getValue(); int directMask = privateMask | finalMask | constructorMask; if ((accessFlags & staticMask) != 0) { if (inst instanceof Instruction35c) { inst.opcode = Opcode.INVOKE_STATIC; } else if (inst instanceof Instruction3rc) { inst.opcode = Opcode.INVOKE_STATIC_RANGE; } } else if ((accessFlags & directMask) != 0) { if (inst instanceof Instruction35c) { inst.opcode = Opcode.INVOKE_DIRECT; } else if (inst instanceof Instruction3rc) { inst.opcode = Opcode.INVOKE_DIRECT_RANGE; } } else { if (inst instanceof Instruction35c) { inst.opcode = Opcode.INVOKE_VIRTUAL; } else if (inst instanceof Instruction3rc) { inst.opcode = Opcode.INVOKE_VIRTUAL_RANGE; } } }