📄 bytecoderewriter.java
字号:
/* * ByteCodeRewriter.java * * Created on Mar 10, 2004 * */package gov.nist.security.bcs;import gov.nist.security.permissions.SipPermissionChecker;import gov.nist.security.permissions.parser.ByteCodeArgumentTag;import gov.nist.security.permissions.parser.ByteCodeTag;import gov.nist.security.permissions.parser.InheritanceTag;import gov.nist.security.permissions.parser.MethodTag;import gov.nist.security.permissions.parser.PermissionTag;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.util.Enumeration;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Vector;import org.apache.bcel.Constants;import org.apache.bcel.classfile.ClassParser;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.generic.BasicType;import org.apache.bcel.generic.ClassGen;import org.apache.bcel.generic.ConstantPoolGen;import org.apache.bcel.generic.FieldGen;import org.apache.bcel.generic.Instruction;import org.apache.bcel.generic.InstructionConstants;import org.apache.bcel.generic.InstructionFactory;import org.apache.bcel.generic.InstructionHandle;import org.apache.bcel.generic.InstructionList;import org.apache.bcel.generic.InvokeInstruction;import org.apache.bcel.generic.MethodGen;import org.apache.bcel.generic.ObjectType;import org.apache.bcel.generic.PUSH;import org.apache.bcel.generic.Type;import org.apache.bcel.util.InstructionFinder;import org.apache.log4j.Logger;/** * Class that will rewrite the bytecode * @author Jean Deruelle <jean.deruelle@nist.gov> * * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a> */public class ByteCodeRewriter { /**log4j logging*/ static private Logger logger = Logger.getLogger(ByteCodeRewriter.class); /**list of the permissions to check upon the service*/ private Hashtable sipPermissions=null; /**the upload directory of the service*/ private String uploadDirectory=null; /**a classloader loads recursively all the classes that a class need but we want to rewrite only the first one so when the first class (the one we want to rewite) is loaded we put this flag to true and before reloading another class we have to put it to false*/ public static boolean find; /**the sip URI with which the services of the user will register with our stateless proxy*/ private String userServiceSipURI=null; /**the mainClass of the service to load*/ private String mainClass=null; private String dumpPath=null; /** Creates a new instance of SafeClassLoader * @param urls - the urls to load * @param sipPermissions - the sip permissions defined in the permissions.xml file * @param uploadDirectory - the upload Directory * @param parent - the parent ClassLoader * @param mainClass - the mainClass of the service * @param userServiceSipURI - the sip URI with which the services of the user will register with our stateless proxy */ public ByteCodeRewriter(//URL[] urls, Hashtable sipPermissions, String uploadDirectory, //java.lang.ClassLoader parent, java.lang.String mainClass, java.lang.String userServiceSipURI) { //super(urls,parent); this.sipPermissions=sipPermissions; this.uploadDirectory=uploadDirectory; this.mainClass=mainClass; this.userServiceSipURI=userServiceSipURI; //find=false; } /** * Override the load Class from the super class URLClassLoader * to add some security check before runtime and for the runtime, * to add a service monitor and a resource monitor * in using the bytecode rewriting technique * @param name - the name of the class * @return null if the class has not the rigths to be executed * else we return the class loaded */ public Class rewriteClass(String name){ Class userClass=null; try{ //we put this boolean variable to restrict the bytecode rewriting //to the first class //(because if we don't put it, it will try to rewrite //all the class loaded by this class) //if(!find){ //We dump the file and we will worked on the file dumped try{ dumpPath= uploadDirectory+"dump"+File.separatorChar+name.replace('.',File.separatorChar)+".class"; if(!new File(dumpPath).exists()){ JavaClass jclass = new ClassParser( uploadDirectory.concat( name.replace('.',File.separatorChar))+".class") .parse(); ConstantPoolGen cp = new ConstantPoolGen(jclass.getConstantPool()); // Dump the class to the directory dump with the same name jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } } catch(FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } //find=true; checkInheritance(name); enforceSecurity(dumpPath); if(mainClass!=null){ //if it is the main class, we add a service monitor if(mainClass.equals(name)){ addSecurityWrappers(name,getAllSecurityWrappers()); //put a resource monitor instrumentBasicBlocks(name,true); logger.warn("resource monitor added"); //put a cpu monitor addCPUMonitor(name,true); logger.warn("CPU monitor added"); } //we call the service monitor of the main class else{ //put a resource monitor instrumentBasicBlocks(name,false); logger.warn("resource monitor added"); //put a cpu monitor addCPUMonitor(name,false); //put a placeholder logger.warn("CPU monitor added"); } // copyEvent(name); //add serviceMonitor //addServiceMonitor(name); logger.warn("Service monitor added"); } //and we load the service //userClass=super.loadClass(name); //} //else //userClass=super.loadClass(name); return userClass; } catch(NoClassDefFoundError error){ logger.error(error.toString()); return null; } } /** * Copy the parameters of the SipListener Methods into a placeHolder * @param name - the name of the file to check */ protected void copyEvent(String name){ JavaClass jclass = null; try{ jclass = new ClassParser(dumpPath).parse(); } catch(IOException ioe){ ioe.printStackTrace(); } /*Class clazz=null; try{ clazz=Class.forName(name); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } Class[] interfaces=clazz.getInterfaces(); boolean hasSipListenerInterface=false; for(int i=0;i<interfaces.length;i++){ if(interfaces[i].getName().equalsIgnoreCase("javax.sip.SipListener")){ hasSipListenerInterface=true; break; } } if(!hasSipListenerInterface) return; else{*/ ConstantPoolGen cp = new ConstantPoolGen(jclass.getConstantPool()); 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); //Do the check if(method.getName().equals("processRequest")){ //Get the instruction List from the bytecode method InstructionList il = method.getInstructionList(); il.setPositions(); // Factory to create new instructions InstructionFactory factory = new InstructionFactory(cp); InstructionList newInitInstructionList = new InstructionList(); //Put the value of the RequestEvent //in the RequestEvent field of the place holder newInitInstructionList.append(factory.createLoad( Type.OBJECT, 1)); newInitInstructionList.append(factory.createFieldAccess( "gov.nist.security.bcs.wrapper.PlaceHolder", "requestEvent", new ObjectType("javax.sip.RequestEvent"), Constants.PUTSTATIC)); newInitInstructionList.append(InstructionConstants.ACONST_NULL); newInitInstructionList.append(factory.createFieldAccess( "gov.nist.security.bcs.wrapper.PlaceHolder", "responseEvent", new ObjectType("javax.sip.ResponseEvent"), Constants.PUTSTATIC)); newInitInstructionList.append(InstructionConstants.ACONST_NULL); newInitInstructionList.append(factory.createFieldAccess( "gov.nist.security.bcs.wrapper.PlaceHolder", "timeoutEvent", new ObjectType("javax.sip.TimeoutEvent"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -