Пример #1
0
		static public void ProcessInitObj(StackTypes stack, Type t)
		{
			if(!t.IsValueType)
				throw new VerifierException(); 
			TypeEx tRef = stack.Pop();
			if(!tRef.type.IsByRef)
				throw new VerifierException();
			if(!t.Equals(tRef.type.GetElementType()))
				throw new VerifierException();
		}
Пример #2
0
		public static void ProcessUnBox(StackTypes stack, Type T)
		{
			TypeEx objType = stack.Pop();
			Type valueType = T;
			if(! ((objType.IsBoxable && objType.boxed) || !objType.IsBoxable) )
				throw new VerifierException();
			if(! valueType.IsValueType )
				throw new VerifierException();
			stack.Push( TypeEx.BuildRefType(valueType) );
		}
Пример #3
0
		public static void ProcessNeg(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!t.type.IsPrimitive || t.boxed)
				throw new VerifierException();
			stack.Push(TypeFixer.FixType(t));
		}
Пример #4
0
		public static void ProcessLdLen(StackTypes stack)
		{
			TypeEx array = stack.Pop();
			if(!array.type.IsArray)
				throw new VerifierException();
			stack.Push(typeof(int));
		}
Пример #5
0
		public static void ProcessCastClass(StackTypes stack, TypeEx t)
		{
			TypeEx T = stack.Pop();
			if(T.IsBoxable && !T.boxed)
				throw new VerifierException();
			stack.Push(t);
		}
Пример #6
0
		public static void ProcessStFld(StackTypes stack, FieldInfo field)
		{
			TypeEx fldValue = stack.Pop(); 
			TypeEx obj = stack.Pop();
			if(obj.type.IsByRef)  //STFLD accepts both objects and managed pointers on value-types
			{
				if(! field.DeclaringType.Equals(obj.type.GetElementType()) || !field.DeclaringType.IsValueType )
					throw new VerifierException();
			}
			else
			  TypeChecker.CheckAssignment(new TypeEx(field.DeclaringType),obj);
			TypeChecker.CheckAssignment(new TypeEx(field.FieldType),fldValue);
		}
Пример #7
0
		public static void ProcessLdElem(StackTypes stack,TypeEx desiredArrayElem,bool loadAddress)
		{
			TypeEx index = stack.Pop();
			TypeEx array = stack.Pop();
			TypeEx arrayElem = ProcessLdStElem(array,desiredArrayElem,index);
			if(loadAddress)
				arrayElem = arrayElem.BuildRefType();
			stack.Push(arrayElem);
		}
Пример #8
0
		static public void ProcessStSFld(StackTypes stack, FieldInfo field)
		{
			TypeEx fldValue = stack.Pop(); 
			TypeChecker.CheckAssignment(new TypeEx(field.FieldType),fldValue);
		}
