📄 bytecoderewriter.java
字号:
//and if(count==6){ if(handle.getInstruction().toString(cp.getConstantPool()).indexOf("ifne")!=-1){ ((IFNE)handle.getInstruction()).setTarget(startHandle); boolean found=false; //we are looking for the getStatic of a SecurityWrapper instruction //we will put it in the startHandle and restart the process while(!found){ handle=handle.getPrev(); //If it's the instruction getStatic of one of all SecurityWrapper //we stop the search for(int i=0;i<securityWrapperList.size();i++){ String securityWrapperName=(String)securityWrapperList.elementAt(i); if(handle.getInstruction().toString(cp.getConstantPool()).indexOf("getstatic ")!=-1 && handle.getInstruction().toString(cp.getConstantPool()).indexOf(mainClass)!=-1 && handle.getInstruction().toString(cp.getConstantPool()).indexOf("__"+securityWrapperName.replace('.','_'))!=-1){ found=true; startHandle=handle; } } } //we restart the process count=0; } else stop=true; } } } catch(Exception e){ e.printStackTrace(); } method.setMaxStack(); method.setMaxLocals(); return method.getMethod(); }*/ /** * For the instructionHandle in parameter which MUST be a method call * this method find the InstructionHandle of the firstArgument of this method call * @param instructionHandle - the instructionHandle which MUST be a method call * @param numberOfArguments - the numer of parameter to this method call * @return InstructionHandle of the firstArgument of this method call */ protected InstructionHandle findFirstArgument(InstructionHandle instructionHandle,int numberOfArguments){ InstructionHandle handle=instructionHandle; //For each argument of the permissions.xml file //we check the instruction until we found the following instructions : //ldc(load a string), aload(load the value of an attribute), //getstatic(load a static value either by an attribute or by a method) //or new(init a new field) but this is a special case //when you do a new : the instructions in the bytecode are //starting with an invokespecial <init> and finishing with a new instruction //so this is why it's a little bit tricky //it's possible there is some other instructions that load a value on the stack //but as I don't them, i am waiting to get an error to add some other instructions to check for(int i=0;i<numberOfArguments;i++){ boolean found=false; boolean foundInvokeSpecialInit=false; while(!found){ handle=handle.getPrev(); Instruction instruction=handle.getInstruction(); //logger.debug(instruction.toString()); if(!foundInvokeSpecialInit){ if(handle.toString().indexOf("ldc")!=-1 || handle.toString().indexOf("aload")!=-1 || handle.toString().indexOf("sipush")!=-1 || handle.toString().indexOf("getstatic")!=-1){ found=true; } if(handle.toString().indexOf("invokespecial")!=-1 && handle.toString().indexOf("<init>")!=-1){ foundInvokeSpecialInit=true; } } else{ if(handle.toString().indexOf("new")!=-1){ found=true; foundInvokeSpecialInit=false; } } } } return handle; } /** * This method get all the securityWrapper that have been defined/called in the permissions file.xml * without any redondancy * @return List of all the SecurityWrapper */ protected Vector getAllSecurityWrappers(){ Vector securityWrapperList= new Vector(); Enumeration keys=sipPermissions.keys(); while(keys.hasMoreElements()){ PermissionTag permissionTag=(PermissionTag)sipPermissions.get(keys.nextElement()); Vector methodsToCheck=permissionTag.getMethodsToCheck(); for(int i=0;i<methodsToCheck.size();i++){ ByteCodeTag byteCodeTag=((MethodTag)methodsToCheck.elementAt(i)).getByteCodeTag(); String securityWrapperName=byteCodeTag.getClassToInvoke().replace('.','_'); if(securityWrapperList==null || securityWrapperList.size()<=0) securityWrapperList.addElement(securityWrapperName); else{ int j=0; boolean found=false; while(j<securityWrapperList.size() && !found){ if(((String)securityWrapperList.elementAt(j)).equals(securityWrapperName)){ found=true; } j++; } if(!found) securityWrapperList.addElement(securityWrapperName); } } } /*System.out.println(); for(int i=0;i<securityWrapperList.size();i++) System.out.println(securityWrapperList.elementAt(i));*/ return securityWrapperList; } /** * This method add all the security wrapppers in parameter to the user's service in the bytecode. * Through these security wrappers we will be able to check the permissions and so stop the service * @param service - name of the service * @param securityWrapperList - List of all the security Wrappers */ protected void addSecurityWrappers(String service,Vector securityWrapperList){ 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 security Wrappers to the class for(int i=0; i<securityWrapperList.size();i++){ String securityWrapperName=(String)securityWrapperList.elementAt(i); //Add a SecurityWrapper static field to the class ClassGen cg=new ClassGen(jclass); FieldGen fieldGen=new FieldGen( Constants.ACC_STATIC | Constants.ACC_PUBLIC , new ObjectType(securityWrapperName.replace('_','.')), "__"+securityWrapperName, cp); cg.addField(fieldGen.getField()); //Finalizing the adding of the field jclass=cg.getJavaClass(); //dump the class rewritten with the wrapper 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(); //Initializes the __securityWrappper field to the beginning of the main method if(method.getName().equals("main")){ //Initializes the security Wrappers for(int j=0; j<securityWrapperList.size();j++){ String securityWrapperName=(String)securityWrapperList.elementAt(j); InstructionList newInitInstructionList = new InstructionList(); //Initializes the field newInitInstructionList.append(factory.createNew(securityWrapperName.replace('_','.'))); newInitInstructionList.append(InstructionConstants.DUP); newInitInstructionList.append(factory.createInvoke( securityWrapperName.replace('_','.'), "<init>", Type.VOID, Type.NO_ARGS, org.apache.bcel.Constants.INVOKESPECIAL)); newInitInstructionList.append(factory.createFieldAccess( jclass.getClassName(), "__"+securityWrapperName, new ObjectType(securityWrapperName.replace('_','.')), Constants.PUTSTATIC)); InstructionHandle start=il.getStart(); il.insert(start,newInitInstructionList); method.setMaxLocals(); method.setMaxStack(); //Field Initialized } } methods[i]=method.getMethod(); } } //dump the class rewritten with the wrapper initialized jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } } catch(Exception e){ e.printStackTrace(); } } /** * This method add the cpu resource monitor to the user's service in the bytecode. * Through this monitor we will be able to check the memory used for the service * @param service - name of the service * @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 addCPUMonitor(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); //Add the cpu resource monitor to the class if(isMainClass){ //Add a cpu resource monitor static 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.CPUMonitor"), "__cpuMonitor", cp); cg.addField(fieldGen.getField()); //Finalizing the adding of the field jclass=cg.getJavaClass(); //dump the class rewritten with the wrapper 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -