instructionsequencereplacer.java

来自「ProGuard 是一个免费的 Java类文件的压缩」· Java 代码 · 共 783 行 · 第 1/3 页

JAVA
783
字号
        for (int index = 0; index < jumpOffsetCount; index++)        {            if (!matchingBranchOffsets(offset,                                       jumpOffsets1[index],                                       jumpOffsets2[index]))            {                return false;            }        }        return true;    }    private int matchedArgument(int argument)    {        int argumentIndex = argument - X;        return argumentIndex < 0 ?            argument :            matchedArguments[argumentIndex];    }    private int[] matchedArguments(int[] arguments,                                   int   argumentCount)    {        int[] matchedArguments = new int[argumentCount];        for (int index = 0; index < argumentCount; index++)        {            matchedArguments[index] = matchedArgument(arguments[index]);        }        return matchedArguments;    }    private int matchedConstantIndex(int constantIndex)    {        int argumentIndex = constantIndex - X;        return argumentIndex < 0 ?            matchedConstantIndices[constantIndex] :            matchedArguments[argumentIndex];    }    private int matchedBranchOffset(int offset, int branchOffset)    {        int argumentIndex = branchOffset - X;        return argumentIndex < 0 ?            branchOffset :            matchedArguments[argumentIndex] - offset;    }    private int[] matchedJumpOffsets(int   offset,                                     int[] jumpOffsets,                                     int   jumpOffsetCount)    {        int[] matchedJumpOffsets = new int[jumpOffsetCount];        for (int index = 0; index < jumpOffsetCount; index++)        {            matchedJumpOffsets[index] = matchedBranchOffset(offset,                                                            jumpOffsets[index]);        }        return matchedJumpOffsets;    }    private void matchInstruction(boolean       condition,                                  Clazz         clazz,                                  Method        method,                                  CodeAttribute codeAttribute,                                  int           offset,                                  Instruction   instruction)    {        // Did the instruction match?        if (condition)        {            // Remember the offset of the matching instruction.            matchedInstructionOffsets[patternInstructionIndex] = offset;            // Try to match the next instruction next time.            patternInstructionIndex++;            // Did we match all instructions in the from sequence?            if (patternInstructionIndex == patternInstructions.length)            {                if (patternInstructionsUnmodified())                {                    if (DEBUG)                    {                        System.out.println("InstructionSequenceReplacer: ["+clazz.getName()+"."+method.getName(clazz)+"]");                        System.out.println("  Matched:");                        for (int index = 0; index < patternInstructions.length; index++)                        {                            System.out.println("    "+InstructionFactory.create(codeAttribute.code, matchedInstructionOffsets[index]).toString(matchedInstructionOffsets[index]));                        }                        System.out.println("  Replacement:");                        for (int index = 0; index < replacementInstructions.length; index++)                        {                            System.out.println("    "+replacementInstructionFactory.create(index).shrink().toString(matchedInstructionOffsets[index]));                        }                    }                    // Replace the instruction sequence.                    for (int index = 0; index < replacementInstructions.length; index++)                    {                        codeAttributeEditor.replaceInstruction(matchedInstructionOffsets[index],                                                               replacementInstructionFactory.create(index).shrink());                    }                    // Delete any remaining instructions in the from sequence.                    for (int index = replacementInstructions.length; index < patternInstructions.length; index++)                    {                        codeAttributeEditor.deleteInstruction(matchedInstructionOffsets[index]);                    }                    // Visit the instruction, if required.                    if (extraInstructionVisitor != null)                    {                        instruction.accept(clazz, method, codeAttribute, offset, extraInstructionVisitor);                    }                }                // Start matching from the first instruction again next time.                patternInstructionIndex = 0;                matchedArgumentFlags    = 0;                matchedConstantFlags    = 0;            }        }        else        {            // Is this a failed second instruction?            boolean retry = patternInstructionIndex == 1;            // Start matching from the first instruction next time.            patternInstructionIndex = 0;            matchedArgumentFlags    = 0;            matchedConstantFlags    = 0;            // Retry a failed second instruction as a first instruction.            if (retry)            {                instruction.accept(clazz, method, codeAttribute, offset, this);            }        }    }    private boolean patternInstructionsUnmodified()    {        for (int index = 0; index < patternInstructions.length; index++)        {            if (codeAttributeEditor.isModified(matchedInstructionOffsets[index]))            {                return false;            }        }        return true;    }    /**     * This class creates replacement instructions for matched sequences,     * with any matched arguments filled out.     */    private class MyReplacementInstructionFactory    implements    InstructionVisitor    {        private Instruction replacementInstruction;        /**         * Creates the replacement instruction for the given index in the         * instruction sequence.         */        public Instruction create(int index)        {            // Create the instruction.            replacementInstructions[index].accept(null,                                                  null,                                                  null,                                                  matchedInstructionOffsets[index],                                                  this);            // Return it.            return replacementInstruction;        }        // Implementations for InstructionVisitor.        public void visitSimpleInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SimpleInstruction simpleInstruction)        {            replacementInstruction =                new SimpleInstruction(simpleInstruction.opcode,                                      matchedArgument(simpleInstruction.constant));        }        public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)        {            replacementInstruction =                new VariableInstruction(variableInstruction.opcode,                                        matchedArgument(variableInstruction.variableIndex),                                        matchedArgument(variableInstruction.constant));        }        public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)        {            replacementInstruction =                new ConstantInstruction(constantInstruction.opcode,                                        matchedConstantIndex(constantInstruction.constantIndex),                                        matchedArgument(constantInstruction.constant));        }        public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction)        {            replacementInstruction =                new BranchInstruction(branchInstruction.opcode,                                      matchedBranchOffset(offset,                                                          branchInstruction.branchOffset));        }        public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction)        {            replacementInstruction =                new TableSwitchInstruction(tableSwitchInstruction.opcode,                                           matchedArgument(tableSwitchInstruction.defaultOffset),                                           matchedArgument(tableSwitchInstruction.lowCase),                                           matchedArgument(tableSwitchInstruction.highCase),                                           matchedArgument(tableSwitchInstruction.jumpOffsetCount),                                           matchedJumpOffsets(offset,                                                              tableSwitchInstruction.jumpOffsets,                                                              tableSwitchInstruction.jumpOffsetCount));        }        public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)        {            replacementInstruction =                new LookUpSwitchInstruction(lookUpSwitchInstruction.opcode,                                            matchedArgument(lookUpSwitchInstruction.defaultOffset),                                            matchedArgument(lookUpSwitchInstruction.jumpOffsetCount),                                            matchedArguments(lookUpSwitchInstruction.cases,                                                             lookUpSwitchInstruction.jumpOffsetCount),                                            matchedJumpOffsets(offset,                                                               lookUpSwitchInstruction.jumpOffsets,                                                               lookUpSwitchInstruction.jumpOffsetCount));        }    }}

⌨️ 快捷键说明

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