⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 methodinvocationfixer.java

📁 proguard 3.5 java 混淆器 最新 免费 好用的 大家用用试一下吧 天行健-君子以自强不息 地势坤-君子以厚德载物
💻 JAVA
字号:
/* $Id: MethodInvocationFixer.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $ * * ProGuard -- shrinking, optimization, and obfuscation of Java class files. * * Copyright (c) 2002-2006 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package proguard.classfile.editor;import proguard.classfile.*;import proguard.classfile.util.ClassUtil;import proguard.classfile.attribute.CodeAttrInfo;import proguard.classfile.instruction.*;import proguard.classfile.visitor.*;/** * This InstructionVisitor fixes all inappropriate special/virtual/static/interface * invocations. * * @author Eric Lafortune */public class MethodInvocationFixerimplements   InstructionVisitor,             CpInfoVisitor,             MemberInfoVisitor{    private static final boolean DEBUG = false;    private CodeAttrInfoEditor codeAttrInfoEditor;    // Return values for the visitor methods.    private boolean isMethodInvocation;    private int     accessFlags;    private boolean isInitializer;    private boolean isInterfaceMethod;    private int     parameterSize;    /**     * Creates a new MethodInvocationFixer.     * @param codeAttrInfoEditor a code editor that can be used for     *                           accumulating changes to the code.     */    public MethodInvocationFixer(CodeAttrInfoEditor codeAttrInfoEditor)    {        this.codeAttrInfoEditor = codeAttrInfoEditor;    }    // Implementations for InstructionVisitor.    public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction) {}    public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction) {}    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction) {}    public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction) {}    public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) {}    public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction)    {        int cpIndex  = cpInstruction.cpIndex;        int constant = cpInstruction.constant;        // Get the constant pool entry's information.        isMethodInvocation = false;        isInterfaceMethod  = false;        accessFlags        = 0;        parameterSize      = constant;        classFile.constantPoolEntryAccept(cpIndex, this);        // Is it a method invocation?        if (isMethodInvocation)        {            // Do we need to update the opcode?            byte opcode = cpInstruction.opcode;            // Is the method static?            if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)            {                // But is it not a static invocation?                if (opcode != InstructionConstants.OP_INVOKESTATIC)                {                    // Replace the invocation by an invokestatic instruction.                    Instruction replacementInstruction =                        new CpInstruction(InstructionConstants.OP_INVOKESTATIC,                                          cpIndex).shrink();                    codeAttrInfoEditor.replaceInstruction(offset, replacementInstruction);                    if (DEBUG)                    {                        debug(classFile, methodInfo, offset, cpInstruction, replacementInstruction);                    }                }            }            // Is the method private, or an instance initializer?            else if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0 ||                     isInitializer)            {                // But is it not a special invocation?                if (opcode != InstructionConstants.OP_INVOKESPECIAL)                {                    // Replace the invocation by an invokespecial instruction.                    Instruction replacementInstruction =                        new CpInstruction(InstructionConstants.OP_INVOKESPECIAL,                                          cpIndex).shrink();                    codeAttrInfoEditor.replaceInstruction(offset, replacementInstruction);                    if (DEBUG)                    {                        debug(classFile, methodInfo, offset, cpInstruction, replacementInstruction);                    }                }            }            // Is the method an interface method?            else if (isInterfaceMethod)            {                // But is it not an interface invocation, or is the parameter                // size incorrect?                if (opcode != InstructionConstants.OP_INVOKEINTERFACE ||                    parameterSize != constant)                {                    // Fix the parameter size of the interface invocation.                    Instruction replacementInstruction =                        new CpInstruction(InstructionConstants.OP_INVOKEINTERFACE,                                          cpIndex,                                          parameterSize).shrink();                    codeAttrInfoEditor.replaceInstruction(offset, replacementInstruction);                    if (DEBUG)                    {                        debug(classFile, methodInfo, offset, cpInstruction, replacementInstruction);                    }                }            }            // The method is not static, private, an instance initializer, or            // an interface method.            else            {                // But is it not a virtual invocation (or a special invocation,                // which is allowed for super calls)?                if (opcode != InstructionConstants.OP_INVOKEVIRTUAL &&                    opcode != InstructionConstants.OP_INVOKESPECIAL)                {                    // Replace the invocation by an invokevirtual instruction.                    Instruction replacementInstruction =                        new CpInstruction(InstructionConstants.OP_INVOKEVIRTUAL,                                          cpIndex).shrink();                    codeAttrInfoEditor.replaceInstruction(offset, replacementInstruction);                    if (DEBUG)                    {                        debug(classFile, methodInfo, offset, cpInstruction, replacementInstruction);                    }                }            }        }    }    // Implementations for CpInfoVisitor.    public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) {}    public void visitLongCpInfo(ClassFile classFile, LongCpInfo longCpInfo) {}    public void visitFloatCpInfo(ClassFile classFile, FloatCpInfo floatCpInfo) {}    public void visitDoubleCpInfo(ClassFile classFile, DoubleCpInfo doubleCpInfo) {}    public void visitStringCpInfo(ClassFile classFile, StringCpInfo stringCpInfo) {}    public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo) {}    public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) {}    public void visitUtf8CpInfo(ClassFile classFile, Utf8CpInfo utf8CpInfo) {}    public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo)    {        // Check if this is an interface method.        classFile.constantPoolEntryAccept(interfaceMethodrefCpInfo.u2classIndex, this);        // Get the referenced method's access flags.        interfaceMethodrefCpInfo.referencedMemberInfoAccept(this);    }    public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo)    {        // Check if this is an interface method.        classFile.constantPoolEntryAccept(methodrefCpInfo.u2classIndex, this);        // Get the referenced method's access flags.        methodrefCpInfo.referencedMemberInfoAccept(this);    }    public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)    {        // Check if this class entry refers to an interface class.        ClassFile referencedClassFile = classCpInfo.referencedClassFile;        if (referencedClassFile != null)        {            isInterfaceMethod = (referencedClassFile.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;        }    }    // Implementations for MemberInfoVisitor.    public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo) {}    public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)    {        visitMethodInfo(programClassFile, programMethodInfo);    }    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo) {}    public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)    {        visitMethodInfo(libraryClassFile, libraryMethodInfo);    }    private void visitMethodInfo(ClassFile classFile, MethodInfo methodInfo)    {        // We've found a method definition.        isMethodInvocation = true;        // Get the method's access flags.        accessFlags = methodInfo.getAccessFlags();        // Check if this is an instance initializer.        isInitializer = methodInfo.getName(classFile).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);        // Remember the parameter size of interface methods.        if (isInterfaceMethod)        {            parameterSize = ClassUtil.internalMethodParameterSize(methodInfo.getDescriptor(classFile)) + 1 << 8;        }    }    // Small utility methods.    private void debug(ClassFile     classFile,                       MethodInfo    methodInfo,                       int           offset,                       CpInstruction cpInstruction,                       Instruction   replacementInstruction)    {        System.out.println("MethodInvocationFixer:");        System.out.println("  Class file       = "+classFile.getName());        System.out.println("  Method           = "+methodInfo.getName(classFile)+methodInfo.getDescriptor(classFile));        System.out.println("  Instruction      = "+cpInstruction.toString(offset));        System.out.println("  Interface method = "+isInterfaceMethod);        if (isInterfaceMethod)        {            System.out.println("  Parameter size   = "+parameterSize);        }        System.out.println("  Replacement instruction = "+replacementInstruction.toString(offset));    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -