📄 bytecoderewriter.java
字号:
il.setPositions(); if(isMainClass){ //Initializes the __cpuMonitor field to the beginning of the main method if(method.getName().equals("main")){ InstructionList newInitInstructionList = new InstructionList(); //Initializes the field newInitInstructionList.append(factory.createNew("gov.nist.security.bcs.monitor.CPUMonitor")); newInitInstructionList.append(InstructionConstants.DUP); newInitInstructionList.append(factory.createInvoke( "gov.nist.security.bcs.monitor.CPUMonitor", "<init>", Type.VOID, Type.NO_ARGS, org.apache.bcel.Constants.INVOKESPECIAL)); newInitInstructionList.append(factory.createFieldAccess( jclass.getClassName(), "__cpuMonitor", new ObjectType("gov.nist.security.bcs.monitor.CPUMonitor"), Constants.PUTSTATIC)); InstructionHandle start=il.getStart(); il.insert(start,newInitInstructionList); method.setMaxLocals(); method.setMaxStack(); //Field Initialized } } InstructionFinder f = new InstructionFinder(il); int currentPosition = 0; // Find the allocation instructions // (ANEWARRAY, MULTIANEWARRAY, NEW, NEWARRAY). String pat = "AllocationInstruction+"; for (Iterator it = f.search(pat); it.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])it.next(); // the invoke instruction. InstructionHandle last = match[match.length -1]; if(last.getInstruction().toString(cp.getConstantPool()) .indexOf("gov.nist.security.bcs.monitor.CPUMonitor".replace('.','/'))==-1){ InstructionList newInstructionListBefore = new InstructionList(); InstructionList newInstructionListAfter = new InstructionList(); //load the value of the field __cpuMonitor of the main Class /*newInstructionListBefore.append(factory.createFieldAccess( mainClass, "__cpuMonitor", new ObjectType("gov.nist.security.bcs.monitor.CPUMonitor"), Constants.GETSTATIC));*/ newInstructionListAfter.append(factory.createFieldAccess( mainClass, "__cpuMonitor", new ObjectType("gov.nist.security.bcs.monitor.CPUMonitor"), Constants.GETSTATIC)); // Invoke the method of the cpu monitor that checks the memory used /*InvokeInstruction invokeInstructionBefore = factory.createInvoke ("gov.nist.security.bcs.monitor.CPUMonitor", "checkMemoryBefore", BasicType.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL);*/ InvokeInstruction invokeInstructionAfter= factory.createInvoke ("gov.nist.security.bcs.monitor.CPUMonitor", "checkMemoryAfter", BasicType.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL); //newInstructionListBefore.append(invokeInstructionBefore); newInstructionListAfter.append(invokeInstructionAfter); //Put the call just before and after the invocation //il.insert(last,newInstructionListBefore); il.append(last,newInstructionListAfter); method.setMaxLocals(); method.setMaxStack(); } } methods[i]=method.getMethod(); } } //dump the class rewritten with the wrapper initialized jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } } catch(Exception e){ e.printStackTrace(); } } /** * Wrap all basic blocks with instruction counting code. * @param service - the name of the service to wrap * @param isMainClass - boolean telling if it is the mainClass because we don't do the same thing * if it's the main class or a utility class */ protected void instrumentBasicBlocks (String service,boolean isMainClass) { try{ //parse the class to check or rewrite the bytecode JavaClass jclass = new ClassParser(dumpPath).parse(); if(!jclass.isInterface()){ ConstantPoolGen cp = new ConstantPoolGen(jclass.getConstantPool()); // Factory to create new instructions InstructionFactory factory = new InstructionFactory(cp); //if it is the main class if(isMainClass){ //Add a ResourceMonitor field to the class ClassGen cg=new ClassGen(jclass); FieldGen fieldGen=new FieldGen(Constants.ACC_STATIC | Constants.ACC_PUBLIC ,new ObjectType("gov.nist.security.bcs.monitor.ResourceMonitor"),"__resourceMonitor",cp); cg.addField(fieldGen.getField()); //Finalizing the adding of the field jclass=cg.getJavaClass(); //dump the class rewrote with the monitor added jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } org.apache.bcel.classfile.Method methods[]= jclass.getMethods(); for (int i = 0; i< methods.length; i++) { if (!methods[i].isAbstract() && !methods[i].isNative()) { MethodGen method = new MethodGen(methods[i],jclass.getClassName(), cp); InstructionList il = method.getInstructionList(); il.setPositions(); if(isMainClass){ //Initializes the __resourceMonitor field to the beginning of the main method if(method.getName().equals("main")){ InstructionList newInitInstructionList = new InstructionList(); //Initializes the field newInitInstructionList.append(factory.createNew("gov.nist.security.bcs.monitor.ResourceMonitor")); newInitInstructionList.append(InstructionConstants.DUP); newInitInstructionList.append(new PUSH(cp,jclass.getClassName())); newInitInstructionList.append(factory.createInvoke( "gov.nist.security.bcs.monitor.ResourceMonitor", "<init>", Type.VOID, new Type[]{new ObjectType("java.lang.String")}, org.apache.bcel.Constants.INVOKESPECIAL)); newInitInstructionList.append(factory.createFieldAccess( jclass.getClassName(), "__resourceMonitor", new ObjectType("gov.nist.security.bcs.monitor.ResourceMonitor"), Constants.PUTSTATIC)); InstructionHandle start=il.getStart(); il.insert(start,newInitInstructionList); method.setMaxLocals(); method.setMaxStack(); //Field Initialized } //At each beginning of one of the methods from the SipListener interface //we restart the bytecode instructions counting if(method.getName().equals("processRequest") || method.getName().equals("processResponse") || method.getName().equals("processTimeout")){ InstructionList newRestartInstructionList = new InstructionList(); newRestartInstructionList.append(factory.createFieldAccess( mainClass, "__resourceMonitor", new ObjectType("gov.nist.security.bcs.monitor.ResourceMonitor"), Constants.GETSTATIC)); // Invoke the method of the service monitor which counts the instructions InvokeInstruction invokeInstruction = factory.createInvoke ("gov.nist.security.bcs.monitor.ResourceMonitor", "restartCounting", BasicType.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL); newRestartInstructionList.append(invokeInstruction); il.append(il.getStart().getNext(),newRestartInstructionList); method.setMaxLocals(); method.setMaxStack(); //Counting restarted } } InstructionFinder f = new InstructionFinder(il); int currentPosition = 0; // Find the branch instructions (Basic Blocks). String pat = "BranchInstruction+"; for (Iterator it = f.search(pat); it.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])it.next(); // Just before the branch instruction. InstructionHandle last = match[match.length -1]; int length = last.getPosition() - currentPosition; currentPosition = last.getPosition(); InstructionList newInstructionList = new InstructionList(); //load the value of the field __resourceMonitor of the main Class newInstructionList.append(factory.createFieldAccess( mainClass, "__resourceMonitor", new ObjectType("gov.nist.security.bcs.monitor.ResourceMonitor"), Constants.GETSTATIC)); // Push the length of the bytecodes. newInstructionList.append(new PUSH(cp,length).getInstruction()); // Invoke the method of the service monitor which counts the instructions InvokeInstruction invokeInstruction = factory.createInvoke ("gov.nist.security.bcs.monitor.ResourceMonitor", "countInstructions", BasicType.VOID, new Type[]{BasicType.INT}, Constants.INVOKEVIRTUAL); newInstructionList.append(invokeInstruction); il.insert(last,newInstructionList); method.setMaxLocals(); method.setMaxStack(); } //changing of the actual method by the modified method methods[i]=method.getMethod(); } } //dump the class rewrote with the monitor added jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } } catch(FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } /** * This method add all a service monitor to the user's service in the bytecode. * Through this service monitor we will be able to talk to the service Listener * @param service - name of the service */ /*protected void addServiceMonitor(String service){ try{ //parse the class to check or rewrite the bytecode JavaClass jclass = new ClassParser(dumpPath).parse(); if(!jclass.isInterface()){ ConstantPoolGen cp = new ConstantPoolGen(jclass.getConstantPool()); // Factory to create new instructions InstructionFactory factory = new InstructionFactory(cp); //Add the service Monitor static field to the class ClassGen cg=new ClassGen(jclass); FieldGen fieldGen=new FieldGen(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -