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

📄 pass3averifier.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
				int maxminus2 =  max_locals()-2;
				if (idx > maxminus2){
					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'.");
				}
			}
		}
		
		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitDSTORE(DSTORE o){
			int idx = o.getIndex();
			if (idx < 0){
				constraintViolated(o, "Index '"+idx+"' must be non-negative. [Constraint by JustIce as an analogon to the single-slot xLOAD/xSTORE instructions; may not happen anyway.]");
			}
			else{
				int maxminus2 =  max_locals()-2;
				if (idx > maxminus2){
					constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'.");
				}
			}
		}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitLOOKUPSWITCH(LOOKUPSWITCH o){
			int[] matchs = o.getMatchs();
			int max = Integer.MIN_VALUE;
			for (int i=0; i<matchs.length; i++){
				if (matchs[i] == max && i != 0){
					constraintViolated(o, "Match '"+matchs[i]+"' occurs more than once.");
				}
				if (matchs[i] < max){
					constraintViolated(o, "Lookup table must be sorted but isn't.");
				}
				else{
					max = matchs[i];
				}
			}
		}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitTABLESWITCH(TABLESWITCH o){ 	
			// "high" must be >= "low". We cannot check this, as BCEL hides
			// it from us.
		}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitPUTSTATIC(PUTSTATIC o){
			String field_name = o.getFieldName(cpg);
			JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
			Field[] fields = jc.getFields();
			Field f = null;
			for (int i=0; i<fields.length; i++){
				if (fields[i].getName().equals(field_name)){
					f = fields[i];
					break;
				}
			}
			if (f == null){
				throw new AssertionViolatedException("Field not found?!?");
			}

			if (f.isFinal()){
				if (!(myOwner.getClassName().equals(o.getClassType(cpg).getClassName()))){
					constraintViolated(o, "Referenced field '"+f+"' is final and must therefore be declared in the current class '"+myOwner.getClassName()+"' which is not the case: it is declared in '"+o.getClassType(cpg).getClassName()+"'.");
				}
			}

			if (! (f.isStatic())){
				constraintViolated(o, "Referenced field '"+f+"' is not static which it should be.");
			}

			String meth_name = Repository.lookupClass(myOwner.getClassName()).getMethods()[method_no].getName();

			// If it's an interface, it can be set only in <clinit>.
			if ((!(jc.isClass())) && (!(meth_name.equals(Constants.STATIC_INITIALIZER_NAME)))){
				constraintViolated(o, "Interface field '"+f+"' must be set in a '"+Constants.STATIC_INITIALIZER_NAME+"' method.");
			}
		}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitGETSTATIC(GETSTATIC o){
			String field_name = o.getFieldName(cpg);
			JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
			Field[] fields = jc.getFields();
			Field f = null;
			for (int i=0; i<fields.length; i++){
				if (fields[i].getName().equals(field_name)){
					f = fields[i];
					break;
				}
			}
			if (f == null){
				throw new AssertionViolatedException("Field not found?!?");
			}

			if (! (f.isStatic())){
				constraintViolated(o, "Referenced field '"+f+"' is not static which it should be.");
			}
		}

		/* Checks if the constraints of operands of the said instruction(s) are satisfied. */
		//public void visitPUTFIELD(PUTFIELD o){
			// for performance reasons done in Pass 3b
		//}
		
		/* Checks if the constraints of operands of the said instruction(s) are satisfied. */
		//public void visitGETFIELD(GETFIELD o){
			// for performance reasons done in Pass 3b
		//}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitINVOKEINTERFACE(INVOKEINTERFACE o){
			// INVOKEINTERFACE is a LoadClass; the Class where the referenced method is declared in,
			// is therefore resolved/verified.
			// INVOKEINTERFACE is an InvokeInstruction, the argument and return types are resolved/verified,
			// too. So are the allowed method names.
			String classname = o.getClassName(cpg);
			JavaClass jc = Repository.lookupClass(classname);
			Method[] ms = jc.getMethods();
			Method m = null;
			for (int i=0; i<ms.length; i++){
				if ( (ms[i].getName().equals(o.getMethodName(cpg))) &&
				     (Type.getReturnType(ms[i].getSignature()).equals(o.getReturnType(cpg))) &&
				     (objarrayequals(Type.getArgumentTypes(ms[i].getSignature()), o.getArgumentTypes(cpg))) ){
					m = ms[i];
					break;
				}
			}
			if (m == null){
				constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature not found in class '"+jc.getClassName()+"'. The native verfier does allow the method to be declared in some superinterface, which the Java Virtual Machine Specification, Second Edition does not.");
			}
			if (jc.isClass()){
				constraintViolated(o, "Referenced class '"+jc.getClassName()+"' is a class, but not an interface as expected.");
			}
		}

		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitINVOKESPECIAL(INVOKESPECIAL o){
			// INVOKESPECIAL is a LoadClass; the Class where the referenced method is declared in,
			// is therefore resolved/verified.
			// INVOKESPECIAL is an InvokeInstruction, the argument and return types are resolved/verified,
			// too. So are the allowed method names.
			String classname = o.getClassName(cpg);
			JavaClass jc = Repository.lookupClass(classname);
			Method[] ms = jc.getMethods();
			Method m = null;
			for (int i=0; i<ms.length; i++){
				if ( (ms[i].getName().equals(o.getMethodName(cpg))) &&
				     (Type.getReturnType(ms[i].getSignature()).equals(o.getReturnType(cpg))) &&
				     (objarrayequals(Type.getArgumentTypes(ms[i].getSignature()), o.getArgumentTypes(cpg))) ){
					m = ms[i];
					break;
				}
			}
			if (m == null){
				constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature not found in class '"+jc.getClassName()+"'. The native verfier does allow the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
			}
			
			JavaClass current = Repository.lookupClass(myOwner.getClassName());
			if (current.isSuper()){
			
				if ((Repository.instanceOf( current, jc )) && (!current.equals(jc))){
					
					if (! (o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME) )){
						// Special lookup procedure for ACC_SUPER classes.
						
						int supidx = -1;
						
						Method meth = null;
						while (supidx != 0){
							supidx = current.getSuperclassNameIndex();
							current = Repository.lookupClass(current.getSuperclassName());
							
							Method[] meths = current.getMethods();
							for (int i=0; i<meths.length; i++){
								if	( (meths[i].getName().equals(o.getMethodName(cpg))) &&
				     				(Type.getReturnType(meths[i].getSignature()).equals(o.getReturnType(cpg))) &&
				     				(objarrayequals(Type.getArgumentTypes(meths[i].getSignature()), o.getArgumentTypes(cpg))) ){
									meth = meths[i];
									break;
								}
							}
							if (meth != null) break;
						}
						if (meth == null){
							constraintViolated(o, "ACC_SUPER special lookup procedure not successful: method '"+o.getMethodName(cpg)+"' with proper signature not declared in superclass hierarchy.");
						}						
					}
				}
			}
			
			
		}
		
		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitINVOKESTATIC(INVOKESTATIC o){
			// INVOKESTATIC is a LoadClass; the Class where the referenced method is declared in,
			// is therefore resolved/verified.
			// INVOKESTATIC is an InvokeInstruction, the argument and return types are resolved/verified,
			// too. So are the allowed method names.
			String classname = o.getClassName(cpg);
			JavaClass jc = Repository.lookupClass(classname);
			Method[] ms = jc.getMethods();
			Method m = null;
			for (int i=0; i<ms.length; i++){
				if ( (ms[i].getName().equals(o.getMethodName(cpg))) &&
				     (Type.getReturnType(ms[i].getSignature()).equals(o.getReturnType(cpg))) &&
				     (objarrayequals(Type.getArgumentTypes(ms[i].getSignature()), o.getArgumentTypes(cpg))) ){
					m = ms[i];
					break;
				}
			}
			if (m == null){
				constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature not found in class '"+jc.getClassName()+"'. The native verifier possibly allows the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
			}
			
			if (! (m.isStatic())){ // implies it's not abstract, verified in pass 2.
				constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' has ACC_STATIC unset.");
			}
		
		}


		/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
		public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){
			// INVOKEVIRTUAL is a LoadClass; the Class where the referenced method is declared in,
			// is therefore resolved/verified.
			// INVOKEVIRTUAL is an InvokeInstruction, the argument and return types are resolved/verified,
			// too. So are the allowed method names.
			String classname = o.getClassName(cpg);
			JavaClass jc = Repository.lookupClass(classname);
			Method[] ms = jc.getMethods();
			Method m = null;
			for (int i=0; i<ms.length; i++){
				if ( (ms[i].getName().equals(o.getMethodName(cpg))) &&
				     (Type.getReturnType(ms[i].getSignature()).equals(o.getReturnType(cpg))) &&
				     (objarrayequals(Type.getArgumentTypes(ms[i].getSignature()), o.getArgumentTypes(cpg))) ){
					m = ms[i];
					break;
				}
			}
			if (m == null){
				constraintViolated(o, "Referenced method '"+o.getMethodName(cpg)+"' with expected signature not found in class '"+jc.getClassName()+"'. The native verfier does allow the method to be declared in some superclass or implemented interface, which the Java Virtual Machine Specification, Second Edition does not.");
			}
			if (! (jc.isClass())){
				constraintViolated(o, "Referenced class '"+jc.getClassName()+"' is an interface, but not a class as expected.");
			}
					
		}

		
		// WIDE stuff is BCEL-internal and cannot be checked here.

		/**
		 * A utility method like equals(Object) for arrays.
		 * The equality of the elements is based on their equals(Object)
		 * method instead of their object identity.
		 */ 
		private boolean objarrayequals(Object[] o, Object[] p){
			if (o.length != p.length){
				return false;
			}
			
			for (int i=0; i<o.length; i++){
				if (! (o[i].equals(p[i])) ){
					return false;
				}
			}
			
			return true;
		}

	}
}

⌨️ 快捷键说明

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