Пример #9
0
		internal static bool Check(MethodEx methodRepr)
		{
			//Attention: the `null` value on stack means a null reference that is of any object type 
			//As `typeof(object)` is the most general Type, so `null` is the most exact object type 
			FreeStacks(methodRepr);
			try
			{
				Instruction lastI = methodRepr[methodRepr.Count-1]; 
				if(    lastI.Code != InstructionCode.RET 
					&& lastI.Code != InstructionCode.BR
					&& lastI.Code != InstructionCode.THROW
					&& lastI.Code != InstructionCode.RETHROW
					&& lastI.Code != InstructionCode.LEAVE
					&& lastI.Code != InstructionCode.ENDFINALLY
					&& lastI.Code != InstructionCode.ENDFILTER )
						throw new VerifierException();
				MethodInfoExtention method = new MethodInfoExtention(methodRepr.Method);
				StackTypes stack = new StackTypes(); //initially the stack is empty
				int nextHandler = FindNextHandler(-1,methodRepr.EHClauses);
				CheckBlockExits(methodRepr);
				for (int iNum = 0; iNum < methodRepr.Count ; iNum ++)
				{  
					Instruction i = methodRepr[iNum]; 
					i.SetStack(MergeStacks(i.Stack,stack));
					if(nextHandler == iNum)
					{
						PushExceptionOnStack(iNum,i.Stack,methodRepr.EHClauses);
						nextHandler = FindNextHandler(iNum,methodRepr.EHClauses);
					}
					stack = i.Stack.Clone() as StackTypes;  
					switch(i.Code)
					{
						case InstructionCode.DUP :    
						{
							stack.Push(stack.Peek()); 
						} break;
						case InstructionCode.LDARG : 
						{
							stack.Push(method.GetArgType((Int32)i.Param));
						} break;
						case InstructionCode.LDARGA : 
						{
							TypeEx t = method.GetArgType((Int32)i.Param).BuildRefType();
							stack.Push(t);
						} break;
						case InstructionCode.LDLOCA : 
						{
							TypeEx t = new TypeEx(TypeEx.BuildRefType(methodRepr.Locals[(Int32)i.Param]));
							stack.Push(t);
						} break;
						case InstructionCode.LDLOC : 
						{
							stack.Push(new TypeEx(methodRepr.Locals[(Int32)i.Param]));
						} break;
						case InstructionCode.LDIND :
						{
							ProcessLdInd(i.TypeBySuffixOrParam(), stack);
						} break;
						case InstructionCode.LDC:
						{
							stack.Push(new TypeEx(i.TypeBySuffixOrParam()));
						} break;
						case InstructionCode.LDNULL:
						{
							stack.Push(new TypeEx(null));//see `Attention` at the top of the method.
						} break;
						case InstructionCode.LDFLD:
						{
							ProcessLdFld(stack, i.Param as FieldInfo,false);
						} break;
						case InstructionCode.LDFLDA:
						{
							ProcessLdFld(stack, i.Param as FieldInfo,true);
						} break;
						case InstructionCode.LDSFLD:
						{
							stack.Push(new TypeEx((i.Param as FieldInfo).FieldType)); 
						} break;
						case InstructionCode.LDSFLDA:
						{
							stack.Push(TypeEx.BuildRefType((i.Param as FieldInfo).FieldType)); 
						} break;
						case InstructionCode.LDELEM:
						{
							ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), false);
						} break;
						case InstructionCode.LDELEMA:
						{
							ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), true);
						} break;
						case InstructionCode.LDLEN :
						{
							ProcessLdLen(stack);
						} break;
						case InstructionCode.LDOBJ :
						{
							ProcessLdObj(stack, i.Param as Type);
						} break;
						case InstructionCode.LDSTR:
						{
							if(!(i.Param is string)) 
								throw new VerifierException();
							stack.Push(typeof(string));
						} break;
						case InstructionCode.LDFTN:
						{
							stack.Push(new TypeEx(typeof(IntPtr))); 
						} break;
						case InstructionCode.LDVIRTFTN:
						{
							TypeEx obj = stack.Pop();
							MethodInfo methodInfo = i.Param as MethodInfo;
							if(!methodInfo.IsVirtual)
								throw new VerifierException();
							TypeChecker.CheckAssignment(new TypeEx(methodInfo.DeclaringType , true), obj);
							stack.Push(typeof(IntPtr));
						} break;
						case InstructionCode.LDTOKEN:
						{
							if(i.Param is Type)
								stack.Push(typeof(System.RuntimeTypeHandle));
							else if(i.Param is MethodBase)
								stack.Push(typeof(System.RuntimeMethodHandle));
							else if(i.Param is FieldInfo)
								stack.Push(typeof(System.RuntimeFieldHandle));
							else
								throw new VerifierException();
						} break;
						case InstructionCode.SIZEOF :
						{
							ProcessSizeOf(stack,i.Param as Type);
						} break;

						case InstructionCode.CLT: 
						case InstructionCode.CGT:
						case InstructionCode.CEQ:
						{
              ProcessBinOp(OpType.Compare,stack);
						} break;

						case InstructionCode.BLE:
						case InstructionCode.BLT: 
						case InstructionCode.BGE:
						case InstructionCode.BGT:
						case InstructionCode.BEQ:
						case InstructionCode.BNE:
						{
							TypeEx t1 = stack.Pop();
							TypeEx t2 = stack.Pop();
							Arithmetics.CheckTypes(t1,t2);
							ProcessBr(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
							//Andrew: mb wrong, we may let equal stacks to be the same object
						} break;
						case InstructionCode.BRTRUE:
						case InstructionCode.BRFALSE:
						{
							ProcessBrTrueFalse(stack);
							ProcessBr(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
							//Andrew: mb wrong, we may let equal stacks to be the same object
						} break;
						case InstructionCode.BR : 
						{
							ProcessBr(iNum,methodRepr,stack);
							stack = null; 
						} break;

						case InstructionCode.SWITCH:
						{
							ProcessSwitch(stack);
							ProcessSwitch(iNum,methodRepr,stack);
							stack = stack.Clone() as StackTypes; 
						} break;
            
						case InstructionCode.THROW :
						{
							ProcessThrow(stack);
							stack = null;
						}break;
            
						case InstructionCode.RETHROW :
						{
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Catch)
								throw new VerifierException();
							stack = null;
						}break;

						case InstructionCode.LEAVE : 
						{
							BlockType blockType = GetNearestBlock(methodRepr.EHClauses,iNum).type;
							if(blockType != BlockType.Catch && blockType != BlockType.Try)
								throw new VerifierException();
							ProcessLeave(iNum,methodRepr,stack);
							stack = null; 
						} break;

						case InstructionCode.ENDFINALLY : 
						{ 
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Finally)
								throw new VerifierException();
							ProcessLeave(stack);
							stack = null; 
						} break;

						case InstructionCode.ENDFILTER : 
						{ 
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Filter)
								throw new VerifierException();
							ProcessEndFilter(stack);
							stack = null; 
						} break;

						case InstructionCode.NOT:
						{
							ProcessNot(stack);
						} break;

						case InstructionCode.NEG:
						{
							ProcessNeg(stack);
						} break;
              
						case InstructionCode.CKFINITE :
						{ 
							ProcessCkFinite(stack);
						} break;

						case InstructionCode.CONV:
						{
							ProcessConv(i.TypeBySuffixOrParam(), stack);
						} break;

						case InstructionCode.SUB: 
						case InstructionCode.ADD: 
						case InstructionCode.MUL: 
						case InstructionCode.DIV: 
						case InstructionCode.REM: 
						case InstructionCode.XOR:
						case InstructionCode.OR:
						case InstructionCode.AND:
						{
							ProcessBinOp(IsFloatOperation(i) ? OpType.FloatOrInt : OpType.Int , stack);
						} break;

						case InstructionCode.SHL:
						case InstructionCode.SHR:
						{
							ProcessBinOp(OpType.Shift , stack);
						} break;

						case InstructionCode.CPOBJ :
						{
							ProcessCpObj(stack, i.Param as Type);
						} break;

						case InstructionCode.STARG : 
						{
							ProcessSt(method.GetArgType((Int32)i.Param) , stack);
						} break;
						case InstructionCode.STLOC : 
						{
							ProcessSt(new TypeEx(methodRepr.Locals[(Int32)i.Param]) , stack);
						} break;
						case InstructionCode.STIND :
						{
							ProcessStInd(i.TypeBySuffixOrParam() , stack);
						} break;
						case InstructionCode.STFLD:
						{
							ProcessStFld(stack, i.Param as FieldInfo);
						} break;
						case InstructionCode.STSFLD:
						{
							ProcessStSFld(stack, i.Param as FieldInfo);
						} break;
						case InstructionCode.STELEM:
						{
							ProcessStElem(stack, new TypeEx(i.TypeBySuffixOrParam()));
						} break;
						case InstructionCode.STOBJ :
						{
							ProcessStObj(stack, i.Param as Type);
						} break;

						case InstructionCode.RET : 
						{
							if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Global)
								throw new VerifierException();
							ProcessRet(method.GetReturnType(), stack);
							stack = null;  
						} break;
						case InstructionCode.CALL : 
						case InstructionCode.CALLVIRT :
						case InstructionCode.NEWOBJ :
						{
							//constructor may be invoked using either CALL or NEWOBJ instructions
							MethodBase callee = i.Param as MethodBase; 
							if(i.Code == InstructionCode.NEWOBJ && callee.IsConstructor && IsDelegate(callee.DeclaringType))
								ProcessDelegateConstruction(methodRepr,iNum,stack);
							else
							  ProcessCallOrNewobj(new MethodInfoExtention(callee,i.Code == InstructionCode.CALLVIRT), stack, i.Code == InstructionCode.NEWOBJ);
                            if(i.HasTail && methodRepr[iNum+1].Code != InstructionCode.RET)
								throw new VerifierException();
						} break;
						case InstructionCode.INITOBJ :
						{
							ProcessInitObj(stack, i.Param as Type);
						} break;
						case InstructionCode.NEWARR :
						{
							ProcessNewArr(stack, i.Param as Type);
						} break;
						case InstructionCode.ISINST :
						case InstructionCode.CASTCLASS :
						{
							ProcessCastClass(stack, new TypeEx(i.Param as Type , true));
						} break;

						case InstructionCode.BOX :
						{
							ProcessBox(stack, i.Param as Type);
						} break;

						case InstructionCode.UNBOX :
						{
							ProcessUnBox(stack, i.Param as Type);
						} break;

						case InstructionCode.POP :
						{
							stack.Pop(); 
						} break;

						case InstructionCode.NOP :
						case InstructionCode.BREAK :
							break;

						default: 
						{
							throw new VerifierException();
							//Instruction is not supported yet...
						}
					}  
				}
				return(true);
			}
			catch(VerifierException )
			{ 
				FreeStacks(methodRepr);
				return(false);
			}
			//catch(NullReferenceException ) //Andrew: ZaLyaPa :( waiting for Sergey to patch NEWOBJ (delegate construction)
			//{
			//	FreeStacks(methodRepr);
			//	return(false);
			//}
		}
