From 3cf63a5f7e551c8b8424ad50b9ff7236e6412116 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 15 Oct 2013 10:12:41 +0200 Subject: [PATCH 1/7] Emulate some more instructions --- de4dot.blocks/cflow/InstructionEmulator.cs | 282 +++++++++++++++++++-- de4dot.blocks/cflow/Int32Value.cs | 204 +++++++++++++-- de4dot.blocks/cflow/Int64Value.cs | 205 ++++++++++++++- de4dot.blocks/cflow/Real8Value.cs | 64 +++++ 4 files changed, 703 insertions(+), 52 deletions(-) diff --git a/de4dot.blocks/cflow/InstructionEmulator.cs b/de4dot.blocks/cflow/InstructionEmulator.cs index 3345cf64..1e9468c2 100644 --- a/de4dot.blocks/cflow/InstructionEmulator.cs +++ b/de4dot.blocks/cflow/InstructionEmulator.cs @@ -297,8 +297,8 @@ namespace de4dot.blocks.cflow { case Code.Ldc_I8: valueStack.Push(new Int64Value((long)instr.Operand)); break; case Code.Ldc_R4: valueStack.Push(new Real8Value((float)instr.Operand)); break; case Code.Ldc_R8: valueStack.Push(new Real8Value((double)instr.Operand)); break; - case Code.Ldc_I4_0: valueStack.Push(Int32Value.zero); break; - case Code.Ldc_I4_1: valueStack.Push(Int32Value.one); break; + case Code.Ldc_I4_0: valueStack.Push(Int32Value.Zero); break; + case Code.Ldc_I4_1: valueStack.Push(Int32Value.One); break; case Code.Ldc_I4_2: valueStack.Push(new Int32Value(2)); break; case Code.Ldc_I4_3: valueStack.Push(new Int32Value(3)); break; case Code.Ldc_I4_4: valueStack.Push(new Int32Value(4)); break; @@ -347,29 +347,29 @@ namespace de4dot.blocks.cflow { case Code.Castclass: Emulate_Castclass(instr); break; case Code.Isinst: Emulate_Isinst(instr); break; - case Code.Add_Ovf: EmulateIntOps2(); break; - case Code.Add_Ovf_Un: EmulateIntOps2(); break; - case Code.Sub_Ovf: EmulateIntOps2(); break; - case Code.Sub_Ovf_Un: EmulateIntOps2(); break; - case Code.Mul_Ovf: EmulateIntOps2(); break; - case Code.Mul_Ovf_Un: EmulateIntOps2(); break; + case Code.Add_Ovf: Emulate_Add_Ovf(instr); break; + case Code.Add_Ovf_Un: Emulate_Add_Ovf_Un(instr); break; + case Code.Sub_Ovf: Emulate_Sub_Ovf(instr); break; + case Code.Sub_Ovf_Un: Emulate_Sub_Ovf_Un(instr); break; + case Code.Mul_Ovf: Emulate_Mul_Ovf(instr); break; + case Code.Mul_Ovf_Un: Emulate_Mul_Ovf_Un(instr); break; - case Code.Conv_Ovf_I1: - case Code.Conv_Ovf_I1_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break; - case Code.Conv_Ovf_I2: - case Code.Conv_Ovf_I2_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break; - case Code.Conv_Ovf_I4: - case Code.Conv_Ovf_I4_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break; - case Code.Conv_Ovf_I8: - case Code.Conv_Ovf_I8_Un: valueStack.Pop(); valueStack.Push(Int64Value.CreateUnknown()); break; - case Code.Conv_Ovf_U1: - case Code.Conv_Ovf_U1_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknownUInt8()); break; - case Code.Conv_Ovf_U2: - case Code.Conv_Ovf_U2_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknownUInt16()); break; - case Code.Conv_Ovf_U4: - case Code.Conv_Ovf_U4_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break; - case Code.Conv_Ovf_U8: - case Code.Conv_Ovf_U8_Un: valueStack.Pop(); valueStack.Push(Int64Value.CreateUnknown()); break; + case Code.Conv_Ovf_I1: Emulate_Conv_Ovf_I1(instr); break; + case Code.Conv_Ovf_I1_Un: Emulate_Conv_Ovf_I1_Un(instr); break; + case Code.Conv_Ovf_I2: Emulate_Conv_Ovf_I2(instr); break; + case Code.Conv_Ovf_I2_Un: Emulate_Conv_Ovf_I2_Un(instr); break; + case Code.Conv_Ovf_I4: Emulate_Conv_Ovf_I4(instr); break; + case Code.Conv_Ovf_I4_Un: Emulate_Conv_Ovf_I4_Un(instr); break; + case Code.Conv_Ovf_I8: Emulate_Conv_Ovf_I8(instr); break; + case Code.Conv_Ovf_I8_Un: Emulate_Conv_Ovf_I8_Un(instr); break; + case Code.Conv_Ovf_U1: Emulate_Conv_Ovf_U1(instr); break; + case Code.Conv_Ovf_U1_Un: Emulate_Conv_Ovf_U1_Un(instr); break; + case Code.Conv_Ovf_U2: Emulate_Conv_Ovf_U2(instr); break; + case Code.Conv_Ovf_U2_Un: Emulate_Conv_Ovf_U2_Un(instr); break; + case Code.Conv_Ovf_U4: Emulate_Conv_Ovf_U4(instr); break; + case Code.Conv_Ovf_U4_Un: Emulate_Conv_Ovf_U4_Un(instr); break; + case Code.Conv_Ovf_U8: Emulate_Conv_Ovf_U8(instr); break; + case Code.Conv_Ovf_U8_Un: Emulate_Conv_Ovf_U8_Un(instr); break; case Code.Ldelem_I1: valueStack.Pop(2); valueStack.Push(Int32Value.CreateUnknown()); break; case Code.Ldelem_I2: valueStack.Pop(2); valueStack.Push(Int32Value.CreateUnknown()); break; @@ -595,6 +595,166 @@ namespace de4dot.blocks.cflow { } } + void Emulate_Conv_Ovf_I1(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I1((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I1((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I1((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I1_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I1_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I1_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I1_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I2(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I2((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I2((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I2((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I2_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I2_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I2_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I2_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I4(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I4((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I4((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I4((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I4_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I4_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I4_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I4_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I8(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I8((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I8((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I8((Real8Value)val1)); break; + default: valueStack.Push(Int64Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_I8_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_I8_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_I8_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_I8_Un((Real8Value)val1)); break; + default: valueStack.Push(Int64Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_U1(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U1((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U1((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U1((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknownUInt8()); break; + } + } + + void Emulate_Conv_Ovf_U1_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U1_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U1_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U1_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknownUInt8()); break; + } + } + + void Emulate_Conv_Ovf_U2(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U2((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U2((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U2((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknownUInt16()); break; + } + } + + void Emulate_Conv_Ovf_U2_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U2_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U2_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U2_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknownUInt16()); break; + } + } + + void Emulate_Conv_Ovf_U4(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U4((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U4((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U4((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_U4_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U4_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U4_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U4_Un((Real8Value)val1)); break; + default: valueStack.Push(Int32Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_U8(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U8((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U8((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U8((Real8Value)val1)); break; + default: valueStack.Push(Int64Value.CreateUnknown()); break; + } + } + + void Emulate_Conv_Ovf_U8_Un(Instruction instr) { + var val1 = valueStack.Pop(); + switch (val1.valueType) { + case ValueType.Int32: valueStack.Push(Int32Value.Conv_Ovf_U8_Un((Int32Value)val1)); break; + case ValueType.Int64: valueStack.Push(Int64Value.Conv_Ovf_U8_Un((Int64Value)val1)); break; + case ValueType.Real8: valueStack.Push(Real8Value.Conv_Ovf_U8_Un((Real8Value)val1)); break; + default: valueStack.Push(Int64Value.CreateUnknown()); break; + } + } + void Emulate_Add(Instruction instr) { var val2 = valueStack.Pop(); var val1 = valueStack.Pop(); @@ -702,6 +862,78 @@ namespace de4dot.blocks.cflow { valueStack.PushUnknown(); } + void Emulate_Add_Ovf(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + + void Emulate_Add_Ovf_Un(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + + void Emulate_Sub_Ovf(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + + void Emulate_Sub_Ovf_Un(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + + void Emulate_Mul_Ovf(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + + void Emulate_Mul_Ovf_Un(Instruction instr) { + var val2 = valueStack.Pop(); + var val1 = valueStack.Pop(); + + if (val1.IsInt32() && val2.IsInt32()) + 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 + valueStack.PushUnknown(); + } + void Emulate_And(Instruction instr) { var val2 = valueStack.Pop(); var val1 = valueStack.Pop(); @@ -794,7 +1026,7 @@ namespace de4dot.blocks.cflow { else if (val1.IsInt64() && val2.IsInt64()) valueStack.Push(Int64Value.Ceq((Int64Value)val1, (Int64Value)val2)); else if (val1.IsNull() && val2.IsNull()) - valueStack.Push(Int32Value.one); + valueStack.Push(Int32Value.One); else valueStack.Push(Int32Value.CreateUnknownBool()); } diff --git a/de4dot.blocks/cflow/Int32Value.cs b/de4dot.blocks/cflow/Int32Value.cs index f885bf6a..94008b9d 100644 --- a/de4dot.blocks/cflow/Int32Value.cs +++ b/de4dot.blocks/cflow/Int32Value.cs @@ -21,10 +21,10 @@ using System; namespace de4dot.blocks.cflow { public class Int32Value : Value { - public static readonly Int32Value zero = new Int32Value(0); - public static readonly Int32Value one = new Int32Value(1); + public static readonly Int32Value Zero = new Int32Value(0); + public static readonly Int32Value One = new Int32Value(1); - const uint NO_UNKNOWN_BITS = uint.MaxValue; + internal const uint NO_UNKNOWN_BITS = uint.MaxValue; public readonly int value; public readonly uint validMask; @@ -56,6 +56,10 @@ namespace de4dot.blocks.cflow { return (validMask & (1U << n)) != 0; } + bool AreBitsValid(uint bitsToTest) { + return (validMask & bitsToTest) == bitsToTest; + } + public static Int32Value CreateUnknownBool() { return new Int32Value(0, NO_UNKNOWN_BITS << 1); } @@ -214,6 +218,107 @@ namespace de4dot.blocks.cflow { return new Int32Value((int)a.value); } + bool CheckSign(uint mask) { + return ((uint)value & mask) == 0 || ((uint)value & mask) == mask; + } + + public static Int32Value Conv_Ovf_I1(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + !a.CheckSign(NO_UNKNOWN_BITS << 7)) + return CreateUnknown(); + return Conv_I1(a); + } + + public static Int32Value Conv_Ovf_I1_Un(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + (uint)a.value > sbyte.MaxValue) + return CreateUnknown(); + return Conv_I1(a); + } + + public static Int32Value Conv_Ovf_I2(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + !a.CheckSign(NO_UNKNOWN_BITS << 15)) + return CreateUnknown(); + return Conv_I2(a); + } + + public static Int32Value Conv_Ovf_I2_Un(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + (uint)a.value > short.MaxValue) + return CreateUnknown(); + return Conv_I2(a); + } + + public static Int32Value Conv_Ovf_I4(Int32Value a) { + return a; + } + + public static Int32Value Conv_Ovf_I4_Un(Int32Value a) { + if (!IsBitValid(a.validMask, 31) || a.value < 0) + return CreateUnknown(); + return a; + } + + public static Int64Value Conv_Ovf_I8(Int32Value a) { + ulong validMask = a.validMask; + if (IsBitValid(a.validMask, 31)) + validMask |= Int64Value.NO_UNKNOWN_BITS << 32; + return new Int64Value(a.value, validMask); + } + + public static Int64Value Conv_Ovf_I8_Un(Int32Value a) { + return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + } + + public static Int32Value Conv_Ovf_U1(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + a.value < 0 || a.value > byte.MaxValue) + return CreateUnknownUInt8(); + return Conv_U1(a); + } + + public static Int32Value Conv_Ovf_U1_Un(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 8) || + (uint)a.value > byte.MaxValue) + return CreateUnknownUInt8(); + return Conv_U1(a); + } + + public static Int32Value Conv_Ovf_U2(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + a.value < 0 || a.value > ushort.MaxValue) + return CreateUnknownUInt16(); + return Conv_U2(a); + } + + public static Int32Value Conv_Ovf_U2_Un(Int32Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 16) || + (uint)a.value > ushort.MaxValue) + return CreateUnknownUInt16(); + return Conv_U2(a); + } + + public static Int32Value Conv_Ovf_U4(Int32Value a) { + if (!IsBitValid(a.validMask, 31) || a.value < 0) + return CreateUnknown(); + return a; + } + + public static Int32Value Conv_Ovf_U4_Un(Int32Value a) { + return a; + } + + public static Int64Value Conv_Ovf_U8(Int32Value a) { + if (!IsBitValid(a.validMask, 31) || a.value < 0) + return Int64Value.CreateUnknown(); + return new Int64Value(a.value, (ulong)a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + } + + public static Int64Value Conv_Ovf_U8_Un(Int32Value a) { + return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + } + public static Int32Value Add(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return new Int32Value(a.value + b.value); @@ -226,7 +331,7 @@ namespace de4dot.blocks.cflow { if (a.AllBitsValid() && b.AllBitsValid()) return new Int32Value(a.value - b.value); if (ReferenceEquals(a, b)) - return zero; + return Zero; return CreateUnknown(); } @@ -234,7 +339,7 @@ namespace de4dot.blocks.cflow { if (a.AllBitsValid() && b.AllBitsValid()) return new Int32Value(a.value * b.value); if (a.IsZero() || b.IsZero()) - return zero; + return Zero; if (a.HasValue(1)) return b; if (b.HasValue(1)) @@ -252,7 +357,7 @@ namespace de4dot.blocks.cflow { } } if (ReferenceEquals(a, b) && a.IsNonZero()) - return one; + return One; if (b.HasValue(1)) return a; return CreateUnknown(); @@ -268,7 +373,7 @@ namespace de4dot.blocks.cflow { } } if (ReferenceEquals(a, b) && a.IsNonZero()) - return one; + return One; if (b.HasValue(1)) return a; return CreateUnknown(); @@ -284,7 +389,7 @@ namespace de4dot.blocks.cflow { } } if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1)) - return zero; + return Zero; return CreateUnknown(); } @@ -298,7 +403,7 @@ namespace de4dot.blocks.cflow { } } if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1)) - return zero; + return Zero; return CreateUnknown(); } @@ -308,24 +413,93 @@ namespace de4dot.blocks.cflow { return CreateUnknown(); } + public static Int32Value Add_Ovf(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int32Value(checked(a.value + b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int32Value Add_Ovf_Un(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + uint aa = (uint)a.value, bb = (uint)b.value; + try { + return new Int32Value((int)checked(aa + bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int32Value Sub_Ovf(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int32Value(checked(a.value - b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int32Value Sub_Ovf_Un(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + uint aa = (uint)a.value, bb = (uint)b.value; + try { + return new Int32Value((int)checked(aa - bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int32Value Mul_Ovf(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int32Value(checked(a.value * b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int32Value Mul_Ovf_Un(Int32Value a, Int32Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + uint aa = (uint)a.value, bb = (uint)b.value; + try { + return new Int32Value((int)checked(aa * bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + public static Int32Value And(Int32Value a, Int32Value b) { int av = a.value, bv = b.value; uint am = a.validMask, bm = b.validMask; - return new Int32Value(av & bv, (uint)((am & bm) | ((av & am) ^ am) | ((bv & bm) ^ bm))); + return new Int32Value(av & bv, (am & bm) | (((uint)av & am) ^ am) | (((uint)bv & bm) ^ bm)); } public static Int32Value Or(Int32Value a, Int32Value b) { int av = a.value, bv = b.value; uint am = a.validMask, bm = b.validMask; - return new Int32Value(av | bv, (uint)((am & bm) | (av & am) | (bv & bm))); + return new Int32Value(av | bv, (am & bm) | ((uint)av & am) | ((uint)bv & bm)); } public static Int32Value Xor(Int32Value a, Int32Value b) { if (ReferenceEquals(a, b)) - return zero; + return Zero; int av = a.value, bv = b.value; uint am = a.validMask, bm = b.validMask; - return new Int32Value(av ^ bv, (uint)(am & bm)); + return new Int32Value(av ^ bv, am & bm); } public static Int32Value Not(Int32Value a) { @@ -372,8 +546,8 @@ namespace de4dot.blocks.cflow { static Int32Value create(Bool3 b) { switch (b) { - case Bool3.False: return zero; - case Bool3.True: return one; + case Bool3.False: return Zero; + case Bool3.True: return One; default: return CreateUnknownBool(); } } diff --git a/de4dot.blocks/cflow/Int64Value.cs b/de4dot.blocks/cflow/Int64Value.cs index 9ec2ff41..d9f129ae 100644 --- a/de4dot.blocks/cflow/Int64Value.cs +++ b/de4dot.blocks/cflow/Int64Value.cs @@ -21,10 +21,10 @@ using System; namespace de4dot.blocks.cflow { public class Int64Value : Value { - public static readonly Int64Value zero = new Int64Value(0); - public static readonly Int64Value one = new Int64Value(1); + public static readonly Int64Value Zero = new Int64Value(0); + public static readonly Int64Value One = new Int64Value(1); - const ulong NO_UNKNOWN_BITS = ulong.MaxValue; + internal const ulong NO_UNKNOWN_BITS = ulong.MaxValue; public readonly long value; public readonly ulong validMask; @@ -56,6 +56,10 @@ namespace de4dot.blocks.cflow { return (validMask & (1UL << n)) != 0; } + bool AreBitsValid(ulong bitsToTest) { + return (validMask & bitsToTest) == bitsToTest; + } + public static Int64Value CreateUnknown() { return new Int64Value(0, 0UL); } @@ -108,6 +112,114 @@ namespace de4dot.blocks.cflow { return new Int64Value((long)a.value); } + bool CheckSign(ulong mask) { + return ((ulong)value & mask) == 0 || ((ulong)value & mask) == mask; + } + + public static Int32Value Conv_Ovf_I1(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + !a.CheckSign(NO_UNKNOWN_BITS << 7)) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I1(a); + } + + public static Int32Value Conv_Ovf_I1_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + (ulong)a.value > (ulong)sbyte.MaxValue) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I1(a); + } + + public static Int32Value Conv_Ovf_I2(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + !a.CheckSign(NO_UNKNOWN_BITS << 15)) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I2(a); + } + + public static Int32Value Conv_Ovf_I2_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + (ulong)a.value > (ulong)short.MaxValue) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I2(a); + } + + public static Int32Value Conv_Ovf_I4(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 31) || + !a.CheckSign(NO_UNKNOWN_BITS << 31)) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I4(a); + } + + public static Int32Value Conv_Ovf_I4_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 31) || + (ulong)a.value > (ulong)int.MaxValue) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_I4(a); + } + + public static Int64Value Conv_Ovf_I8(Int64Value a) { + return a; + } + + public static Int64Value Conv_Ovf_I8_Un(Int64Value a) { + if (!IsBitValid(a.validMask, 63) || a.value < 0) + return CreateUnknown(); + return a; + } + + public static Int32Value Conv_Ovf_U1(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || + a.value < 0 || a.value > byte.MaxValue) + return Int32Value.CreateUnknownUInt8(); + return Int32Value.Conv_U1(a); + } + + public static Int32Value Conv_Ovf_U1_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 8) || + (ulong)a.value > byte.MaxValue) + return Int32Value.CreateUnknownUInt8(); + return Int32Value.Conv_U1(a); + } + + public static Int32Value Conv_Ovf_U2(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || + a.value < 0 || a.value > ushort.MaxValue) + return Int32Value.CreateUnknownUInt16(); + return Int32Value.Conv_U2(a); + } + + public static Int32Value Conv_Ovf_U2_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 16) || + (ulong)a.value > ushort.MaxValue) + return Int32Value.CreateUnknownUInt16(); + return Int32Value.Conv_U2(a); + } + + public static Int32Value Conv_Ovf_U4(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 31) || + a.value < 0 || a.value > uint.MaxValue) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_U4(a); + } + + public static Int32Value Conv_Ovf_U4_Un(Int64Value a) { + if (!a.AreBitsValid(NO_UNKNOWN_BITS << 32) || + (ulong)a.value > uint.MaxValue) + return Int32Value.CreateUnknown(); + return Int32Value.Conv_U4(a); + } + + public static Int64Value Conv_Ovf_U8(Int64Value a) { + if (!IsBitValid(a.validMask, 63) || a.value < 0) + return CreateUnknown(); + return a; + } + + public static Int64Value Conv_Ovf_U8_Un(Int64Value a) { + return a; + } + public static Int64Value Add(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) return new Int64Value(a.value + b.value); @@ -120,7 +232,7 @@ namespace de4dot.blocks.cflow { if (a.AllBitsValid() && b.AllBitsValid()) return new Int64Value(a.value - b.value); if (ReferenceEquals(a, b)) - return zero; + return Zero; return CreateUnknown(); } @@ -128,7 +240,7 @@ namespace de4dot.blocks.cflow { if (a.AllBitsValid() && b.AllBitsValid()) return new Int64Value(a.value * b.value); if (a.IsZero() || b.IsZero()) - return zero; + return Zero; if (a.HasValue(1)) return b; if (b.HasValue(1)) @@ -146,7 +258,7 @@ namespace de4dot.blocks.cflow { } } if (ReferenceEquals(a, b) && a.IsNonZero()) - return one; + return One; if (b.HasValue(1)) return a; return CreateUnknown(); @@ -162,7 +274,7 @@ namespace de4dot.blocks.cflow { } } if (ReferenceEquals(a, b) && a.IsNonZero()) - return one; + return One; if (b.HasValue(1)) return a; return CreateUnknown(); @@ -178,7 +290,7 @@ namespace de4dot.blocks.cflow { } } if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1)) - return zero; + return Zero; return CreateUnknown(); } @@ -192,7 +304,7 @@ namespace de4dot.blocks.cflow { } } if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1)) - return zero; + return Zero; return CreateUnknown(); } @@ -202,6 +314,75 @@ namespace de4dot.blocks.cflow { return CreateUnknown(); } + public static Int64Value Add_Ovf(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int64Value(checked(a.value + b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int64Value Add_Ovf_Un(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + ulong aa = (ulong)a.value, bb = (ulong)b.value; + try { + return new Int64Value((long)checked(aa + bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int64Value Sub_Ovf(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int64Value(checked(a.value - b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int64Value Sub_Ovf_Un(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + ulong aa = (ulong)a.value, bb = (ulong)b.value; + try { + return new Int64Value((long)checked(aa - bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int64Value Mul_Ovf(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + try { + return new Int64Value(checked(a.value * b.value)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + + public static Int64Value Mul_Ovf_Un(Int64Value a, Int64Value b) { + if (a.AllBitsValid() && b.AllBitsValid()) { + ulong aa = (ulong)a.value, bb = (ulong)b.value; + try { + return new Int64Value((long)checked(aa * bb)); + } + catch (OverflowException) { + } + } + return CreateUnknown(); + } + public static Int64Value And(Int64Value a, Int64Value b) { long av = a.value, bv = b.value; ulong am = a.validMask, bm = b.validMask; @@ -216,7 +397,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Xor(Int64Value a, Int64Value b) { if (ReferenceEquals(a, b)) - return zero; + return Zero; long av = a.value, bv = b.value; ulong am = a.validMask, bm = b.validMask; return new Int64Value(av ^ bv, am & bm); @@ -266,8 +447,8 @@ namespace de4dot.blocks.cflow { static Int32Value Create(Bool3 b) { switch (b) { - case Bool3.False: return Int32Value.zero; - case Bool3.True: return Int32Value.one; + case Bool3.False: return Int32Value.Zero; + case Bool3.True: return Int32Value.One; default: return Int32Value.CreateUnknownBool(); } } diff --git a/de4dot.blocks/cflow/Real8Value.cs b/de4dot.blocks/cflow/Real8Value.cs index 868f2339..430ef9c6 100644 --- a/de4dot.blocks/cflow/Real8Value.cs +++ b/de4dot.blocks/cflow/Real8Value.cs @@ -49,5 +49,69 @@ namespace de4dot.blocks.cflow { public static Real8Value Neg(Real8Value a) { return new Real8Value(-a.value); } + + public static Int32Value Conv_Ovf_I1(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_I1_Un(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_I2(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_I2_Un(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_I4(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_I4_Un(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int64Value Conv_Ovf_I8(Real8Value a) { + return Int64Value.CreateUnknown(); + } + + public static Int64Value Conv_Ovf_I8_Un(Real8Value a) { + return Int64Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_U1(Real8Value a) { + return Int32Value.CreateUnknownUInt8(); + } + + public static Int32Value Conv_Ovf_U1_Un(Real8Value a) { + return Int32Value.CreateUnknownUInt8(); + } + + public static Int32Value Conv_Ovf_U2(Real8Value a) { + return Int32Value.CreateUnknownUInt16(); + } + + public static Int32Value Conv_Ovf_U2_Un(Real8Value a) { + return Int32Value.CreateUnknownUInt16(); + } + + public static Int32Value Conv_Ovf_U4(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int32Value Conv_Ovf_U4_Un(Real8Value a) { + return Int32Value.CreateUnknown(); + } + + public static Int64Value Conv_Ovf_U8(Real8Value a) { + return Int64Value.CreateUnknown(); + } + + public static Int64Value Conv_Ovf_U8_Un(Real8Value a) { + return Int64Value.CreateUnknown(); + } } } From 1dee5e80173c73ad7815d67ea1b70ce85fc46050 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 15 Oct 2013 10:12:53 +0200 Subject: [PATCH 2/7] Support latest Dotfuscator --- .../Dotfuscator/StringDecrypter.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/de4dot.code/deobfuscators/Dotfuscator/StringDecrypter.cs b/de4dot.code/deobfuscators/Dotfuscator/StringDecrypter.cs index 71466c7b..5576b00f 100644 --- a/de4dot.code/deobfuscators/Dotfuscator/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Dotfuscator/StringDecrypter.cs @@ -73,15 +73,23 @@ namespace de4dot.code.deobfuscators.Dotfuscator { continue; simpleDeobfuscator.Deobfuscate(method); - var instructions = method.Body.Instructions; - for (int i = 0; i <= instructions.Count - 3; i++) { - var ldci4 = method.Body.Instructions[i]; + var instrs = method.Body.Instructions; + for (int i = 0; i < instrs.Count - 3; i++) { + var ldarg = instrs[i]; + if (!ldarg.IsLdarg() || ldarg.GetParameterIndex() != 0) + continue; + var callvirt = instrs[i + 1]; + if (callvirt.OpCode.Code != Code.Callvirt) + continue; + var calledMethod = callvirt.Operand as MemberRef; + if (calledMethod == null || calledMethod.FullName != "System.Char[] System.String::ToCharArray()") + continue; + var stloc = instrs[i + 2]; + if (!stloc.IsStloc()) + continue; + var ldci4 = instrs[i + 3]; if (!ldci4.IsLdcI4()) continue; - if (instructions[i + 1].OpCode.Code != Code.Ldarg_1) - continue; - if (instructions[i + 2].OpCode.Code != Code.Add) - continue; var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value()); stringDecrypterMethods.Add(info.method, info); From 156bc4c7ee3e6564df24c66a9b6857319a7f17e9 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 16 Oct 2013 10:13:09 +0200 Subject: [PATCH 3/7] Rename public value -> Value, validMask -> ValidMask --- de4dot.blocks/cflow/CflowUtils.cs | 2 +- de4dot.blocks/cflow/ConstantsFolder.cs | 4 +- de4dot.blocks/cflow/InstructionEmulator.cs | 2 +- de4dot.blocks/cflow/Int32Value.cs | 196 +++++++++--------- de4dot.blocks/cflow/Int64Value.cs | 168 +++++++-------- de4dot.blocks/cflow/Real8Value.cs | 16 +- de4dot.code/deobfuscators/ArrayFinder.cs | 10 +- .../Babel_NET/BabelMethodCallInliner.cs | 6 +- .../Babel_NET/StringDecrypter.cs | 18 +- .../DeepSea/DsMethodCallInliner.cs | 4 +- .../Eazfuscator_NET/StringDecrypter.cs | 6 +- 11 files changed, 216 insertions(+), 216 deletions(-) diff --git a/de4dot.blocks/cflow/CflowUtils.cs b/de4dot.blocks/cflow/CflowUtils.cs index 1f644bf1..401f75d1 100644 --- a/de4dot.blocks/cflow/CflowUtils.cs +++ b/de4dot.blocks/cflow/CflowUtils.cs @@ -25,7 +25,7 @@ namespace de4dot.blocks.cflow { if (!intValue.AllBitsValid()) return null; - int index = intValue.value; + int index = intValue.Value; if (targets == null || index < 0 || index >= targets.Count) return fallThrough; else diff --git a/de4dot.blocks/cflow/ConstantsFolder.cs b/de4dot.blocks/cflow/ConstantsFolder.cs index 43c291de..917b5c28 100644 --- a/de4dot.blocks/cflow/ConstantsFolder.cs +++ b/de4dot.blocks/cflow/ConstantsFolder.cs @@ -89,14 +89,14 @@ namespace de4dot.blocks.cflow { var intValue = (Int32Value)value; if (!intValue.AllBitsValid()) return false; - block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.value)); + 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)); + block.Instructions[index] = new Instr(OpCodes.Ldc_I8.ToInstruction(intValue.Value)); return true; } return false; diff --git a/de4dot.blocks/cflow/InstructionEmulator.cs b/de4dot.blocks/cflow/InstructionEmulator.cs index 1e9468c2..56f6a47f 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 new Real8Value((float)((Real8Value)value).Value); return new UnknownValue(); case ElementType.R8: diff --git a/de4dot.blocks/cflow/Int32Value.cs b/de4dot.blocks/cflow/Int32Value.cs index 94008b9d..41844f33 100644 --- a/de4dot.blocks/cflow/Int32Value.cs +++ b/de4dot.blocks/cflow/Int32Value.cs @@ -25,23 +25,23 @@ namespace de4dot.blocks.cflow { public static readonly Int32Value One = new Int32Value(1); internal const uint NO_UNKNOWN_BITS = uint.MaxValue; - public readonly int value; - public readonly uint validMask; + public readonly int Value; + public readonly uint ValidMask; public Int32Value(int value) : base(ValueType.Int32) { - this.value = value; - this.validMask = NO_UNKNOWN_BITS; + this.Value = value; + this.ValidMask = NO_UNKNOWN_BITS; } public Int32Value(int value, uint validMask) : base(ValueType.Int32) { - this.value = value; - this.validMask = validMask; + this.Value = value; + this.ValidMask = validMask; } public bool HasUnknownBits() { - return validMask != NO_UNKNOWN_BITS; + return ValidMask != NO_UNKNOWN_BITS; } public bool AllBitsValid() { @@ -49,7 +49,7 @@ namespace de4dot.blocks.cflow { } bool IsBitValid(int n) { - return IsBitValid(validMask, n); + return IsBitValid(ValidMask, n); } static bool IsBitValid(uint validMask, int n) { @@ -57,7 +57,7 @@ namespace de4dot.blocks.cflow { } bool AreBitsValid(uint bitsToTest) { - return (validMask & bitsToTest) == bitsToTest; + return (ValidMask & bitsToTest) == bitsToTest; } public static Int32Value CreateUnknownBool() { @@ -81,11 +81,11 @@ namespace de4dot.blocks.cflow { } public bool IsNonZero() { - return (value & validMask) != 0; + return (Value & ValidMask) != 0; } public bool HasValue(int value) { - return AllBitsValid() && this.value == value; + return AllBitsValid() && this.Value == value; } public bool HasValue(uint value) { @@ -117,11 +117,11 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U1(Int32Value a) { - return Conv_U1(a.value, a.validMask); + return Conv_U1(a.Value, a.ValidMask); } public static Int32Value Conv_U1(Int64Value a) { - return Conv_U1((int)a.value, (uint)a.validMask); + return Conv_U1((int)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_U1(int value, uint validMask) { @@ -131,15 +131,15 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U1(Real8Value a) { - return new Int32Value((int)(byte)a.value); + return new Int32Value((int)(byte)a.Value); } public static Int32Value Conv_I1(Int32Value a) { - return Conv_I1(a.value, a.validMask); + return Conv_I1(a.Value, a.ValidMask); } public static Int32Value Conv_I1(Int64Value a) { - return Conv_I1((int)a.value, (uint)a.validMask); + return Conv_I1((int)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_I1(int value, uint validMask) { @@ -152,15 +152,15 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I1(Real8Value a) { - return new Int32Value((int)(sbyte)a.value); + return new Int32Value((int)(sbyte)a.Value); } public static Int32Value Conv_U2(Int32Value a) { - return Conv_U2(a.value, a.validMask); + return Conv_U2(a.Value, a.ValidMask); } public static Int32Value Conv_U2(Int64Value a) { - return Conv_U2((int)a.value, (uint)a.validMask); + return Conv_U2((int)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_U2(int value, uint validMask) { @@ -170,15 +170,15 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U2(Real8Value a) { - return new Int32Value((int)(ushort)a.value); + return new Int32Value((int)(ushort)a.Value); } public static Int32Value Conv_I2(Int32Value a) { - return Conv_I2(a.value, a.validMask); + return Conv_I2(a.Value, a.ValidMask); } public static Int32Value Conv_I2(Int64Value a) { - return Conv_I2((int)a.value, (uint)a.validMask); + return Conv_I2((int)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_I2(int value, uint validMask) { @@ -191,7 +191,7 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I2(Real8Value a) { - return new Int32Value((int)(short)a.value); + return new Int32Value((int)(short)a.Value); } public static Int32Value Conv_U4(Int32Value a) { @@ -199,11 +199,11 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_U4(Int64Value a) { - return new Int32Value((int)(uint)a.value, (uint)a.validMask); + return new Int32Value((int)(uint)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_U4(Real8Value a) { - return new Int32Value((int)(uint)a.value); + return new Int32Value((int)(uint)a.Value); } public static Int32Value Conv_I4(Int32Value a) { @@ -211,15 +211,15 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_I4(Int64Value a) { - return new Int32Value((int)a.value, (uint)a.validMask); + return new Int32Value((int)a.Value, (uint)a.ValidMask); } public static Int32Value Conv_I4(Real8Value a) { - return new Int32Value((int)a.value); + return new Int32Value((int)a.Value); } bool CheckSign(uint mask) { - return ((uint)value & mask) == 0 || ((uint)value & mask) == mask; + return ((uint)Value & mask) == 0 || ((uint)Value & mask) == mask; } public static Int32Value Conv_Ovf_I1(Int32Value a) { @@ -231,7 +231,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Conv_Ovf_I1_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || - (uint)a.value > sbyte.MaxValue) + (uint)a.Value > sbyte.MaxValue) return CreateUnknown(); return Conv_I1(a); } @@ -245,7 +245,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Conv_Ovf_I2_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || - (uint)a.value > short.MaxValue) + (uint)a.Value > short.MaxValue) return CreateUnknown(); return Conv_I2(a); } @@ -255,52 +255,52 @@ namespace de4dot.blocks.cflow { } public static Int32Value Conv_Ovf_I4_Un(Int32Value a) { - if (!IsBitValid(a.validMask, 31) || a.value < 0) + if (!IsBitValid(a.ValidMask, 31) || a.Value < 0) return CreateUnknown(); return a; } public static Int64Value Conv_Ovf_I8(Int32Value a) { - ulong validMask = a.validMask; - if (IsBitValid(a.validMask, 31)) + ulong validMask = a.ValidMask; + if (IsBitValid(a.ValidMask, 31)) validMask |= Int64Value.NO_UNKNOWN_BITS << 32; - return new Int64Value(a.value, validMask); + return new Int64Value(a.Value, validMask); } public static Int64Value Conv_Ovf_I8_Un(Int32Value a) { - return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + return new Int64Value((long)(uint)a.Value, a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32)); } public static Int32Value Conv_Ovf_U1(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || - a.value < 0 || a.value > byte.MaxValue) + a.Value < 0 || a.Value > byte.MaxValue) return CreateUnknownUInt8(); return Conv_U1(a); } public static Int32Value Conv_Ovf_U1_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 8) || - (uint)a.value > byte.MaxValue) + (uint)a.Value > byte.MaxValue) return CreateUnknownUInt8(); return Conv_U1(a); } public static Int32Value Conv_Ovf_U2(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || - a.value < 0 || a.value > ushort.MaxValue) + a.Value < 0 || a.Value > ushort.MaxValue) return CreateUnknownUInt16(); return Conv_U2(a); } public static Int32Value Conv_Ovf_U2_Un(Int32Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 16) || - (uint)a.value > ushort.MaxValue) + (uint)a.Value > ushort.MaxValue) return CreateUnknownUInt16(); return Conv_U2(a); } public static Int32Value Conv_Ovf_U4(Int32Value a) { - if (!IsBitValid(a.validMask, 31) || a.value < 0) + if (!IsBitValid(a.ValidMask, 31) || a.Value < 0) return CreateUnknown(); return a; } @@ -310,26 +310,26 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_Ovf_U8(Int32Value a) { - if (!IsBitValid(a.validMask, 31) || a.value < 0) + if (!IsBitValid(a.ValidMask, 31) || a.Value < 0) return Int64Value.CreateUnknown(); - return new Int64Value(a.value, (ulong)a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + return new Int64Value(a.Value, (ulong)a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32)); } public static Int64Value Conv_Ovf_U8_Un(Int32Value a) { - return new Int64Value((long)(uint)a.value, a.validMask | (Int64Value.NO_UNKNOWN_BITS << 32)); + return new Int64Value((long)(uint)a.Value, a.ValidMask | (Int64Value.NO_UNKNOWN_BITS << 32)); } public static Int32Value Add(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int32Value(a.value + b.value); + return new Int32Value(a.Value + b.Value); if (ReferenceEquals(a, b)) - return new Int32Value(a.value << 1, (a.validMask << 1) | 1); + return new Int32Value(a.Value << 1, (a.ValidMask << 1) | 1); return CreateUnknown(); } public static Int32Value Sub(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int32Value(a.value - b.value); + return new Int32Value(a.Value - b.Value); if (ReferenceEquals(a, b)) return Zero; return CreateUnknown(); @@ -337,7 +337,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Mul(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int32Value(a.value * b.value); + return new Int32Value(a.Value * b.Value); if (a.IsZero() || b.IsZero()) return Zero; if (a.HasValue(1)) @@ -350,7 +350,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Div(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value(a.value / b.value); + return new Int32Value(a.Value / b.Value); } catch (ArithmeticException) { return CreateUnknown(); @@ -366,7 +366,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Div_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value((int)((uint)a.value / (uint)b.value)); + return new Int32Value((int)((uint)a.Value / (uint)b.Value)); } catch (ArithmeticException) { return CreateUnknown(); @@ -382,7 +382,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Rem(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value(a.value % b.value); + return new Int32Value(a.Value % b.Value); } catch (ArithmeticException) { return CreateUnknown(); @@ -396,7 +396,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Rem_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value((int)((uint)a.value % (uint)b.value)); + return new Int32Value((int)((uint)a.Value % (uint)b.Value)); } catch (ArithmeticException) { return CreateUnknown(); @@ -409,14 +409,14 @@ namespace de4dot.blocks.cflow { public static Int32Value Neg(Int32Value a) { if (a.AllBitsValid()) - return new Int32Value(-a.value); + return new Int32Value(-a.Value); return CreateUnknown(); } public static Int32Value Add_Ovf(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value(checked(a.value + b.value)); + return new Int32Value(checked(a.Value + b.Value)); } catch (OverflowException) { } @@ -426,7 +426,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Add_Ovf_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - uint aa = (uint)a.value, bb = (uint)b.value; + uint aa = (uint)a.Value, bb = (uint)b.Value; try { return new Int32Value((int)checked(aa + bb)); } @@ -439,7 +439,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Sub_Ovf(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value(checked(a.value - b.value)); + return new Int32Value(checked(a.Value - b.Value)); } catch (OverflowException) { } @@ -449,7 +449,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Sub_Ovf_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - uint aa = (uint)a.value, bb = (uint)b.value; + uint aa = (uint)a.Value, bb = (uint)b.Value; try { return new Int32Value((int)checked(aa - bb)); } @@ -462,7 +462,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Mul_Ovf(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int32Value(checked(a.value * b.value)); + return new Int32Value(checked(a.Value * b.Value)); } catch (OverflowException) { } @@ -472,7 +472,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Mul_Ovf_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - uint aa = (uint)a.value, bb = (uint)b.value; + uint aa = (uint)a.Value, bb = (uint)b.Value; try { return new Int32Value((int)checked(aa * bb)); } @@ -483,65 +483,65 @@ namespace de4dot.blocks.cflow { } public static Int32Value And(Int32Value a, Int32Value b) { - int av = a.value, bv = b.value; - uint am = a.validMask, bm = b.validMask; + int av = a.Value, bv = b.Value; + uint am = a.ValidMask, bm = b.ValidMask; return new Int32Value(av & bv, (am & bm) | (((uint)av & am) ^ am) | (((uint)bv & bm) ^ bm)); } public static Int32Value Or(Int32Value a, Int32Value b) { - int av = a.value, bv = b.value; - uint am = a.validMask, bm = b.validMask; + int av = a.Value, bv = b.Value; + uint am = a.ValidMask, bm = b.ValidMask; return new Int32Value(av | bv, (am & bm) | ((uint)av & am) | ((uint)bv & bm)); } public static Int32Value Xor(Int32Value a, Int32Value b) { if (ReferenceEquals(a, b)) return Zero; - int av = a.value, bv = b.value; - uint am = a.validMask, bm = b.validMask; + int av = a.Value, bv = b.Value; + uint am = a.ValidMask, bm = b.ValidMask; return new Int32Value(av ^ bv, am & bm); } public static Int32Value Not(Int32Value a) { - return new Int32Value(~a.value, a.validMask); + return new Int32Value(~a.Value, a.ValidMask); } public static Int32Value Shl(Int32Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(int) * 8) + if (b.Value < 0 || b.Value >= sizeof(int) * 8) return CreateUnknown(); - int shift = b.value; - uint validMask = (a.validMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift)); - return new Int32Value(a.value << shift, validMask); + int shift = b.Value; + uint validMask = (a.ValidMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift)); + return new Int32Value(a.Value << shift, validMask); } public static Int32Value Shr(Int32Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(int) * 8) + if (b.Value < 0 || b.Value >= sizeof(int) * 8) return CreateUnknown(); - int shift = b.value; - uint validMask = a.validMask >> shift; + int shift = b.Value; + uint validMask = a.ValidMask >> shift; if (a.IsBitValid(sizeof(int) * 8 - 1)) validMask |= (uint.MaxValue << (sizeof(int) * 8 - shift)); - return new Int32Value(a.value >> shift, validMask); + return new Int32Value(a.Value >> shift, validMask); } public static Int32Value Shr_Un(Int32Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(int) * 8) + if (b.Value < 0 || b.Value >= sizeof(int) * 8) return CreateUnknown(); - int shift = b.value; - uint validMask = (a.validMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift)); - return new Int32Value((int)((uint)a.value >> shift), validMask); + int shift = b.Value; + uint validMask = (a.ValidMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift)); + return new Int32Value((int)((uint)a.Value >> shift), validMask); } static Int32Value create(Bool3 b) { @@ -574,27 +574,27 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareEq(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value == b.value ? Bool3.True : Bool3.False; + return a.Value == b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.True; - if ((a.value & a.validMask & b.validMask) != (b.value & a.validMask & b.validMask)) + if ((a.Value & a.ValidMask & b.ValidMask) != (b.Value & a.ValidMask & b.ValidMask)) return Bool3.False; return Bool3.Unknown; } public static Bool3 CompareNeq(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value != b.value ? Bool3.True : Bool3.False; + return a.Value != b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.False; - if ((a.value & a.validMask & b.validMask) != (b.value & a.validMask & b.validMask)) + if ((a.Value & a.ValidMask & b.ValidMask) != (b.Value & a.ValidMask & b.ValidMask)) return Bool3.True; return Bool3.Unknown; } public static Bool3 CompareGt(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value > b.value ? Bool3.True : Bool3.False; + return a.Value > b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MinValue)) return Bool3.False; // min > x => false if (b.HasValue(int.MaxValue)) @@ -604,7 +604,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGt_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (uint)a.value > (uint)b.value ? Bool3.True : Bool3.False; + return (uint)a.Value > (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MinValue)) return Bool3.False; // min > x => false if (b.HasValue(uint.MaxValue)) @@ -614,7 +614,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGe(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value >= b.value ? Bool3.True : Bool3.False; + return a.Value >= b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MaxValue)) return Bool3.True; // max >= x => true if (b.HasValue(int.MinValue)) @@ -624,7 +624,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGe_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (uint)a.value >= (uint)b.value ? Bool3.True : Bool3.False; + return (uint)a.Value >= (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MaxValue)) return Bool3.True; // max >= x => true if (b.HasValue(uint.MinValue)) @@ -634,7 +634,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLe(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value <= b.value ? Bool3.True : Bool3.False; + return a.Value <= b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MinValue)) return Bool3.True; // min <= x => true if (b.HasValue(int.MaxValue)) @@ -644,7 +644,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (uint)a.value <= (uint)b.value ? Bool3.True : Bool3.False; + return (uint)a.Value <= (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MinValue)) return Bool3.True; // min <= x => true if (b.HasValue(uint.MaxValue)) @@ -654,7 +654,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLt(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value < b.value ? Bool3.True : Bool3.False; + return a.Value < b.Value ? Bool3.True : Bool3.False; if (a.HasValue(int.MaxValue)) return Bool3.False; // max < x => false if (b.HasValue(int.MinValue)) @@ -664,7 +664,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (uint)a.value < (uint)b.value ? Bool3.True : Bool3.False; + return (uint)a.Value < (uint)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(uint.MaxValue)) return Bool3.False; // max < x => false if (b.HasValue(uint.MinValue)) @@ -674,24 +674,24 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareTrue(Int32Value a) { if (a.AllBitsValid()) - return a.value != 0 ? Bool3.True : Bool3.False; - if ((a.value & a.validMask) != 0) + return a.Value != 0 ? Bool3.True : Bool3.False; + if ((a.Value & a.ValidMask) != 0) return Bool3.True; return Bool3.Unknown; } public static Bool3 CompareFalse(Int32Value a) { if (a.AllBitsValid()) - return a.value == 0 ? Bool3.True : Bool3.False; - if ((a.value & a.validMask) != 0) + return a.Value == 0 ? Bool3.True : Bool3.False; + if ((a.Value & a.ValidMask) != 0) return Bool3.False; return Bool3.Unknown; } public override string ToString() { if (AllBitsValid()) - return value.ToString(); - return string.Format("0x{0:X8}({1:X8})", value, validMask); + return Value.ToString(); + return string.Format("0x{0:X8}({1:X8})", Value, ValidMask); } } } diff --git a/de4dot.blocks/cflow/Int64Value.cs b/de4dot.blocks/cflow/Int64Value.cs index d9f129ae..0bf4a558 100644 --- a/de4dot.blocks/cflow/Int64Value.cs +++ b/de4dot.blocks/cflow/Int64Value.cs @@ -25,23 +25,23 @@ namespace de4dot.blocks.cflow { public static readonly Int64Value One = new Int64Value(1); internal const ulong NO_UNKNOWN_BITS = ulong.MaxValue; - public readonly long value; - public readonly ulong validMask; + public readonly long Value; + public readonly ulong ValidMask; public Int64Value(long value) : base(ValueType.Int64) { - this.value = value; - this.validMask = NO_UNKNOWN_BITS; + this.Value = value; + this.ValidMask = NO_UNKNOWN_BITS; } public Int64Value(long value, ulong validMask) : base(ValueType.Int64) { - this.value = value; - this.validMask = validMask; + this.Value = value; + this.ValidMask = validMask; } bool HasUnknownBits() { - return validMask != NO_UNKNOWN_BITS; + return ValidMask != NO_UNKNOWN_BITS; } public bool AllBitsValid() { @@ -49,7 +49,7 @@ namespace de4dot.blocks.cflow { } bool IsBitValid(int n) { - return IsBitValid(validMask, n); + return IsBitValid(ValidMask, n); } static bool IsBitValid(ulong validMask, int n) { @@ -57,7 +57,7 @@ namespace de4dot.blocks.cflow { } bool AreBitsValid(ulong bitsToTest) { - return (validMask & bitsToTest) == bitsToTest; + return (ValidMask & bitsToTest) == bitsToTest; } public static Int64Value CreateUnknown() { @@ -69,11 +69,11 @@ namespace de4dot.blocks.cflow { } public bool IsNonZero() { - return ((ulong)value & validMask) != 0; + return ((ulong)Value & ValidMask) != 0; } public bool HasValue(long value) { - return AllBitsValid() && this.value == value; + return AllBitsValid() && this.Value == value; } public bool HasValue(ulong value) { @@ -81,8 +81,8 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_U8(Int32Value a) { - long value = (long)(ulong)(uint)a.value; - ulong validMask = a.validMask | (NO_UNKNOWN_BITS << 32); + long value = (long)(ulong)(uint)a.Value; + ulong validMask = a.ValidMask | (NO_UNKNOWN_BITS << 32); return new Int64Value(value, validMask); } @@ -91,12 +91,12 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_U8(Real8Value a) { - return new Int64Value((long)(ulong)a.value); + return new Int64Value((long)(ulong)a.Value); } public static Int64Value Conv_I8(Int32Value a) { - long value = a.value; - ulong validMask = a.validMask; + long value = a.Value; + ulong validMask = a.ValidMask; if (IsBitValid(validMask, 31)) validMask |= NO_UNKNOWN_BITS << 32; else @@ -109,11 +109,11 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_I8(Real8Value a) { - return new Int64Value((long)a.value); + return new Int64Value((long)a.Value); } bool CheckSign(ulong mask) { - return ((ulong)value & mask) == 0 || ((ulong)value & mask) == mask; + return ((ulong)Value & mask) == 0 || ((ulong)Value & mask) == mask; } public static Int32Value Conv_Ovf_I1(Int64Value a) { @@ -125,7 +125,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Conv_Ovf_I1_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || - (ulong)a.value > (ulong)sbyte.MaxValue) + (ulong)a.Value > (ulong)sbyte.MaxValue) return Int32Value.CreateUnknown(); return Int32Value.Conv_I1(a); } @@ -139,7 +139,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Conv_Ovf_I2_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || - (ulong)a.value > (ulong)short.MaxValue) + (ulong)a.Value > (ulong)short.MaxValue) return Int32Value.CreateUnknown(); return Int32Value.Conv_I2(a); } @@ -153,7 +153,7 @@ namespace de4dot.blocks.cflow { public static Int32Value Conv_Ovf_I4_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 31) || - (ulong)a.value > (ulong)int.MaxValue) + (ulong)a.Value > (ulong)int.MaxValue) return Int32Value.CreateUnknown(); return Int32Value.Conv_I4(a); } @@ -163,55 +163,55 @@ namespace de4dot.blocks.cflow { } public static Int64Value Conv_Ovf_I8_Un(Int64Value a) { - if (!IsBitValid(a.validMask, 63) || a.value < 0) + if (!IsBitValid(a.ValidMask, 63) || a.Value < 0) return CreateUnknown(); return a; } public static Int32Value Conv_Ovf_U1(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 7) || - a.value < 0 || a.value > byte.MaxValue) + a.Value < 0 || a.Value > byte.MaxValue) return Int32Value.CreateUnknownUInt8(); return Int32Value.Conv_U1(a); } public static Int32Value Conv_Ovf_U1_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 8) || - (ulong)a.value > byte.MaxValue) + (ulong)a.Value > byte.MaxValue) return Int32Value.CreateUnknownUInt8(); return Int32Value.Conv_U1(a); } public static Int32Value Conv_Ovf_U2(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 15) || - a.value < 0 || a.value > ushort.MaxValue) + a.Value < 0 || a.Value > ushort.MaxValue) return Int32Value.CreateUnknownUInt16(); return Int32Value.Conv_U2(a); } public static Int32Value Conv_Ovf_U2_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 16) || - (ulong)a.value > ushort.MaxValue) + (ulong)a.Value > ushort.MaxValue) return Int32Value.CreateUnknownUInt16(); return Int32Value.Conv_U2(a); } public static Int32Value Conv_Ovf_U4(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 31) || - a.value < 0 || a.value > uint.MaxValue) + a.Value < 0 || a.Value > uint.MaxValue) return Int32Value.CreateUnknown(); return Int32Value.Conv_U4(a); } public static Int32Value Conv_Ovf_U4_Un(Int64Value a) { if (!a.AreBitsValid(NO_UNKNOWN_BITS << 32) || - (ulong)a.value > uint.MaxValue) + (ulong)a.Value > uint.MaxValue) return Int32Value.CreateUnknown(); return Int32Value.Conv_U4(a); } public static Int64Value Conv_Ovf_U8(Int64Value a) { - if (!IsBitValid(a.validMask, 63) || a.value < 0) + if (!IsBitValid(a.ValidMask, 63) || a.Value < 0) return CreateUnknown(); return a; } @@ -222,15 +222,15 @@ namespace de4dot.blocks.cflow { public static Int64Value Add(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int64Value(a.value + b.value); + return new Int64Value(a.Value + b.Value); if (ReferenceEquals(a, b)) - return new Int64Value(a.value << 1, (a.validMask << 1) | 1); + return new Int64Value(a.Value << 1, (a.ValidMask << 1) | 1); return CreateUnknown(); } public static Int64Value Sub(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int64Value(a.value - b.value); + return new Int64Value(a.Value - b.Value); if (ReferenceEquals(a, b)) return Zero; return CreateUnknown(); @@ -238,7 +238,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Mul(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return new Int64Value(a.value * b.value); + return new Int64Value(a.Value * b.Value); if (a.IsZero() || b.IsZero()) return Zero; if (a.HasValue(1)) @@ -251,7 +251,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Div(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value(a.value / b.value); + return new Int64Value(a.Value / b.Value); } catch (ArithmeticException) { return CreateUnknown(); @@ -267,7 +267,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Div_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value((long)((ulong)a.value / (ulong)b.value)); + return new Int64Value((long)((ulong)a.Value / (ulong)b.Value)); } catch (ArithmeticException) { return CreateUnknown(); @@ -283,7 +283,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Rem(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value(a.value % b.value); + return new Int64Value(a.Value % b.Value); } catch (ArithmeticException) { return CreateUnknown(); @@ -297,7 +297,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Rem_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value((long)((ulong)a.value % (ulong)b.value)); + return new Int64Value((long)((ulong)a.Value % (ulong)b.Value)); } catch (ArithmeticException) { return CreateUnknown(); @@ -310,14 +310,14 @@ namespace de4dot.blocks.cflow { public static Int64Value Neg(Int64Value a) { if (a.AllBitsValid()) - return new Int64Value(-a.value); + return new Int64Value(-a.Value); return CreateUnknown(); } public static Int64Value Add_Ovf(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value(checked(a.value + b.value)); + return new Int64Value(checked(a.Value + b.Value)); } catch (OverflowException) { } @@ -327,7 +327,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Add_Ovf_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - ulong aa = (ulong)a.value, bb = (ulong)b.value; + ulong aa = (ulong)a.Value, bb = (ulong)b.Value; try { return new Int64Value((long)checked(aa + bb)); } @@ -340,7 +340,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Sub_Ovf(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value(checked(a.value - b.value)); + return new Int64Value(checked(a.Value - b.Value)); } catch (OverflowException) { } @@ -350,7 +350,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Sub_Ovf_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - ulong aa = (ulong)a.value, bb = (ulong)b.value; + ulong aa = (ulong)a.Value, bb = (ulong)b.Value; try { return new Int64Value((long)checked(aa - bb)); } @@ -363,7 +363,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Mul_Ovf(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { try { - return new Int64Value(checked(a.value * b.value)); + return new Int64Value(checked(a.Value * b.Value)); } catch (OverflowException) { } @@ -373,7 +373,7 @@ namespace de4dot.blocks.cflow { public static Int64Value Mul_Ovf_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) { - ulong aa = (ulong)a.value, bb = (ulong)b.value; + ulong aa = (ulong)a.Value, bb = (ulong)b.Value; try { return new Int64Value((long)checked(aa * bb)); } @@ -384,65 +384,65 @@ namespace de4dot.blocks.cflow { } public static Int64Value And(Int64Value a, Int64Value b) { - long av = a.value, bv = b.value; - ulong am = a.validMask, bm = b.validMask; + long av = a.Value, bv = b.Value; + ulong am = a.ValidMask, bm = b.ValidMask; return new Int64Value(av & bv, (am & bm) | (((ulong)av & am) ^ am) | (((ulong)bv & bm) ^ bm)); } public static Int64Value Or(Int64Value a, Int64Value b) { - long av = a.value, bv = b.value; - ulong am = a.validMask, bm = b.validMask; + long av = a.Value, bv = b.Value; + ulong am = a.ValidMask, bm = b.ValidMask; return new Int64Value(av | bv, (am & bm) | ((ulong)av & am) | ((ulong)bv & bm)); } public static Int64Value Xor(Int64Value a, Int64Value b) { if (ReferenceEquals(a, b)) return Zero; - long av = a.value, bv = b.value; - ulong am = a.validMask, bm = b.validMask; + long av = a.Value, bv = b.Value; + ulong am = a.ValidMask, bm = b.ValidMask; return new Int64Value(av ^ bv, am & bm); } public static Int64Value Not(Int64Value a) { - return new Int64Value(~a.value, a.validMask); + return new Int64Value(~a.Value, a.ValidMask); } public static Int64Value Shl(Int64Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(long) * 8) + if (b.Value < 0 || b.Value >= sizeof(long) * 8) return CreateUnknown(); - int shift = b.value; - ulong validMask = (a.validMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift)); - return new Int64Value(a.value << shift, validMask); + int shift = b.Value; + ulong validMask = (a.ValidMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift)); + return new Int64Value(a.Value << shift, validMask); } public static Int64Value Shr(Int64Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(long) * 8) + if (b.Value < 0 || b.Value >= sizeof(long) * 8) return CreateUnknown(); - int shift = b.value; - ulong validMask = a.validMask >> shift; + int shift = b.Value; + ulong validMask = a.ValidMask >> shift; if (a.IsBitValid(sizeof(long) * 8 - 1)) validMask |= (ulong.MaxValue << (sizeof(long) * 8 - shift)); - return new Int64Value(a.value >> shift, validMask); + return new Int64Value(a.Value >> shift, validMask); } public static Int64Value Shr_Un(Int64Value a, Int32Value b) { if (b.HasUnknownBits()) return CreateUnknown(); - if (b.value == 0) + if (b.Value == 0) return a; - if (b.value < 0 || b.value >= sizeof(long) * 8) + if (b.Value < 0 || b.Value >= sizeof(long) * 8) return CreateUnknown(); - int shift = b.value; - ulong validMask = (a.validMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift)); - return new Int64Value((long)((ulong)a.value >> shift), validMask); + int shift = b.Value; + ulong validMask = (a.ValidMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift)); + return new Int64Value((long)((ulong)a.Value >> shift), validMask); } static Int32Value Create(Bool3 b) { @@ -475,27 +475,27 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareEq(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value == b.value ? Bool3.True : Bool3.False; + return a.Value == b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.True; - if (((ulong)a.value & a.validMask & b.validMask) != ((ulong)b.value & a.validMask & b.validMask)) + if (((ulong)a.Value & a.ValidMask & b.ValidMask) != ((ulong)b.Value & a.ValidMask & b.ValidMask)) return Bool3.False; return Bool3.Unknown; } public static Bool3 CompareNeq(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value != b.value ? Bool3.True : Bool3.False; + return a.Value != b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.False; - if (((ulong)a.value & a.validMask & b.validMask) != ((ulong)b.value & a.validMask & b.validMask)) + if (((ulong)a.Value & a.ValidMask & b.ValidMask) != ((ulong)b.Value & a.ValidMask & b.ValidMask)) return Bool3.True; return Bool3.Unknown; } public static Bool3 CompareGt(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value > b.value ? Bool3.True : Bool3.False; + return a.Value > b.Value ? Bool3.True : Bool3.False; if (a.HasValue(long.MinValue)) return Bool3.False; // min > x => false if (b.HasValue(long.MaxValue)) @@ -505,7 +505,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGt_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (ulong)a.value > (ulong)b.value ? Bool3.True : Bool3.False; + return (ulong)a.Value > (ulong)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(ulong.MinValue)) return Bool3.False; // min > x => false if (b.HasValue(ulong.MaxValue)) @@ -515,7 +515,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGe(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value >= b.value ? Bool3.True : Bool3.False; + return a.Value >= b.Value ? Bool3.True : Bool3.False; if (a.HasValue(long.MaxValue)) return Bool3.True; // max >= x => true if (b.HasValue(long.MinValue)) @@ -525,7 +525,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareGe_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (ulong)a.value >= (ulong)b.value ? Bool3.True : Bool3.False; + return (ulong)a.Value >= (ulong)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(ulong.MaxValue)) return Bool3.True; // max >= x => true if (b.HasValue(ulong.MinValue)) @@ -535,7 +535,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLe(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value <= b.value ? Bool3.True : Bool3.False; + return a.Value <= b.Value ? Bool3.True : Bool3.False; if (a.HasValue(long.MinValue)) return Bool3.True; // min <= x => true if (b.HasValue(long.MaxValue)) @@ -545,7 +545,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLe_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (ulong)a.value <= (ulong)b.value ? Bool3.True : Bool3.False; + return (ulong)a.Value <= (ulong)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(ulong.MinValue)) return Bool3.True; // min <= x => true if (b.HasValue(ulong.MaxValue)) @@ -555,7 +555,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLt(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return a.value < b.value ? Bool3.True : Bool3.False; + return a.Value < b.Value ? Bool3.True : Bool3.False; if (a.HasValue(long.MaxValue)) return Bool3.False; // max < x => false if (b.HasValue(long.MinValue)) @@ -565,7 +565,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareLt_Un(Int64Value a, Int64Value b) { if (a.AllBitsValid() && b.AllBitsValid()) - return (ulong)a.value < (ulong)b.value ? Bool3.True : Bool3.False; + return (ulong)a.Value < (ulong)b.Value ? Bool3.True : Bool3.False; if (a.HasValue(ulong.MaxValue)) return Bool3.False; // max < x => false if (b.HasValue(ulong.MinValue)) @@ -575,24 +575,24 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareTrue(Int64Value a) { if (a.AllBitsValid()) - return a.value != 0 ? Bool3.True : Bool3.False; - if (((ulong)a.value & a.validMask) != 0) + return a.Value != 0 ? Bool3.True : Bool3.False; + if (((ulong)a.Value & a.ValidMask) != 0) return Bool3.True; return Bool3.Unknown; } public static Bool3 CompareFalse(Int64Value a) { if (a.AllBitsValid()) - return a.value == 0 ? Bool3.True : Bool3.False; - if (((ulong)a.value & a.validMask) != 0) + return a.Value == 0 ? Bool3.True : Bool3.False; + if (((ulong)a.Value & a.ValidMask) != 0) return Bool3.False; return Bool3.Unknown; } public override string ToString() { if (AllBitsValid()) - return value.ToString(); - return string.Format("0x{0:X8}L({1:X8})", value, validMask); + return Value.ToString(); + return string.Format("0x{0:X8}L({1:X8})", Value, ValidMask); } } } diff --git a/de4dot.blocks/cflow/Real8Value.cs b/de4dot.blocks/cflow/Real8Value.cs index 430ef9c6..511fcbaf 100644 --- a/de4dot.blocks/cflow/Real8Value.cs +++ b/de4dot.blocks/cflow/Real8Value.cs @@ -19,35 +19,35 @@ namespace de4dot.blocks.cflow { public class Real8Value : Value { - public readonly double value; + public readonly double Value; public Real8Value(double value) : base(ValueType.Real8) { - this.value = value; + this.Value = value; } public static Real8Value Add(Real8Value a, Real8Value b) { - return new Real8Value(a.value + b.value); + return new Real8Value(a.Value + b.Value); } public static Real8Value Sub(Real8Value a, Real8Value b) { - return new Real8Value(a.value - b.value); + return new Real8Value(a.Value - b.Value); } public static Real8Value Mul(Real8Value a, Real8Value b) { - return new Real8Value(a.value * b.value); + return new Real8Value(a.Value * b.Value); } public static Real8Value Div(Real8Value a, Real8Value b) { - return new Real8Value(a.value / b.value); + return new Real8Value(a.Value / b.Value); } public static Real8Value Rem(Real8Value a, Real8Value b) { - return new Real8Value(a.value % b.value); + return new Real8Value(a.Value % b.Value); } public static Real8Value Neg(Real8Value a) { - return new Real8Value(-a.value); + return new Real8Value(-a.Value); } public static Int32Value Conv_Ovf_I1(Real8Value a) { diff --git a/de4dot.code/deobfuscators/ArrayFinder.cs b/de4dot.code/deobfuscators/ArrayFinder.cs index 821405eb..af7ccc1b 100644 --- a/de4dot.code/deobfuscators/ArrayFinder.cs +++ b/de4dot.code/deobfuscators/ArrayFinder.cs @@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators { var intValue = resultValueArray[i] as Int32Value; if (intValue == null || !intValue.AllBitsValid()) return null; - resultArray[i] = (byte)intValue.value; + resultArray[i] = (byte)intValue.Value; } return resultArray; } @@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators { var intValue = resultValueArray[i] as Int32Value; if (intValue == null || !intValue.AllBitsValid()) return null; - resultArray[i] = (short)intValue.value; + resultArray[i] = (short)intValue.Value; } return resultArray; } @@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators { var intValue = resultValueArray[i] as Int32Value; if (intValue == null || !intValue.AllBitsValid()) return null; - resultArray[i] = (int)intValue.value; + resultArray[i] = (int)intValue.Value; } return resultArray; } @@ -168,8 +168,8 @@ namespace de4dot.code.deobfuscators { 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; + if (0 <= index.Value && index.Value < resultValueArray.Length) + resultValueArray[index.Value] = value; } } else diff --git a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs index eb514e26..88623545 100644 --- a/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs +++ b/de4dot.code/deobfuscators/Babel_NET/BabelMethodCallInliner.cs @@ -64,8 +64,8 @@ namespace de4dot.code.deobfuscators.Babel_NET { return false; var instr = instructions[emulateIndex]; var targets = (Instruction[])instr.Operand; - if (switchIndex.value >= 0 && switchIndex.value < targets.Length) - emulateIndex = instructions.IndexOf(targets[switchIndex.value]); + if (switchIndex.Value >= 0 && switchIndex.Value < targets.Length) + emulateIndex = instructions.IndexOf(targets[switchIndex.Value]); else emulateIndex++; return true; @@ -221,7 +221,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { var retValue2 = (Int32Value)retValue; if (!retValue2.AllBitsValid()) return false; - newValue = retValue2.value; + newValue = retValue2.Value; return true; default: diff --git a/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs index bda53b08..77b4f663 100644 --- a/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Babel_NET/StringDecrypter.cs @@ -126,7 +126,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { emulator.Push(new Int32Value(offset)); foreach (var instr in OffsetCalcInstructions) emulator.Emulate(instr); - return ((Int32Value)emulator.Pop()).value; + return ((Int32Value)emulator.Pop()).Value; } public string Decrypt(object[] args) { @@ -348,7 +348,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { case Code.Newarr: var arrayType = (ITypeDefOrRef)instr.Operand; - int arrayCount = ((Int32Value)emulator.Pop()).value; + int arrayCount = ((Int32Value)emulator.Pop()).Value; if (arrayType.FullName == "System.Char") emulator.Push(new UserValue(new char[arrayCount])); else @@ -362,7 +362,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { break; case Code.Ldelem_U1: - arrayIndex = ((Int32Value)emulator.Pop()).value; + arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) emulator.Push(new Int32Value(((byte[])((UserValue)array).obj)[arrayIndex])); @@ -372,22 +372,22 @@ namespace de4dot.code.deobfuscators.Babel_NET { case Code.Stelem_I1: value = emulator.Pop(); - arrayIndex = ((Int32Value)emulator.Pop()).value; + arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) - ((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).value; + ((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).Value; break; case Code.Stelem_I2: value = emulator.Pop(); - arrayIndex = ((Int32Value)emulator.Pop()).value; + arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); if (array is UserValue) - ((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).value; + ((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).Value; break; case Code.Ldelem_Ref: - arrayIndex = ((Int32Value)emulator.Pop()).value; + arrayIndex = ((Int32Value)emulator.Pop()).Value; array = (Value)emulator.Pop(); var userValue = array as UserValue; if (userValue != null && userValue.obj is string[]) @@ -451,7 +451,7 @@ namespace de4dot.code.deobfuscators.Babel_NET { object CreateDNLibOperand(OpCode opcode, Value op) { if (op is Int32Value) - return ((Int32Value)op).value; + return ((Int32Value)op).Value; if (op is StringValue) return ((StringValue)op).value; return null; diff --git a/de4dot.code/deobfuscators/DeepSea/DsMethodCallInliner.cs b/de4dot.code/deobfuscators/DeepSea/DsMethodCallInliner.cs index 0a23829a..7da4cc1d 100644 --- a/de4dot.code/deobfuscators/DeepSea/DsMethodCallInliner.cs +++ b/de4dot.code/deobfuscators/DeepSea/DsMethodCallInliner.cs @@ -191,8 +191,8 @@ namespace de4dot.code.deobfuscators.DeepSea { if (value == null || !value.AllBitsValid()) return false; var targets = (Instruction[])instr.Operand; - if (value.value >= 0 && value.value < targets.Length) - index = instrs.IndexOf(targets[value.value]); + if (value.Value >= 0 && value.Value < targets.Length) + index = instrs.IndexOf(targets[value.Value]); else index++; break; diff --git a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs index dd40699d..b8a3e082 100644 --- a/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs +++ b/de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs @@ -626,7 +626,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET { if (val == null || !val.AllBitsValid()) fields[field] = null; else - fields[field] = val.value; + fields[field] = val.Value; break; case Code.Call: @@ -695,8 +695,8 @@ done: ; var dcGen = dynocode.GetDynocodeGenerator(ctor.DeclaringType); if (dcGen == null) return false; - int loopLocalValue = initValue2.value; - foreach (var val in dcGen.GetValues(initValue.value)) + int loopLocalValue = initValue2.Value; + foreach (var val in dcGen.GetValues(initValue.Value)) loopLocalValue ^= val; emu.SetLocal(loopLocal, new Int32Value(loopLocalValue)); From 52111f7e393a94391ccf7da3c70c1500a4f74336 Mon Sep 17 00:00:00 2001 From: de4dot Date: Wed, 16 Oct 2013 10:13:19 +0200 Subject: [PATCH 4/7] Real8Value can now also be "invalid", like Int{32|64}Value --- de4dot.blocks/cflow/InstructionEmulator.cs | 14 +++++- de4dot.blocks/cflow/Int32Value.cs | 12 +++++ de4dot.blocks/cflow/Int64Value.cs | 4 ++ de4dot.blocks/cflow/Real8Value.cs | 54 ++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) 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(); } From ae408ab6eb36652ff735184d63968a0a189a47a4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 17 Oct 2013 19:19:21 +0200 Subject: [PATCH 5/7] Rename create() -> Create() --- de4dot.blocks/cflow/Int32Value.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/de4dot.blocks/cflow/Int32Value.cs b/de4dot.blocks/cflow/Int32Value.cs index 85c9b544..32fe2cae 100644 --- a/de4dot.blocks/cflow/Int32Value.cs +++ b/de4dot.blocks/cflow/Int32Value.cs @@ -556,7 +556,7 @@ namespace de4dot.blocks.cflow { return new Int32Value((int)((uint)a.Value >> shift), validMask); } - static Int32Value create(Bool3 b) { + static Int32Value Create(Bool3 b) { switch (b) { case Bool3.False: return Zero; case Bool3.True: return One; @@ -565,23 +565,23 @@ namespace de4dot.blocks.cflow { } public static Int32Value Ceq(Int32Value a, Int32Value b) { - return create(CompareEq(a, b)); + return Create(CompareEq(a, b)); } public static Int32Value Cgt(Int32Value a, Int32Value b) { - return create(CompareGt(a, b)); + return Create(CompareGt(a, b)); } public static Int32Value Cgt_Un(Int32Value a, Int32Value b) { - return create(CompareGt_Un(a, b)); + return Create(CompareGt_Un(a, b)); } public static Int32Value Clt(Int32Value a, Int32Value b) { - return create(CompareLt(a, b)); + return Create(CompareLt(a, b)); } public static Int32Value Clt_Un(Int32Value a, Int32Value b) { - return create(CompareLt_Un(a, b)); + return Create(CompareLt_Un(a, b)); } public static Bool3 CompareEq(Int32Value a, Int32Value b) { From 78196ffeee66e3dd94fe1ce2642ab395fc2cd137 Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 17 Oct 2013 19:26:06 +0200 Subject: [PATCH 6/7] Add (uint) casts to prevent long temp values --- de4dot.blocks/cflow/Int32Value.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/de4dot.blocks/cflow/Int32Value.cs b/de4dot.blocks/cflow/Int32Value.cs index 32fe2cae..bb838288 100644 --- a/de4dot.blocks/cflow/Int32Value.cs +++ b/de4dot.blocks/cflow/Int32Value.cs @@ -81,7 +81,7 @@ namespace de4dot.blocks.cflow { } public bool IsNonZero() { - return (Value & ValidMask) != 0; + return ((uint)Value & ValidMask) != 0; } public bool HasValue(int value) { @@ -589,7 +589,7 @@ namespace de4dot.blocks.cflow { return a.Value == b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.True; - if ((a.Value & a.ValidMask & b.ValidMask) != (b.Value & a.ValidMask & b.ValidMask)) + if (((uint)a.Value & a.ValidMask & b.ValidMask) != ((uint)b.Value & a.ValidMask & b.ValidMask)) return Bool3.False; return Bool3.Unknown; } @@ -599,7 +599,7 @@ namespace de4dot.blocks.cflow { return a.Value != b.Value ? Bool3.True : Bool3.False; if (ReferenceEquals(a, b)) return Bool3.False; - if ((a.Value & a.ValidMask & b.ValidMask) != (b.Value & a.ValidMask & b.ValidMask)) + if (((uint)a.Value & a.ValidMask & b.ValidMask) != ((uint)b.Value & a.ValidMask & b.ValidMask)) return Bool3.True; return Bool3.Unknown; } @@ -687,7 +687,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareTrue(Int32Value a) { if (a.AllBitsValid()) return a.Value != 0 ? Bool3.True : Bool3.False; - if ((a.Value & a.ValidMask) != 0) + if (((uint)a.Value & a.ValidMask) != 0) return Bool3.True; return Bool3.Unknown; } @@ -695,7 +695,7 @@ namespace de4dot.blocks.cflow { public static Bool3 CompareFalse(Int32Value a) { if (a.AllBitsValid()) return a.Value == 0 ? Bool3.True : Bool3.False; - if ((a.Value & a.ValidMask) != 0) + if (((uint)a.Value & a.ValidMask) != 0) return Bool3.False; return Bool3.Unknown; } From f05fd30dc5e8031d1015bfa62701c0628e6367de Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 17 Oct 2013 20:20:27 +0200 Subject: [PATCH 7/7] Add Real8Value.ToString() --- de4dot.blocks/cflow/Real8Value.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/de4dot.blocks/cflow/Real8Value.cs b/de4dot.blocks/cflow/Real8Value.cs index d6c7bbd8..5087046d 100644 --- a/de4dot.blocks/cflow/Real8Value.cs +++ b/de4dot.blocks/cflow/Real8Value.cs @@ -167,5 +167,11 @@ namespace de4dot.blocks.cflow { public static Int64Value Conv_Ovf_U8_Un(Real8Value a) { return Int64Value.CreateUnknown(); } + + public override string ToString() { + if (!IsValid) + return ""; + return Value.ToString(); + } } }