Beispiel #1
0
        public static Value[] getInitializedArray(int arraySize, MethodDefinition method, ref int newarrIndex, Code stelemOpCode)
        {
            var resultValueArray = new Value[arraySize];

            var emulator = new InstructionEmulator(method.HasThis, false, method.Parameters, method.Body.Variables);
            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;

                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);
            }
            if (i != newarrIndex + 1)
                i--;
            newarrIndex = i;

            return resultValueArray;
        }
 void setLocal(int index, Value value)
 {
     if (0 <= index && index < locals.Count)
         locals[index] = truncateValue(value, variableDefinitions[index].VariableType);
 }
 void setArg(int index, Value value)
 {
     if (0 <= index && index < args.Count)
         args[index] = truncateValue(value, getArgType(index));
 }
 Block getSwitchTarget(IList<Block> targets, Block fallThrough, Block source, Value value)
 {
     if (!value.isInt32())
         return null;
     return CflowUtils.getSwitchTarget(targets, fallThrough, (Int32Value)value);
 }
		bool EmulateToReturn(int index, Instruction lastInstr) {
			int pushes, pops;
			lastInstr.CalculateStackUsage(false, out pushes, out pops);
			instructionEmulator.Pop(pops);

			returnValue = null;
			if (pushes != 0) {
				returnValue = new UnknownValue();
				instructionEmulator.SetProtected(returnValue);
				instructionEmulator.Push(returnValue);
			}

			if (!EmulateInstructions(ref index, true))
				return false;
			if (index >= methodToInline.Body.Instructions.Count)
				return false;
			if (methodToInline.Body.Instructions[index].OpCode.Code != Code.Ret)
				return false;

			if (returnValue != null) {
				if (instructionEmulator.Pop() != returnValue)
					return false;
			}
			return instructionEmulator.StackSize() == 0;
		}
		static Block GetSwitchTarget(IList<Block> targets, Block fallThrough, Value value) {
			if (!value.IsInt32())
				return null;
			return CflowUtils.GetSwitchTarget(targets, fallThrough, (Int32Value)value);
		}
