codeattrinfoeditor.java
来自「proguard 3.5 java 混淆器 最新 免费 好用的 大家用用试一下吧」· Java 代码 · 共 756 行 · 第 1/2 页
JAVA
756 行
localVariableInfo.u2startpc = remapInstructionOffset(localVariableInfo.u2startpc); } // Implementations for LocalVariableTypeInfoVisitor. public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo) { // Remap the code offset and length. localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startpc, localVariableTypeInfo.u2length); localVariableTypeInfo.u2startpc = remapInstructionOffset(localVariableTypeInfo.u2startpc); } // Small utility methods. /** * Checks if it is possible to modifies the given code without having to * update any offsets. * * @param codeAttrInfo the code to be changed. * @return the new code length. */ private boolean canPerformSimpleReplacements(CodeAttrInfo codeAttrInfo) { if (inserted) { return false; } byte[] code = codeAttrInfo.code; int codeLength = codeAttrInfo.u4codeLength; // Go over all replacement instructions. for (int offset = 0; offset < codeLength; offset++) { // Check if the replacement instruction, if any, has a different // length than the original instruction. Instruction replacementInstruction = replacements[offset]; if (replacementInstruction != null && replacementInstruction.length(offset) != InstructionFactory.create(code, offset).length(offset)) { return false; } } return true; } /** * Modifies the given code without updating any offsets. * * @param codeAttrInfo the code to be changed. */ private void performSimpleReplacements(CodeAttrInfo codeAttrInfo) { byte[] code = codeAttrInfo.code; int codeLength = codeAttrInfo.u4codeLength; // Go over all replacement instructions. for (int offset = 0; offset < codeLength; offset++) { // Overwrite the original instruction with the replacement // instruction if any. Instruction replacementInstruction = replacements[offset]; if (replacementInstruction != null) { replacementInstruction.write(codeAttrInfo, offset); } } } /** * Modifies the given code based on the previously specified changes. * * @param classFile the class file of the code to be changed. * @param methodInfo the method of the code to be changed. * @param codeAttrInfo the code to be changed. * @return the new code length. */ private int moveInstructions(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo) { byte[] oldCode = codeAttrInfo.code; int oldLength = codeAttrInfo.u4codeLength; // Make sure there is a sufficiently large instruction offset map. if (instructionOffsetMap == null || instructionOffsetMap.length < oldLength + 1) { instructionOffsetMap = new int[oldLength + 1]; } // Fill out the offset map that specifies the new instruction offsets, // given their current instruction offsets, by going over the // instructions, deleting and inserting instructions as specified. int oldOffset = 0; int newOffset = 0; boolean lengthIncreased = false; do { // Get the next instruction. Instruction instruction = InstructionFactory.create(oldCode, oldOffset); // Compute the mapping of the instruction. newOffset = mapInstruction(instruction, oldOffset, newOffset); oldOffset += instruction.length(oldOffset); // Is the new instruction exceeding the available space? if (newOffset > oldOffset) { // Remember to create a new code array later on. lengthIncreased = true; } } while (oldOffset < oldLength); // Also add an entry for the first offset after the code. instructionOffsetMap[oldOffset] = newOffset; // Create a new code array if necessary. if (lengthIncreased) { codeAttrInfo.code = new byte[newOffset]; } // Now actually move the instructions based on this map. oldOffset = 0; do { // Get the next instruction. Instruction instruction = InstructionFactory.create(oldCode, oldOffset); // Move the instruction to its new offset. moveInstruction(classFile, methodInfo, codeAttrInfo, oldOffset, instruction); oldOffset += instruction.length(oldOffset); } while (oldOffset < oldLength); return newOffset; } /** * Fills out the instruction offset map for the given instruction with its * new offset. * @param instruction the instruction to be moved. * @param oldOffset the instruction's old offset. * @param newOffset the instruction's new offset. * @return the next new offset. */ private int mapInstruction(Instruction instruction, int oldOffset, int newOffset) { instructionOffsetMap[oldOffset] = newOffset; // Account for the pre-inserted instruction, if any. Instruction preInstruction = preInsertions[oldOffset]; if (preInstruction != null) { newOffset += preInstruction.length(newOffset); } // Account for the replacement instruction, or for the current // instruction, if it shouldn't be deleted. Instruction replacementInstruction = replacements[oldOffset]; if (replacementInstruction != null) { newOffset += replacementInstruction.length(newOffset); } else if (!deleted[oldOffset]) { // Note that the instruction's length may change at its new offset, // e.g. if it is a switch instruction. newOffset += instruction.length(newOffset); } // Account for the post-inserted instruction, if any. Instruction postInstruction = postInsertions[oldOffset]; if (postInstruction != null) { newOffset += postInstruction.length(newOffset); } return newOffset; } /** * Moves the given instruction to its new offset. */ private void moveInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int oldOffset, Instruction instruction) { int newOffset = remapInstructionOffset(oldOffset); // Remap and insert the pre-inserted instruction, if any. Instruction preInstruction = preInsertions[oldOffset]; if (preInstruction != null) { preInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this); preInstruction.write(codeAttrInfo, newOffset); newOffset += preInstruction.length(newOffset); } // Remap and insert the replacment instruction, or the current // instruction, if it shouldn't be deleted. Instruction replacementInstruction = replacements[oldOffset]; if (replacementInstruction != null) { replacementInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this); replacementInstruction.write(codeAttrInfo, newOffset); newOffset += replacementInstruction.length(newOffset); } else if (!deleted[oldOffset]) { instruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this); instruction.write(codeAttrInfo, newOffset); newOffset += instruction.length(newOffset); } // Remap and insert the post-inserted instruction, if any. Instruction postInstruction = postInsertions[oldOffset]; if (postInstruction != null) { postInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this); postInstruction.write(codeAttrInfo, newOffset); } } /** * Adjusts the given jump offsets for the instruction at the given offset. */ private void remapJumpOffsets(int offset, int[] jumpOffsets, int length) { for (int index = 0; index < length; index++) { jumpOffsets[index] = remapBranchOffset(offset, jumpOffsets[index]); } } /** * Computes the new branch offset for the instruction at the given offset * with the given branch offset. */ private int remapBranchOffset(int offset, int branchOffset) { return remapInstructionOffset(offset + branchOffset) - remapInstructionOffset(offset); } /** * Computes the new instruction offset for the instruction at the given offset. */ private int remapInstructionOffset(int offset) { if (offset < 0 || offset > codeLength) { throw new IllegalArgumentException("Invalid instruction offset ["+offset+"] in code with length ["+codeLength+"]"); } return instructionOffsetMap[offset]; } /** * Returns the given list of exceptions, without the ones that have empty * code blocks. */ private int removeEmptyExceptions(ExceptionInfo[] exceptionInfos, int exceptionInfoCount) { // Overwrite all empty exceptions. int newIndex = 0; for (int index = 0; index < exceptionInfoCount; index++) { ExceptionInfo exceptionInfo = exceptionInfos[index]; if (exceptionInfo.u2startpc < exceptionInfo.u2endpc) { exceptionInfos[newIndex++] = exceptionInfo; } } return newIndex; } /** * Returns the given list of line numbers, without the ones that have empty * code blocks. */ private int removeEmptyLineNumbers(LineNumberInfo[] lineNumberInfos, int lineNumberInfoCount, int codeLength) { // Overwrite all empty localVariables. int newIndex = 0; for (int index = 0; index < lineNumberInfoCount; index++) { LineNumberInfo lineNumberInfo = lineNumberInfos[index]; int startpc = lineNumberInfo.u2startpc; if ( startpc < codeLength && (index == 0 || startpc > lineNumberInfos[index-1].u2startpc)) { lineNumberInfos[newIndex++] = lineNumberInfo; } } return newIndex; } /** * Returns the given list of local variables, without the ones that have empty * code blocks. */ private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, int localVariableInfoCount) { // Overwrite all empty exceptions. int newIndex = 0; for (int index = 0; index < localVariableInfoCount; index++) { LocalVariableInfo localVariableInfo = localVariableInfos[index]; if (localVariableInfo.u2length > 0) { localVariableInfos[newIndex++] = localVariableInfo; } } return newIndex; } /** * Returns the given list of local variable types, without the ones that * have empty code blocks. */ private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, int localVariableTypeInfoCount) { // Overwrite all empty exceptions. int newIndex = 0; for (int index = 0; index < localVariableTypeInfoCount; index++) { LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; if (localVariableTypeInfo.u2length > 0) { localVariableTypeInfos[newIndex++] = localVariableTypeInfo; } } return newIndex; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?