codeattrinfoeditor.java
来自「proguard 3.5 java 混淆器 最新 免费 好用的 大家用用试一下吧」· Java 代码 · 共 756 行 · 第 1/2 页
JAVA
756 行
/* $Id: CodeAttrInfoEditor.java,v 1.14.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.attribute.*;import proguard.classfile.attribute.annotation.*;import proguard.classfile.instruction.*;import proguard.classfile.visitor.*;/** * This AttrInfoVisitor accumulates specified changes to code, and then applies * these accumulated changes to the code attributes that it visits. * * @author Eric Lafortune */public class CodeAttrInfoEditor implements AttrInfoVisitor, InstructionVisitor, ExceptionInfoVisitor, LineNumberInfoVisitor, LocalVariableInfoVisitor, LocalVariableTypeInfoVisitor{ private int codeLength; private boolean modified; private boolean inserted; /*private*/public Instruction[] preInsertions; /*private*/public Instruction[] replacements; /*private*/public Instruction[] postInsertions; private boolean[] deleted; private int[] instructionOffsetMap; private StackSizeUpdater stackSizeUpdater; /** * Creates a new CodeAttrInfoEditor. * @param codeLength an estimate of the maximum length of all the code that * will be edited. */ public CodeAttrInfoEditor(int codeLength) { this.codeLength = codeLength; preInsertions = new Instruction[codeLength]; replacements = new Instruction[codeLength]; postInsertions = new Instruction[codeLength]; deleted = new boolean[codeLength]; stackSizeUpdater = new StackSizeUpdater(codeLength); } /** * Resets the accumulated code changes. * @param codeLength the length of the code that will be edited next. */ public void reset(int codeLength) { this.codeLength = codeLength; // Try to reuse the previous arrays. if (preInsertions.length < codeLength) { preInsertions = new Instruction[codeLength]; replacements = new Instruction[codeLength]; postInsertions = new Instruction[codeLength]; deleted = new boolean[codeLength]; } else { for (int index = 0; index < codeLength; index++) { preInsertions[index] = null; replacements[index] = null; postInsertions[index] = null; deleted[index] = false; } } modified = false; inserted = false; } /** * Remembers to place the given instruction right before the instruction * at the given offset. * @param instructionOffset the offset of the instruction. * @param instruction the new instruction. */ public void insertBeforeInstruction(int instructionOffset, Instruction instruction) { if (instructionOffset < 0 || instructionOffset >= codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } preInsertions[instructionOffset] = instruction; modified = true; inserted = true; } /** * Remembers to replace the instruction at the given offset by the given * instruction. * @param instructionOffset the offset of the instruction to be replaced. * @param instruction the new instruction. */ public void replaceInstruction(int instructionOffset, Instruction instruction) { if (instructionOffset < 0 || instructionOffset >= codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } replacements[instructionOffset] = instruction; modified = true; } /** * Remembers to place the given instruction right after the instruction * at the given offset. * @param instructionOffset the offset of the instruction. * @param instruction the new instruction. */ public void insertAfterInstruction(int instructionOffset, Instruction instruction) { if (instructionOffset < 0 || instructionOffset >= codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } postInsertions[instructionOffset] = instruction; modified = true; inserted = true; } /** * Remembers to delete the instruction at the given offset. * @param instructionOffset the offset of the instruction to be deleted. */ public void deleteInstruction(int instructionOffset) { if (instructionOffset < 0 || instructionOffset >= codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]"); } deleted[instructionOffset] = true; modified = true; inserted = true; } /** * Returns whether the instruction at the given offset has been modified * in any way. */ public boolean isModified(int instructionOffset) { return preInsertions[instructionOffset] != null || replacements[instructionOffset] != null || postInsertions[instructionOffset] != null || deleted[instructionOffset]; } /** * Returns whether any instruction has been modified in any way. */ public boolean isModified() { return modified; } // Implementations for AttrInfoVisitor. public void visitUnknownAttrInfo(ClassFile classFile, UnknownAttrInfo unknownAttrInfo) {} public void visitInnerClassesAttrInfo(ClassFile classFile, InnerClassesAttrInfo innerClassesAttrInfo) {} public void visitEnclosingMethodAttrInfo(ClassFile classFile, EnclosingMethodAttrInfo enclosingMethodAttrInfo) {} public void visitConstantValueAttrInfo(ClassFile classFile, FieldInfo fieldInfo, ConstantValueAttrInfo constantValueAttrInfo) {} public void visitExceptionsAttrInfo(ClassFile classFile, MethodInfo methodInfo, ExceptionsAttrInfo exceptionsAttrInfo) {} public void visitSourceFileAttrInfo(ClassFile classFile, SourceFileAttrInfo sourceFileAttrInfo) {} public void visitSourceDirAttrInfo(ClassFile classFile, SourceDirAttrInfo sourceDirAttrInfo) {} public void visitDeprecatedAttrInfo(ClassFile classFile, DeprecatedAttrInfo deprecatedAttrInfo) {} public void visitSyntheticAttrInfo(ClassFile classFile, SyntheticAttrInfo syntheticAttrInfo) {} public void visitSignatureAttrInfo(ClassFile classFile, SignatureAttrInfo signatureAttrInfo) {} public void visitRuntimeVisibleAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleAnnotationsAttrInfo runtimeVisibleAnnotationsAttrInfo) {} public void visitRuntimeInvisibleAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleAnnotationsAttrInfo runtimeInvisibleAnnotationsAttrInfo) {} public void visitRuntimeVisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleParameterAnnotationsAttrInfo runtimeVisibleParameterAnnotationsAttrInfo) {} public void visitRuntimeInvisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleParameterAnnotationsAttrInfo runtimeInvisibleParameterAnnotationsAttrInfo) {} public void visitAnnotationDefaultAttrInfo(ClassFile classFile, AnnotationDefaultAttrInfo annotationDefaultAttrInfo) {} public void visitCodeAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo) { // Avoid doing any work if nothing is changing anyway. if (!modified) { return; } // Check if we can perform a faster simple replacement of instructions. if (canPerformSimpleReplacements(codeAttrInfo)) { // Simply overwrite the instructions. performSimpleReplacements(codeAttrInfo); } else { // Move and remap the instructions. codeAttrInfo.u4codeLength = moveInstructions(classFile, methodInfo, codeAttrInfo); // Remap the exception table. codeAttrInfo.exceptionsAccept(classFile, methodInfo, this); // Remap the line number table and the local variable table. codeAttrInfo.attributesAccept(classFile, methodInfo, this); // Remove exceptions with empty code blocks. codeAttrInfo.u2exceptionTableLength = removeEmptyExceptions(codeAttrInfo.exceptionTable, codeAttrInfo.u2exceptionTableLength); } // Update the maximum stack size. stackSizeUpdater.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo); } // Implementations for LineNumberInfoVisitor. public void visitLineNumberTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberTableAttrInfo lineNumberTableAttrInfo) { // Remap all line number table entries. lineNumberTableAttrInfo.lineNumbersAccept(classFile, methodInfo, codeAttrInfo, this); // Remove line numbers with empty code blocks. lineNumberTableAttrInfo.u2lineNumberTableLength = removeEmptyLineNumbers(lineNumberTableAttrInfo.lineNumberTable, lineNumberTableAttrInfo.u2lineNumberTableLength, codeAttrInfo.u4codeLength); } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTableAttrInfo localVariableTableAttrInfo) { // Remap all local variable table entries. localVariableTableAttrInfo.localVariablesAccept(classFile, methodInfo, codeAttrInfo, this); // Remove local variables with empty code blocks. localVariableTableAttrInfo.u2localVariableTableLength = removeEmptyLocalVariables(localVariableTableAttrInfo.localVariableTable, localVariableTableAttrInfo.u2localVariableTableLength); } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableTypeTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeTableAttrInfo localVariableTypeTableAttrInfo) { // Remap all local variable table entries. localVariableTypeTableAttrInfo.localVariablesAccept(classFile, methodInfo, codeAttrInfo, this); // Remove local variables with empty code blocks. localVariableTypeTableAttrInfo.u2localVariableTypeTableLength = removeEmptyLocalVariableTypes(localVariableTypeTableAttrInfo.localVariableTypeTable, localVariableTypeTableAttrInfo.u2localVariableTypeTableLength); } // Implementations for InstructionVisitor. public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction) {} public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction) {} 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) { // Adjust the branch offset. branchInstruction.branchOffset = remapBranchOffset(offset, branchInstruction.branchOffset); } public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction) { // Adjust the default jump offset. tableSwitchInstruction.defaultOffset = remapBranchOffset(offset, tableSwitchInstruction.defaultOffset); // Adjust the jump offsets. remapJumpOffsets(offset, tableSwitchInstruction.jumpOffsets, tableSwitchInstruction.highCase - tableSwitchInstruction.lowCase + 1); } public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { // Adjust the default jump offset. lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset, lookUpSwitchInstruction.defaultOffset); // Adjust the jump offsets. remapJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets, lookUpSwitchInstruction.jumpOffsetCount); } // Implementations for ExceptionInfoVisitor. public void visitExceptionInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, ExceptionInfo exceptionInfo) { // Remap the code offsets. Note that the instruction offset map also has // an entry for the first offset after the code, for u2endpc. exceptionInfo.u2startpc = remapInstructionOffset(exceptionInfo.u2startpc); exceptionInfo.u2endpc = remapInstructionOffset(exceptionInfo.u2endpc); exceptionInfo.u2handlerpc = remapInstructionOffset(exceptionInfo.u2handlerpc); } // Implementations for LineNumberInfoVisitor. public void visitLineNumberInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberInfo lineNumberInfo) { // Remap the code offset. lineNumberInfo.u2startpc = remapInstructionOffset(lineNumberInfo.u2startpc); } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo) { // Remap the code offset and length. localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startpc, localVariableInfo.u2length);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?