Exemple #1
0
		public void VisitInstruction(TypedInstruction instruction)
		{
			if (m_offset < 0)
			{
				m_offset = NullCheck.Check<NullDerefRule>(instruction, m_info.Tracker, out m_details);
			}
		}
		private int DoGetStackCount(TypedInstruction instruction, StackBehaviour behavior)
		{
			int count = 0;
			
			switch (behavior)
			{
				case StackBehaviour.Pop0:
				case StackBehaviour.Push0:
					break;
					
				case StackBehaviour.Pop1:
				case StackBehaviour.Popi:
				case StackBehaviour.Popref:
				case StackBehaviour.Push1:
				case StackBehaviour.Pushi:
				case StackBehaviour.Pushi8:
				case StackBehaviour.Pushr4:
				case StackBehaviour.Pushr8:
				case StackBehaviour.Pushref:
					count = 1;
					break;
					
				case StackBehaviour.Pop1_pop1:
				case StackBehaviour.Popi_pop1:
				case StackBehaviour.Popi_popi:
				case StackBehaviour.Popi_popi8:
				case StackBehaviour.Popi_popr4:
				case StackBehaviour.Popi_popr8:
				case StackBehaviour.Popref_pop1:
				case StackBehaviour.Popref_popi:
				case StackBehaviour.Push1_push1:
					count = 2;
					break;
					
				case StackBehaviour.Popi_popi_popi:
				case StackBehaviour.Popref_popi_popi:
				case StackBehaviour.Popref_popi_popi8:
				case StackBehaviour.Popref_popi_popr4:
				case StackBehaviour.Popref_popi_popr8:
				case StackBehaviour.Popref_popi_popref:
					count = 3;
					break;
					
				case StackBehaviour.PopAll:				// leave
					count = int.MaxValue;
					break;
					
				case StackBehaviour.Varpop:				// call, newobj, ret
					Call call = instruction as Call;
					if (call != null)
					{
						count = call.Target.Parameters.Count + (call.Target.HasThis ? 1 : 0);
					}
					else if (instruction.Untyped.OpCode.Code == Code.Ret)
					{
						count = int.MaxValue;
					}
					else
					{
						NewObj no = instruction as NewObj;
						DBC.Assert(no != null, "Varpop opcode should be call, ret, or newobj");
						
						count = no.Ctor.Parameters.Count;
					}
					break;
				
				case StackBehaviour.Varpush:			// call
					Call call2 = instruction as Call;
					DBC.Assert(call2 != null, "Varpush opcode should be call");
					if (call2.Target.ReturnType.ReturnType.FullName != "System.Void")
						count = 1;
					break;

				default:
					DBC.Fail("Bad stack behavior: {0}", behavior);
					break;
			}
						
			return count;
		}
		private int DoGetStackDelta(TypedInstruction instruction)
		{
			int delta = 0;
			
			delta += DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPush);
			delta -= DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPop);
//			Log.DebugLine(this, "{0} (delta = {1})", instruction, delta);
						
			return delta;
		}
		private void DoCheck(TypedInstruction binary)
		{
			if (binary.Index >= 2)
			{
				int rhsEnd = binary.Index - 1;
				int rhsStart = rhsEnd - DoGetPushRange(m_info, rhsEnd);

				int lhsEnd = rhsStart - 1;
				int lhsStart = lhsEnd - DoGetPushRange(m_info, lhsEnd);
			
				Log.DebugLine(this, "{0} at {1:X}", binary.Untyped.OpCode.Code, binary.Untyped.Offset);
				Log.DebugLine(this, "   lhs range: [{0:X}, {1:X}]", m_info.Instructions[lhsStart].Untyped.Offset, m_info.Instructions[lhsEnd].Untyped.Offset);
				Log.DebugLine(this, "   rhs range: [{0:X}, {1:X}]", m_info.Instructions[rhsStart].Untyped.Offset, m_info.Instructions[rhsEnd].Untyped.Offset);
				
				bool matches = (rhsEnd - rhsStart) == (lhsEnd - lhsStart);
				for (int i = 0; i <= (rhsEnd - rhsStart) && matches; ++i)
				{
					TypedInstruction lhs = m_info.Instructions[lhsStart + i];
					TypedInstruction rhs = m_info.Instructions[rhsStart + i];
					
					matches = lhs.Untyped.Matches(rhs.Untyped);
				}

				if (matches)
				{
					m_offset = binary.Untyped.Offset;
				}
			}
		}
Exemple #5
0
		private void DoCheckLoad(TypedInstruction instruction)
		{
			LoadConstantInt load = m_info.Instructions[instruction.Index - 1] as LoadConstantInt;
			if (load != null)
			{
				if (load.Value < 0 || load.Value > 255)
				{
					m_offset = instruction.Untyped.Offset;						
					Log.DebugLine(this, "bad exit at {0:X2}", m_offset); 
				}
			}

			LoadLocal local = m_info.Instructions[instruction.Index - 1] as LoadLocal;
			if (local != null)
			{
				Log.DebugLine(this, "{0} at {1:X2}", instruction.Untyped.OpCode, instruction.Untyped.Offset); 
				if (m_candidateLoads.IndexOf(local.Variable) < 0)
				{
					m_candidateLoads.Add(local.Variable);
				}
			}
		}
		private void DoCheck(TypedInstruction call, MethodReference target, int nth)
		{
			int index = m_info.Tracker.GetStackIndex(call.Index, nth);
			if (index >= 0)
			{
				LoadString load = m_info.Instructions[index] as LoadString;
				if (load != null)
				{
					m_offset = call.Untyped.Offset;
					m_bad = target.ToString();
					Log.DebugLine(this, "bad call at {0:X2}", m_offset);				
				}
			}
		}
		public void VisitInstruction(TypedInstruction instruction)
		{
			if (m_needsCheck && !m_foundEarlyReturn && m_offset < 0)
			{
				m_offset = NullCheck.Check<EqualsRequiresNullCheckRule>(instruction, m_tracker, out m_details);
			}
		}
		private bool DoMatch(TypedInstruction lhs, TypedInstruction rhs)
		{
			if (lhs.Untyped.OpCode.Code != rhs.Untyped.OpCode.Code)
				return false;
				
			if (lhs.Untyped.Operand != null || rhs.Untyped.Operand != null)
			{
				if (lhs.Untyped.Operand != null && rhs.Untyped.Operand != null)
				{
					if (!DoMatchOperand(lhs.Untyped.Operand, rhs.Untyped.Operand))
						return false;
				}
				else 
					return false;
			}
						
			return true;
		}