Пример #10
0
		static private void ProcessDelegateConstruction(MethodEx method,int iNum,StackTypes stack)
		{
			if(!(IsInstanceDispatch(method,iNum) || IsVirtualDispatch(method,iNum)))
			  throw new VerifierException();
			TypeEx intPtr = stack.Pop();
			MethodInfo ftn = method[iNum-1].Param as MethodInfo;
			ConstructorInfo ctor = method[iNum].Param as ConstructorInfo;
			ProcessDelegateConstruction(stack,ftn,ctor);

		}
Пример #11
0
		static public void ProcessDelegateConstruction(StackTypes stack, MethodInfo ftn, ConstructorInfo ctor)
		{
			TypeEx obj = stack.Pop();
			TypeChecker.CheckAssignment(new TypeEx(ftn.DeclaringType , true), obj);
			Type delegateType = ctor.DeclaringType;
			if(!IsDelegate(delegateType))
				throw new VerifierException();
			MethodInfo prototype = delegateType.GetMethod("Invoke");
			if(!SameSignatures(prototype, ftn))
				throw new VerifierException();
			stack.Push(delegateType);
		}
Пример #12
0
		static public void ProcessConv(Type T, StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!t.type.IsPrimitive || t.boxed )
				throw new VerifierException();
			stack.Push(T);
		}
