Пример #1
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;
		}
Пример #2
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;
		}
Пример #3
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;
		}
Пример #4
0
        bool Emulate_Beq()
        {
            var val2 = instructionEmulator.Pop();
            var val1 = instructionEmulator.Pop();

            if (val1.IsInt32() && val2.IsInt32())
            {
                return(EmulateBranch(2, Int32Value.CompareEq((Int32Value)val1, (Int32Value)val2)));
            }
            else if (val1.IsInt64() && val2.IsInt64())
            {
                return(EmulateBranch(2, Int64Value.CompareEq((Int64Value)val1, (Int64Value)val2)));
            }
            else if (val1.IsReal8() && val2.IsReal8())
            {
                return(EmulateBranch(2, Real8Value.CompareEq((Real8Value)val1, (Real8Value)val2)));
            }
            else if (val1.IsNull() && val2.IsNull())
            {
                return(EmulateBranch(2, true));
            }
            else
            {
                return(false);
            }
        }