diff --git a/de4dot.blocks/cflow/InstructionEmulator.cs b/de4dot.blocks/cflow/InstructionEmulator.cs index 56f6a47f..0eab99ee 100644 --- a/de4dot.blocks/cflow/InstructionEmulator.cs +++ b/de4dot.blocks/cflow/InstructionEmulator.cs @@ -141,7 +141,7 @@ namespace de4dot.blocks.cflow { case ElementType.R4: if (value.IsReal8()) - return new Real8Value((float)((Real8Value)value).Value); + return ((Real8Value)value).ToSingle(); return new UnknownValue(); case ElementType.R8: @@ -870,6 +870,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Add_Ovf((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Add_Ovf((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Add_Ovf((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } @@ -882,6 +884,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Add_Ovf_Un((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Add_Ovf_Un((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Add_Ovf_Un((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } @@ -894,6 +898,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Sub_Ovf((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Sub_Ovf((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Sub_Ovf((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } @@ -906,6 +912,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Sub_Ovf_Un((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Sub_Ovf_Un((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Sub_Ovf_Un((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } @@ -918,6 +926,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Mul_Ovf((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Mul_Ovf((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Mul_Ovf((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } @@ -930,6 +940,8 @@ namespace de4dot.blocks.cflow { valueStack.Push(Int32Value.Mul_Ovf_Un((Int32Value)val1, (Int32Value)val2)); else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Mul_Ovf_Un((Int64Value)val1, (Int64Value)val2)); + else if (val1.IsReal8() && val2.IsReal8()) + valueStack.Push(Real8Value.Mul_Ovf_Un((Real8Value)val1, (Real8Value)val2)); else valueStack.PushUnknown(); } diff --git a/de4dot.blocks/cflow/Int32Value.cs b/de4dot.blocks/cflow/Int32Value.cs index 41844f33..85c9b544 100644 --- a/de4dot.blocks/cflow/Int32Value.cs +++ b/de4dot.blocks/cflow/Int32Value.cs @@ -131,6 +131,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U1(Real8Value a) { + if (!a.IsValid) + return CreateUnknownUInt8(); return new Int32Value((int)(byte)a.Value); } @@ -152,6 +154,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I1(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int32Value((int)(sbyte)a.Value); } @@ -170,6 +174,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U2(Real8Value a) { + if (!a.IsValid) + return CreateUnknownUInt16(); return new Int32Value((int)(ushort)a.Value); } @@ -191,6 +197,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I2(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int32Value((int)(short)a.Value); } @@ -203,6 +211,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U4(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int32Value((int)(uint)a.Value); } @@ -215,6 +225,8 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I4(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int32Value((int)a.Value); } diff --git a/de4dot.blocks/cflow/Int64Value.cs b/de4dot.blocks/cflow/Int64Value.cs index 0bf4a558..48a236e3 100644 --- a/de4dot.blocks/cflow/Int64Value.cs +++ b/de4dot.blocks/cflow/Int64Value.cs @@ -91,6 +91,8 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_U8(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int64Value((long)(ulong)a.Value); } @@ -109,6 +111,8 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_I8(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Int64Value((long)a.Value); } diff --git a/de4dot.blocks/cflow/Real8Value.cs b/de4dot.blocks/cflow/Real8Value.cs index 511fcbaf..d6c7bbd8 100644 --- a/de4dot.blocks/cflow/Real8Value.cs +++ b/de4dot.blocks/cflow/Real8Value.cs @@ -20,36 +20,90 @@ namespace de4dot.blocks.cflow { public class Real8Value : Value { public readonly double Value; + public readonly bool IsValid; public Real8Value(double value) : base(ValueType.Real8) { this.Value = value; + this.IsValid = true; + } + + public Real8Value(double value, bool isValid) + : base(ValueType.Real8) { + this.Value = value; + this.IsValid = isValid; + } + + public static Real8Value CreateUnknown() { + return new Real8Value(0, false); + } + + public Real8Value ToSingle() { + if (!IsValid) + return CreateUnknown(); + return new Real8Value((float)Value); } public static Real8Value Add(Real8Value a, Real8Value b) { + if (!a.IsValid || !b.IsValid) + return CreateUnknown(); return new Real8Value(a.Value + b.Value); } public static Real8Value Sub(Real8Value a, Real8Value b) { + if (!a.IsValid || !b.IsValid) + return CreateUnknown(); return new Real8Value(a.Value - b.Value); } public static Real8Value Mul(Real8Value a, Real8Value b) { + if (!a.IsValid || !b.IsValid) + return CreateUnknown(); return new Real8Value(a.Value * b.Value); } public static Real8Value Div(Real8Value a, Real8Value b) { + if (!a.IsValid || !b.IsValid) + return CreateUnknown(); return new Real8Value(a.Value / b.Value); } public static Real8Value Rem(Real8Value a, Real8Value b) { + if (!a.IsValid || !b.IsValid) + return CreateUnknown(); return new Real8Value(a.Value % b.Value); } public static Real8Value Neg(Real8Value a) { + if (!a.IsValid) + return CreateUnknown(); return new Real8Value(-a.Value); } + public static Real8Value Add_Ovf(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + + public static Real8Value Add_Ovf_Un(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + + public static Real8Value Sub_Ovf(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + + public static Real8Value Sub_Ovf_Un(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + + public static Real8Value Mul_Ovf(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + + public static Real8Value Mul_Ovf_Un(Real8Value a, Real8Value b) { + return CreateUnknown(); + } + public static Int32Value Conv_Ovf_I1(Real8Value a) { return Int32Value.CreateUnknown(); }