Пример #13
0
		static public void ProcessCkFinite(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!TypeFixer.IsFloatOrCompatible(t) || t.boxed )
				throw new VerifierException();
			stack.Push(t);
		}
Пример #14
0
		static public void ProcessStObj(StackTypes stack, Type t)
		{
			TypeEx valObj = stack.Pop();
			TypeEx addr = stack.Pop();
			if(!addr.type.IsByRef)
				throw new VerifierException();
			if(!t.IsValueType)
					throw new VerifierException();
			if(!t.Equals(valObj.type) || !t.Equals(addr.type.GetElementType()))
				throw new VerifierException();
		}
Пример #15
0
		static public void ProcessLdInd(Type T, StackTypes stack)   
		{
			TypeEx addr = stack.Pop();
			if(!addr.type.IsByRef)
				throw new VerifierException();
			TypeEx sourceType = new TypeEx(addr.type.GetElementType());
			TypeEx targetType = new TypeEx(T);
			if(targetType.type.Equals(typeof(object))) //.ref suffix
				stack.Push(sourceType);
			else
			{
				TypeChecker.CheckAssignment(targetType,sourceType);
				stack.Push(targetType);
			}
		}
Пример #16
0
		public static void ProcessBrTrueFalse(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			TypeChecker.CheckBrTrueFalseType(t);
		}
Пример #17
0
		public static void ProcessSt(TypeEx T, StackTypes stack)
		{
			TypeEx t = stack.Pop();
			TypeChecker.CheckAssignment(T,t);
		}
Пример #18
0
		public static void ProcessSwitch(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!TypeFixer.IsInt32OrCompatible(t))
				throw new VerifierException();
		}
Пример #19
0
		public static void ProcessStInd(Type T, StackTypes stack)
		{
			TypeEx val = stack.Pop();
			TypeEx addr = stack.Pop();
			if(!addr.type.IsByRef)
				throw new VerifierException();
			TypeEx targetType = new TypeEx(addr.type.GetElementType());
			TypeEx sourceType = new TypeEx(T);
			TypeChecker.CheckAssignment(targetType,val);
			CheckPrimitiveIndirectAssignment(targetType,sourceType);
		}
Пример #20
0
		public static void ProcessRet(TypeEx returnType, StackTypes stack)
		{
			if(!returnType.type.Equals(typeof(void))) 
			{
				TypeEx t = stack.Pop();
				TypeChecker.CheckAssignment(returnType, t);
			}
			if(stack.Count != 0)
				throw new VerifierException();
		}
Пример #21
0
		public static void ProcessStElem(StackTypes stack, TypeEx desiredArrayElem)
		{
			TypeEx elemValue = stack.Pop();
			TypeEx index = stack.Pop();
			TypeEx array = stack.Pop();
			TypeEx arrayElem = ProcessLdStElem(array,desiredArrayElem,index);
			TypeChecker.CheckAssignment(arrayElem,elemValue);       
		}
Пример #22
0
		public static void ProcessThrow(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			TypeChecker.CheckAssignment(new TypeEx(typeof(Exception)), t);
		}
