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 + -
显示快捷键?