Beispiel #7
0
 bool FixLoadInstruction(Block block, int index, Value value)
 {
     if (value.IsInt32()) {
         var intValue = (Int32Value)value;
         if (!intValue.AllBitsValid())
             return false;
         block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.Value));
         return true;
     }
     else if (value.IsInt64()) {
         var intValue = (Int64Value)value;
         if (!intValue.AllBitsValid())
             return false;
         block.Instructions[index] = new Instr(OpCodes.Ldc_I8.ToInstruction(intValue.Value));
         return true;
     }
     return false;
 }
		void SetLocal(int index, Value value) {
			if (0 <= index && index < locals.Count)
				locals[index] = TruncateValue(value, localDefs[index].Type);
		}
		public void Push(Value value) {
			valueStack.Push(value);
		}
		public void SetArg(Parameter arg, Value value) {
			if (arg != null)
				SetArg(arg.Index, value);
		}
		public void SetLocal(Local local, Value value) {
			if (local != null)
				SetLocal(local.Index, value);
		}
		Value TruncateValue(Value value, TypeSig type) {
			if (type == null)
				return value;
			if (protectedStackValues.ContainsKey(value))
				return value;

			switch (type.ElementType) {
			case ElementType.Boolean:
				if (value.IsInt32())
					return ((Int32Value)value).ToBoolean();
				return Int32Value.CreateUnknownBool();

			case ElementType.I1:
				if (value.IsInt32())
					return ((Int32Value)value).ToInt8();
				return Int32Value.CreateUnknown();

			case ElementType.U1:
				if (value.IsInt32())
					return ((Int32Value)value).ToUInt8();
				return Int32Value.CreateUnknownUInt8();

			case ElementType.I2:
				if (value.IsInt32())
					return ((Int32Value)value).ToInt16();
				return Int32Value.CreateUnknown();

			case ElementType.U2:
				if (value.IsInt32())
					return ((Int32Value)value).ToUInt16();
				return Int32Value.CreateUnknownUInt16();

			case ElementType.I4:
			case ElementType.U4:
				if (value.IsInt32())
					return value;
				return Int32Value.CreateUnknown();

			case ElementType.I8:
			case ElementType.U8:
				if (value.IsInt64())
					return value;
				return Int64Value.CreateUnknown();

			case ElementType.R4:
				if (value.IsReal8())
					return ((Real8Value)value).ToSingle();
				return new UnknownValue();

			case ElementType.R8:
				if (value.IsReal8())
					return value;
				return new UnknownValue();
			}
			return value;
		}
        static Value truncateValue(Value value, TypeReference typeReference)
        {
            if (typeReference == null)
                return value;
            if (DotNetUtils.isAssembly(typeReference.Scope, "mscorlib")) {
                switch (typeReference.FullName) {
                case "System.Boolean":
                    if (value.isInt32())
                        return ((Int32Value)value).toBoolean();
                    return Int32Value.createUnknownBool();

                case "System.SByte":
                    if (value.isInt32())
                        return ((Int32Value)value).toInt8();
                    return Int32Value.createUnknown();

                case "System.Byte":
                    if (value.isInt32())
                        return ((Int32Value)value).toUInt8();
                    return Int32Value.createUnknownUInt8();

                case "System.Int16":
                    if (value.isInt32())
                        return ((Int32Value)value).toInt16();
                    return Int32Value.createUnknown();

                case "System.UInt16":
                    if (value.isInt32())
                        return ((Int32Value)value).toUInt16();
                    return Int32Value.createUnknownUInt16();

                case "System.Int32":
                case "System.UInt32":
                    if (value.isInt32())
                        return value;
                    return Int32Value.createUnknown();

                case "System.Int64":
                case "System.UInt64":
                    if (value.isInt64())
                        return value;
                    return Int64Value.createUnknown();
                }
            }
            return value;
        }
Beispiel #14
0
 object createCecilOperand(OpCode opcode, Value op)
 {
     if (op is Int32Value)
         return ((Int32Value)op).value;
     if (op is StringValue)
         return ((StringValue)op).value;
     return null;
 }
Beispiel #15
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;
		}
		public void SetProtected(Value value) {
			protectedStackValues[value] = true;
		}
			object CreateDNLibOperand(OpCode opcode, Value op) {
				if (op is Int32Value)
					return ((Int32Value)op).Value;
				if (op is StringValue)
					return ((StringValue)op).value;
				return null;
			}
 public void push(Value value)
 {
     valueStack.push(value);
 }
Beispiel #19
0
 static bool VerifyValidArg(Value value)
 {
     if (value.IsInt32())
         return ((Int32Value)value).AllBitsValid();
     if (value.IsInt64())
         return ((Int64Value)value).AllBitsValid();
     if (value.IsReal8())
         return ((Real8Value)value).IsValid;
     return false;
 }
 public void setArg(ParameterDefinition arg, Value value)
 {
     setArg(index(arg), value);
 }
Beispiel #21
0
 bool fixLoadInstruction(Block block, int index, Value value)
 {
     if (value.isInt32()) {
         var intValue = (Int32Value)value;
         if (!intValue.allBitsValid())
             return false;
         block.Instructions[index] = new Instr(DotNetUtils.createLdci4(intValue.value));
         return true;
     }
     else if (value.isInt64()) {
         var intValue = (Int64Value)value;
         if (!intValue.allBitsValid())
             return false;
         block.Instructions[index] = new Instr(Instruction.Create(OpCodes.Ldc_I8, intValue.value));
         return true;
     }
     return false;
 }
 public void setLocal(VariableDefinition local, Value value)
 {
     setLocal(local.Index, value);
 }