Пример #23
0
		public static void ProcessEndFilter(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!TypeFixer.IsInt32OrCompatible(t))
				throw new VerifierException();
			if(stack.Count != 0)
				throw new VerifierException();
		}
Пример #24
0
		public static void ProcessCallOrNewobj(MethodInfoExtention method,StackTypes stack, bool isNewObj)
		{
			for(int i = method.ArgCount-1; i >= (isNewObj ? 1 : 0); i--) 
			{ //when we are creating a new object `this` is not on stack
				TypeEx sourceType = stack.Pop();
				TypeEx targetType = method.GetArgType(i);
				TypeChecker.CheckAssignment(targetType, sourceType);
			}
			TypeEx returnType = method.GetReturnType();
			if(isNewObj)
				stack.Push(method.DeclaringType);
				//Wow! Value-types can be created on stack with NEWOBJ instruction -- not boxed
			else if(!returnType.type.Equals(typeof(void)))
				stack.Push(returnType);
		}
Пример #25
0
		public static void ProcessBox(StackTypes stack, Type T)
		{
			TypeEx valueType = stack.Pop();
			if(! valueType.IsBoxable || valueType.boxed)
				throw new VerifierException();
			TypeChecker.CheckAssignment(new TypeEx(T), valueType);
			
			// Skor >> this code was wrong !
			//stack.Push(new TypeEx(valueType.type ,   true   ));
			stack.Push(new TypeEx(T, true));
		}
Пример #26
0
		public static void ProcessNewArr(StackTypes stack, Type T)
		{
			TypeEx t = stack.Pop();
			if(!TypeFixer.IsInt32OrCompatible(t) && !TypeFixer.IsIntPtrOrCompatible(t))
				throw new VerifierException();
			stack.Push( TypeEx.BuildArrayType(T) );
		}
Пример #27
0
		public static void ProcessNot(StackTypes stack)
		{
			TypeEx t = stack.Pop();
			if(!t.type.IsPrimitive || t.boxed || TypeFixer.IsFloatOrCompatible(t))
				throw new VerifierException();
			stack.Push(TypeFixer.FixType(t));
		}
Пример #28
0
		public static void ProcessLdFld(StackTypes stack, FieldInfo field, bool loadAddress)
		{
			TypeEx obj = stack.Pop();
			if(obj.type != null) //LDNULL LDFLD -- crazy!
			{
				if(obj.type.IsByRef)  //LDFLD to the structure accepts this structure address 
				{
					if(! field.DeclaringType.Equals(obj.type.GetElementType()) || !field.DeclaringType.IsValueType )
						throw new VerifierException();
				}
				else
					TypeChecker.CheckAssignment(new TypeEx(field.DeclaringType),obj);
			}
			Type fieldType = field.FieldType;
			if(loadAddress)
				fieldType = TypeEx.BuildRefType(fieldType);
			stack.Push(fieldType);
		}
Пример #29
0
		public static void ProcessBinOp(OpType opType, StackTypes stack)
		{
			switch(opType)
			{
				case OpType.Shift:
				{
					TypeEx shift = stack.Pop();
					TypeEx t = stack.Pop();
					if(!(TypeFixer.IsInt32OrCompatible(shift) || TypeFixer.IsIntPtrOrCompatible(shift)))
						throw new VerifierException();
					if(!(TypeFixer.IsInt32OrCompatible(shift) || 
						   TypeFixer.IsIntPtrOrCompatible(shift) || 
						   TypeFixer.IsInt64OrCompatible(shift)))
						throw new VerifierException();
					stack.Push(t);
				} break;
				case OpType.FloatOrInt:
				case OpType.Int:
				{
					TypeEx t1 = stack.Pop();
					TypeEx t2 = stack.Pop();
					TypeEx t3 = Arithmetics.GetReturnType(t1,t2,opType == OpType.FloatOrInt);
					stack.Push(t3);
				} break;
				case OpType.Compare:
				{
					TypeEx t1 = stack.Pop();
					TypeEx t2 = stack.Pop();
					Arithmetics.CheckTypes(t1,t2);
					stack.Push(typeof(int));
				} break;
			}
		}
Пример #30
0
		static public void ProcessCpObj(StackTypes stack, Type t)
		{
			TypeEx addr1 = stack.Pop();
			TypeEx addr2 = stack.Pop();
			if(!addr1.type.IsByRef || !addr2.type.IsByRef)
				throw new VerifierException();
				if(!t.IsValueType)
					throw new VerifierException();
			if(!t.Equals(addr1.type.GetElementType()) || !t.Equals(addr2.type.GetElementType()))
				throw new VerifierException();
		}