⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bytecoderewriter.java

📁 First of all, the Applet-phone is a SIP User-Agent with audio and text messaging capabilities. But
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            logger.debug("Checking bytecode for permission : "+permissionName);                   if(methodsToCheck!=null && methodsToCheck.size()!=0)                //check the bytecode and add security hooks                StackPermissionsRespected=stackPerm.checkSipPermissions(methodsToCheck,permissionTag.getName());                                                                  }                return StackPermissionsRespected;            }              /**     * Add runtime bytecode security hooks to the class     * @param method - the original method to modify      * @param handles - the handles which allows to know where to add the code     * @param cp - the constantPoolGen needed to create any piece of code     * @param permissionName - the permission name(URI or Domain or wildcard) to test against at runtime     * @param methodTag - the method tag, of the method we want to check, extracted from the permissions.xml file     * (needed to configure automatically the bytecode rewriting stuff)      * @param argumentChecking - If we have to check a permission before runtime     * We don't need to check the arguments of the permission otherwise we need to check them     * @return the new Method with our bytecode added     */    public MethodGen addSecurityHooks(                                          MethodGen method,                                          InstructionHandle[] handles,                                          ConstantPoolGen cp,                                          String permissionName,                                          MethodTag methodTag,                                          boolean argumentChecking){        int instructionCount=0;        //Get the instruction List from the bytecode method        InstructionList il = method.getInstructionList();           // Factory to create new instructions        InstructionFactory factory = new InstructionFactory(cp);        //New InstructionList that will be some of the bytecode added to the service        InstructionList newInstructionList = new InstructionList();                //We get the bytecode tag from the method tag to configure        //the bytecode rewriting stuff        ByteCodeTag byteCodeTag=methodTag.getByteCodeTag();        //Get the arguments of the method to invoke        Vector bc_args=byteCodeTag.getArguments();                             //Get the vector of arguments of the method we want to check        Vector arguments=methodTag.getArguments();                  newInstructionList.append(factory.createFieldAccess(                                    mainClass,                                    "__"+byteCodeTag.getClassToInvoke().replace('.','_'),                                    new ObjectType(byteCodeTag.getClassToInvoke()),                                    Constants.GETSTATIC));                    //If we have to check a permission before runtime        //We just create a Permission of the type needed        //and put it in the service's bytecode        if(!argumentChecking){            newInstructionList.append(factory.createNew(methodTag.getPermissionName()));            newInstructionList.append(InstructionConstants.DUP);            newInstructionList.append(new PUSH(cp,methodTag.getPermissionAction()));            newInstructionList.append(factory.createInvoke(                                        methodTag.getPermissionName(),                                        "<init>",                                        Type.VOID,                                        new Type[]{new ObjectType("java.lang.String")},                                        Constants.INVOKESPECIAL));                                                            }        else{                                     //Load the value of the arguments of the method to check                                    InstructionList argsInstructionList=new InstructionList();            InstructionHandle handle=handles[handles.length -1];            //logger.debug(handle.getInstruction().toString());            //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),            //sipush(load an integer)            //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            //In theory those are the only instructions that load a value on the stack                           for(int i=0;i<bc_args.size();i++){                boolean found=false;                                                    boolean foundInvokeSpecialInit=false;                while(!found){                                        handle=handle.getPrev();                    instructionCount++;                    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;                        }                    }                    //Add the instruction to load the value of the argument                     //of the method to check on the java Stack                    argsInstructionList.insert(instruction);                                }                                                                            }            //Add the List of instructions to load the arguments of the method             //to the list of instructions that will be added to the bytecode            newInstructionList.append(argsInstructionList);        }        //Specify the types of the method's arguments         //through the ByteCode Tag extracted from the permissions.xml file                    Type[] args_types=new Type[bc_args.size()];                                for(int i=0;i<bc_args.size();i++)            args_types[i]=getBCELType(((ByteCodeArgumentTag)bc_args.get(i)).getClassName());                                //Create a call to the method which will do the check        newInstructionList.append(factory.createInvoke(                                        byteCodeTag.getClassToInvoke(),                                        byteCodeTag.getMethod(), Type.VOID,                                        args_types,                                        org.apache.bcel.Constants.INVOKEVIRTUAL));                //Insert a test to check if the call to the method         //is true. If yes, we go out of the method in throwing an AccessControlException        //else we continue the normal execution and so we go just at the instuction        //loading the first parameter of the method we want to check        /*newInstructionList.append(new IFNE(getPreviousInstruction(handles[handles.length -1],arguments.size())));        newInstructionList.append(factory.createNew("java.security.AccessControlException"));        newInstructionList.append(InstructionConstants.DUP);        newInstructionList.append(new PUSH(cp,"User has not the rigths"));        newInstructionList.append(factory.createInvoke(                                        "java.security.AccessControlException",                                        "<init>",                                        Type.VOID,                                        new Type[]{new ObjectType("java.lang.String")},                                        org.apache.bcel.Constants.INVOKESPECIAL));                                                        newInstructionList.append(new ATHROW());*/        //insert our runtime security check code into the user's service        //just before the arguments of the method we want to check are loaded        il.insert(getPreviousInstruction(handles[handles.length -1],instructionCount),newInstructionList);                return method;                    }            /**     * get the BCEL type of the type in parameter      * if the type is an Object Type or a basic type(int, float,...)     * @param argumentType - the string which stands for the type     * @return the BCEL Type     */    public static Type getBCELType(String argumentType){        if(argumentType.equals("int"))            return Type.INT;        if(argumentType.equals("boolean"))            return Type.BOOLEAN;        if(argumentType.equals("byte"))            return Type.BYTE;        if(argumentType.equals("char"))            return Type.CHAR;        if(argumentType.equals("double"))            return Type.DOUBLE;        if(argumentType.equals("float"))            return Type.FLOAT;        if(argumentType.equals("long"))            return Type.LONG;        if(argumentType.equals("short"))            return Type.SHORT;                return new ObjectType(argumentType);    }        /** Get the Nth previous instructions of the instruction handle in parameter     * @param instructionHandle - he instruction handle of which we want to know the Nth previous instruction     * (example : if N=5, we want to know the 5th previous instruction before the instructionhandle     *  in parameter)     * @param N - the number of previous instruction     * @return the Nth previous instruction     */    public static InstructionHandle getPreviousInstruction(InstructionHandle instructionHandle,int N){                InstructionHandle previousHandle=instructionHandle;        for(int i=0; i<N; i++)                        previousHandle=previousHandle.getPrev();                return previousHandle;    }    /**     * We are looking for piece of code we added in the method addSecurityHooks     * the ifne offset will be positioned on the first argument of the method to check     * But if added many piece of code they will be all     * positioned on the first argument of the method to check     * And so only the first check will be made, all the others will be skipped     * we want to fix that      * @param the original method to modify      * @param the handles which allows to know where to add the code     * @param the constantPoolGen needed to create a piece of code     * @param the permission name(URI or Domain or wildcard) to test against at runtime     * @param the method tag, of the method we want to check, extracted from the permissions.xml file     * (needed to configure automatically the bytecode rewriting stuff)      * @return the new Method with our bytecode added     */    /*public org.apache.bcel.classfile.Method checkMultipleCheckOnMethod(                                          MethodGen method,                                          InstructionHandle[] handles,                                          ConstantPoolGen cp,                                          String permissionName,                                          MethodTag methodTag,                                          boolean argumentChecking){         boolean stop=false;                                                 int count=0;                //Get the vector of arguments of the method we want to check        Vector arguments=methodTag.getArguments();                  InstructionHandle handle=findFirstArgument(handles[handles.length -1],arguments.size());        InstructionHandle startHandle=handle;                //We are looking for piece of code we added         //the ifne offset will be positioned on the        //first argument of the method to check        //But if added many piece of code they will be all        //positioned on the first argument of the method to check            try{            while(!stop){                                                      handle=handle.getPrev();                count++;                //if just before the handle we do not find a athrow instruction                //we can stop the process because                 //there is no or no more piece of code added                if(count==1){                    if(handle.getInstruction().toString().indexOf("athrow")==-1)                        stop=true;                                }                //If it's the fifth previous instruction and                //if it's not the good one we stop the process                if(count==5){                    if(handle.getInstruction().toString(cp.getConstantPool()).indexOf("new java/security/AccessControlException")==-1)                                        stop=true;                                }                //If it's the sixth previous instruction and                //if it's the ifne instruction we affect the new offset target                //to the start handle

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -