示例#1
0
        bool VerifyValidArgs(Instruction instr)
        {
            int pushes, pops;

            instr.CalculateStackUsage(out pushes, out pops);
            if (pops < 0)
            {
                return(false);
            }

            bool  retVal;
            Value val2, val1;

            switch (pops)
            {
            case 0:
                return(true);

            case 1:
                val1   = instructionEmulator.Pop();
                retVal = VerifyValidArg(val1);
                instructionEmulator.Push(val1);
                return(retVal);

            case 2:
                val2   = instructionEmulator.Pop();
                val1   = instructionEmulator.Pop();
                retVal = VerifyValidArg(val2) && VerifyValidArg(val1);
                instructionEmulator.Push(val1);
                instructionEmulator.Push(val2);
                return(retVal);
            }

            return(false);
        }
示例#2
0
		bool FindInts(int index) {
			if (index < 0)
				return false;

			i2 = 0;
			var instrs = stringMethod.Body.Instructions;

			var emu = new InstructionEmulator(stringMethod);
			foreach (var kv in stringMethodConsts.Locals32)
				emu.SetLocal(kv.Key, new Int32Value(kv.Value));

			var fields = new Dictionary<FieldDef, int?>();
			for (int i = index; i < instrs.Count - 2; i++) {
				var instr = instrs[i];

				FieldDef field;
				switch (instr.OpCode.Code) {
				case Code.Ldsfld:
					field = instr.Operand as FieldDef;
					if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4)
						goto default;
					fields[field] = null;
					emu.Push(new Int32Value(i1));
					break;

				case Code.Stsfld:
					field = instr.Operand as FieldDef;
					if (field == null || field.DeclaringType != stringMethod.DeclaringType || field.FieldType.GetElementType() != ElementType.I4)
						goto default;
					if (fields.ContainsKey(field) && fields[field] == null)
						goto default;
					var val = emu.Pop() as Int32Value;
					if (val == null || !val.AllBitsValid())
						fields[field] = null;
					else
						fields[field] = val.Value;
					break;

				case Code.Call:
					var method = instr.Operand as MethodDef;
					if (!decrypterType.Detected || method != decrypterType.Int64Method)
						goto done;
					emu.Push(new Int64Value((long)decrypterType.GetMagic()));
					break;

				case Code.Newobj:
					if (!EmulateDynocode(emu, ref i))
						goto default;
					break;

				default:
					if (instr.OpCode.FlowControl != FlowControl.Next)
						goto done;
					emu.Emulate(instr);
					break;
				}
			}
done:

			foreach (var val in fields.Values) {
				if (val == null)
					continue;
				magic1 = i2 = val.Value;
				return true;
			}

			return false;
		}
示例#3
0
		// 5.1+
		// the only changes are the indexes of ldloc and stfld
		bool EmulateDynocodeNew(InstructionEmulator emu, ref int index) {
			var instrs = stringMethod.Body.Instructions;
			var instr = instrs[index];

			var ctor = instr.Operand as MethodDef;
			if (ctor == null || ctor.MethodSig.GetParamCount() != 1 || ctor.MethodSig.Params[0].ElementType != ElementType.I4)
				return false;

			if (index + 4 >= instrs.Count)
				return false;
			var ldloc = instrs[index + 2];
			var stfld = instrs[index + 3];
			if (!ldloc.IsLdloc() || stfld.OpCode.Code != Code.Stfld)
				return false;
			var enumerableField = stfld.Operand as FieldDef;
			if (enumerableField == null)
				return false;

			var initValue = emu.GetLocal(ldloc.GetLocal(stringMethod.Body.Variables)) as Int32Value;
			if (initValue == null || !initValue.AllBitsValid())
				return false;

			int leaveIndex = FindLeave(instrs, index);
			if (leaveIndex < 0)
				return false;
			var afterLoop = instrs[leaveIndex].Operand as Instruction;
			if (afterLoop == null)
				return false;
			int newIndex = instrs.IndexOf(afterLoop);
			var loopLocal = GetDCLoopLocal(index, newIndex);
			if (loopLocal == null)
				return false;
			var initValue2 = emu.GetLocal(loopLocal) as Int32Value;
			if (initValue2 == null || !initValue2.AllBitsValid())
				return false;

			int loopStart = GetIndexOfCall(instrs, index, leaveIndex, "System.Int32", "()");
			int loopEnd = GetIndexOfCall(instrs, loopStart, leaveIndex, "System.Boolean", "()");
			if (loopStart < 0 || loopEnd < 0)
				return false;
			loopStart++;
			loopEnd--;

			dynocode.Initialize(module);
			var ctorArg = emu.Pop() as Int32Value;
			if (ctorArg == null || !ctorArg.AllBitsValid())
				return false;
			dynocode.CreateEnumerable(ctor, new object[] { ctorArg.Value });
			dynocode.WriteEnumerableField(enumerableField.MDToken.ToUInt32(), initValue.Value);
			dynocode.CreateEnumerator();
			foreach (var val in dynocode) {
				emu.Push(new Int32Value(val));
				for (int i = loopStart; i < loopEnd; i++)
					emu.Emulate(instrs[i]);
			}

			index = newIndex - 1;
			return true;
		}
示例#4
0
		public static Value[] GetInitializedArray(int arraySize, MethodDef method, ref int newarrIndex, Code stelemOpCode) {
			var resultValueArray = new Value[arraySize];

			var emulator = new InstructionEmulator(method);
			var theArray = new UnknownValue();
			emulator.Push(theArray);

			var instructions = method.Body.Instructions;
			int i;
			for (i = newarrIndex + 1; i < instructions.Count; i++) {
				var instr = instructions[i];
				if (instr.OpCode.FlowControl != FlowControl.Next)
					break;
				if (instr.OpCode.Code == Code.Newarr)
					break;
				switch (instr.OpCode.Code) {
				case Code.Newarr:
				case Code.Newobj:
					goto done;

				case Code.Stloc:
				case Code.Stloc_S:
				case Code.Stloc_0:
				case Code.Stloc_1:
				case Code.Stloc_2:
				case Code.Stloc_3:
				case Code.Starg:
				case Code.Starg_S:
				case Code.Stsfld:
				case Code.Stfld:
					if (emulator.Peek() == theArray && i != newarrIndex + 1 && i != newarrIndex + 2)
						goto done;
					break;
				}

				if (instr.OpCode.Code == stelemOpCode) {
					var value = emulator.Pop();
					var index = emulator.Pop() as Int32Value;
					var array = emulator.Pop();
					if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid()) {
						if (0 <= index.Value && index.Value < resultValueArray.Length)
							resultValueArray[index.Value] = value;
					}
				}
				else
					emulator.Emulate(instr);
			}
done:
			if (i != newarrIndex + 1)
				i--;
			newarrIndex = i;

			return resultValueArray;
		}