Beispiel #23
0
 public void push(Value value)
 {
     stack.Add(value);
 }
        static Value truncateValue(Value value, TypeReference typeReference)
        {
            if (typeReference == null)
                return value;

            switch (typeReference.EType) {
            case ElementType.Boolean:
                if (value.isInt32())
                    return ((Int32Value)value).toBoolean();
                return Int32Value.createUnknownBool();

            case ElementType.I1:
                if (value.isInt32())
                    return ((Int32Value)value).toInt8();
                return Int32Value.createUnknown();

            case ElementType.U1:
                if (value.isInt32())
                    return ((Int32Value)value).toUInt8();
                return Int32Value.createUnknownUInt8();

            case ElementType.I2:
                if (value.isInt32())
                    return ((Int32Value)value).toInt16();
                return Int32Value.createUnknown();

            case ElementType.U2:
                if (value.isInt32())
                    return ((Int32Value)value).toUInt16();
                return Int32Value.createUnknownUInt16();

            case ElementType.I4:
            case ElementType.U4:
                if (value.isInt32())
                    return value;
                return Int32Value.createUnknown();

            case ElementType.I8:
            case ElementType.U8:
                if (value.isInt64())
                    return value;
                return Int64Value.createUnknown();
            }
            return value;
        }
		bool InlineMethod(MethodDef methodToInline, int instrIndex, int const1, int const2) {
			this.methodToInline = methodToInline = cflowDeobfuscator.Deobfuscate(methodToInline);

			parameters = methodToInline.Parameters;
			arg1 = parameters[parameters.Count - 2];
			arg2 = parameters[parameters.Count - 1];
			returnValue = null;

			instructionEmulator.Initialize(methodToInline);
			foreach (var arg in parameters) {
				if (!arg.IsNormalMethodParameter)
					continue;
				if (arg.Type.ElementType >= ElementType.Boolean && arg.Type.ElementType <= ElementType.U4)
					instructionEmulator.SetArg(arg, new Int32Value(0));
			}
			instructionEmulator.SetArg(arg1, new Int32Value(const1));
			instructionEmulator.SetArg(arg2, new Int32Value(const2));

			int index = 0;
			if (!EmulateInstructions(ref index, false))
				return false;
			var patcher = TryInlineOtherMethod(instrIndex, methodToInline, methodToInline.Body.Instructions[index], index + 1, 2);
			if (patcher == null)
				return false;
			if (!EmulateToReturn(patcher.afterIndex, patcher.lastInstr))
				return false;
			patcher.Patch(block);
			block.Insert(instrIndex, OpCodes.Pop.ToInstruction());
			block.Insert(instrIndex, OpCodes.Pop.ToInstruction());
			return true;
		}
Beispiel #26
0
        Value truncateValue(Value value, TypeReference typeReference)
        {
            if (typeReference == null)
                return value;
            if (protectedStackValues.ContainsKey(value))
                return value;

            switch (typeReference.EType) {
            case ElementType.Boolean:
                if (value.isInt32())
                    return ((Int32Value)value).toBoolean();
                return Int32Value.createUnknownBool();

            case ElementType.I1:
                if (value.isInt32())
                    return ((Int32Value)value).toInt8();
                return Int32Value.createUnknown();

            case ElementType.U1:
                if (value.isInt32())
                    return ((Int32Value)value).toUInt8();
                return Int32Value.createUnknownUInt8();

            case ElementType.I2:
                if (value.isInt32())
                    return ((Int32Value)value).toInt16();
                return Int32Value.createUnknown();

            case ElementType.U2:
                if (value.isInt32())
                    return ((Int32Value)value).toUInt16();
                return Int32Value.createUnknownUInt16();

            case ElementType.I4:
            case ElementType.U4:
                if (value.isInt32())
                    return value;
                return Int32Value.createUnknown();

            case ElementType.I8:
            case ElementType.U8:
                if (value.isInt64())
                    return value;
                return Int64Value.createUnknown();

            case ElementType.R4:
                if (value.isReal8())
                    return new Real8Value((float)((Real8Value)value).value);
                return new UnknownValue();

            case ElementType.R8:
                if (value.isReal8())
                    return value;
                return new UnknownValue();
            }
            return value;
        }