Emulate some more instructions
This commit is contained in:
parent
ad5fb70673
commit
3cf63a5f7e
|
@ -297,8 +297,8 @@ namespace de4dot.blocks.cflow {
|
||||||
case Code.Ldc_I8: valueStack.Push(new Int64Value((long)instr.Operand)); break;
|
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_R4: valueStack.Push(new Real8Value((float)instr.Operand)); break;
|
||||||
case Code.Ldc_R8: valueStack.Push(new Real8Value((double)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_0: valueStack.Push(Int32Value.Zero); break;
|
||||||
case Code.Ldc_I4_1: valueStack.Push(Int32Value.one); 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_2: valueStack.Push(new Int32Value(2)); break;
|
||||||
case Code.Ldc_I4_3: valueStack.Push(new Int32Value(3)); break;
|
case Code.Ldc_I4_3: valueStack.Push(new Int32Value(3)); break;
|
||||||
case Code.Ldc_I4_4: valueStack.Push(new Int32Value(4)); 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.Castclass: Emulate_Castclass(instr); break;
|
||||||
case Code.Isinst: Emulate_Isinst(instr); break;
|
case Code.Isinst: Emulate_Isinst(instr); break;
|
||||||
|
|
||||||
case Code.Add_Ovf: EmulateIntOps2(); break;
|
case Code.Add_Ovf: Emulate_Add_Ovf(instr); break;
|
||||||
case Code.Add_Ovf_Un: EmulateIntOps2(); break;
|
case Code.Add_Ovf_Un: Emulate_Add_Ovf_Un(instr); break;
|
||||||
case Code.Sub_Ovf: EmulateIntOps2(); break;
|
case Code.Sub_Ovf: Emulate_Sub_Ovf(instr); break;
|
||||||
case Code.Sub_Ovf_Un: EmulateIntOps2(); break;
|
case Code.Sub_Ovf_Un: Emulate_Sub_Ovf_Un(instr); break;
|
||||||
case Code.Mul_Ovf: EmulateIntOps2(); break;
|
case Code.Mul_Ovf: Emulate_Mul_Ovf(instr); break;
|
||||||
case Code.Mul_Ovf_Un: EmulateIntOps2(); break;
|
case Code.Mul_Ovf_Un: Emulate_Mul_Ovf_Un(instr); break;
|
||||||
|
|
||||||
case Code.Conv_Ovf_I1:
|
case Code.Conv_Ovf_I1: Emulate_Conv_Ovf_I1(instr); break;
|
||||||
case Code.Conv_Ovf_I1_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break;
|
case Code.Conv_Ovf_I1_Un: Emulate_Conv_Ovf_I1_Un(instr); break;
|
||||||
case Code.Conv_Ovf_I2:
|
case Code.Conv_Ovf_I2: Emulate_Conv_Ovf_I2(instr); break;
|
||||||
case Code.Conv_Ovf_I2_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break;
|
case Code.Conv_Ovf_I2_Un: Emulate_Conv_Ovf_I2_Un(instr); break;
|
||||||
case Code.Conv_Ovf_I4:
|
case Code.Conv_Ovf_I4: Emulate_Conv_Ovf_I4(instr); break;
|
||||||
case Code.Conv_Ovf_I4_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break;
|
case Code.Conv_Ovf_I4_Un: Emulate_Conv_Ovf_I4_Un(instr); break;
|
||||||
case Code.Conv_Ovf_I8:
|
case Code.Conv_Ovf_I8: Emulate_Conv_Ovf_I8(instr); break;
|
||||||
case Code.Conv_Ovf_I8_Un: valueStack.Pop(); valueStack.Push(Int64Value.CreateUnknown()); break;
|
case Code.Conv_Ovf_I8_Un: Emulate_Conv_Ovf_I8_Un(instr); break;
|
||||||
case Code.Conv_Ovf_U1:
|
case Code.Conv_Ovf_U1: Emulate_Conv_Ovf_U1(instr); break;
|
||||||
case Code.Conv_Ovf_U1_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknownUInt8()); break;
|
case Code.Conv_Ovf_U1_Un: Emulate_Conv_Ovf_U1_Un(instr); break;
|
||||||
case Code.Conv_Ovf_U2:
|
case Code.Conv_Ovf_U2: Emulate_Conv_Ovf_U2(instr); break;
|
||||||
case Code.Conv_Ovf_U2_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknownUInt16()); break;
|
case Code.Conv_Ovf_U2_Un: Emulate_Conv_Ovf_U2_Un(instr); break;
|
||||||
case Code.Conv_Ovf_U4:
|
case Code.Conv_Ovf_U4: Emulate_Conv_Ovf_U4(instr); break;
|
||||||
case Code.Conv_Ovf_U4_Un: valueStack.Pop(); valueStack.Push(Int32Value.CreateUnknown()); break;
|
case Code.Conv_Ovf_U4_Un: Emulate_Conv_Ovf_U4_Un(instr); break;
|
||||||
case Code.Conv_Ovf_U8:
|
case Code.Conv_Ovf_U8: Emulate_Conv_Ovf_U8(instr); break;
|
||||||
case Code.Conv_Ovf_U8_Un: valueStack.Pop(); valueStack.Push(Int64Value.CreateUnknown()); 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_I1: valueStack.Pop(2); valueStack.Push(Int32Value.CreateUnknown()); break;
|
||||||
case Code.Ldelem_I2: 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) {
|
void Emulate_Add(Instruction instr) {
|
||||||
var val2 = valueStack.Pop();
|
var val2 = valueStack.Pop();
|
||||||
var val1 = valueStack.Pop();
|
var val1 = valueStack.Pop();
|
||||||
|
@ -702,6 +862,78 @@ namespace de4dot.blocks.cflow {
|
||||||
valueStack.PushUnknown();
|
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) {
|
void Emulate_And(Instruction instr) {
|
||||||
var val2 = valueStack.Pop();
|
var val2 = valueStack.Pop();
|
||||||
var val1 = valueStack.Pop();
|
var val1 = valueStack.Pop();
|
||||||
|
@ -794,7 +1026,7 @@ namespace de4dot.blocks.cflow {
|
||||||
else if (val1.IsInt64() && val2.IsInt64())
|
else if (val1.IsInt64() && val2.IsInt64())
|
||||||
valueStack.Push(Int64Value.Ceq((Int64Value)val1, (Int64Value)val2));
|
valueStack.Push(Int64Value.Ceq((Int64Value)val1, (Int64Value)val2));
|
||||||
else if (val1.IsNull() && val2.IsNull())
|
else if (val1.IsNull() && val2.IsNull())
|
||||||
valueStack.Push(Int32Value.one);
|
valueStack.Push(Int32Value.One);
|
||||||
else
|
else
|
||||||
valueStack.Push(Int32Value.CreateUnknownBool());
|
valueStack.Push(Int32Value.CreateUnknownBool());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ using System;
|
||||||
|
|
||||||
namespace de4dot.blocks.cflow {
|
namespace de4dot.blocks.cflow {
|
||||||
public class Int32Value : Value {
|
public class Int32Value : Value {
|
||||||
public static readonly Int32Value zero = new Int32Value(0);
|
public static readonly Int32Value Zero = new Int32Value(0);
|
||||||
public static readonly Int32Value one = new Int32Value(1);
|
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 int value;
|
||||||
public readonly uint validMask;
|
public readonly uint validMask;
|
||||||
|
|
||||||
|
@ -56,6 +56,10 @@ namespace de4dot.blocks.cflow {
|
||||||
return (validMask & (1U << n)) != 0;
|
return (validMask & (1U << n)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AreBitsValid(uint bitsToTest) {
|
||||||
|
return (validMask & bitsToTest) == bitsToTest;
|
||||||
|
}
|
||||||
|
|
||||||
public static Int32Value CreateUnknownBool() {
|
public static Int32Value CreateUnknownBool() {
|
||||||
return new Int32Value(0, NO_UNKNOWN_BITS << 1);
|
return new Int32Value(0, NO_UNKNOWN_BITS << 1);
|
||||||
}
|
}
|
||||||
|
@ -214,6 +218,107 @@ namespace de4dot.blocks.cflow {
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public static Int32Value Add(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int32Value(a.value + b.value);
|
return new Int32Value(a.value + b.value);
|
||||||
|
@ -226,7 +331,7 @@ namespace de4dot.blocks.cflow {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int32Value(a.value - b.value);
|
return new Int32Value(a.value - b.value);
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +339,7 @@ namespace de4dot.blocks.cflow {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int32Value(a.value * b.value);
|
return new Int32Value(a.value * b.value);
|
||||||
if (a.IsZero() || b.IsZero())
|
if (a.IsZero() || b.IsZero())
|
||||||
return zero;
|
return Zero;
|
||||||
if (a.HasValue(1))
|
if (a.HasValue(1))
|
||||||
return b;
|
return b;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
|
@ -252,7 +357,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ReferenceEquals(a, b) && a.IsNonZero())
|
if (ReferenceEquals(a, b) && a.IsNonZero())
|
||||||
return one;
|
return One;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
return a;
|
return a;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
|
@ -268,7 +373,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ReferenceEquals(a, b) && a.IsNonZero())
|
if (ReferenceEquals(a, b) && a.IsNonZero())
|
||||||
return one;
|
return One;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
return a;
|
return a;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
|
@ -284,7 +389,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +403,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,24 +413,93 @@ namespace de4dot.blocks.cflow {
|
||||||
return CreateUnknown();
|
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) {
|
public static Int32Value And(Int32Value a, Int32Value b) {
|
||||||
int av = a.value, bv = b.value;
|
int av = a.value, bv = b.value;
|
||||||
uint am = a.validMask, bm = b.validMask;
|
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) {
|
public static Int32Value Or(Int32Value a, Int32Value b) {
|
||||||
int av = a.value, bv = b.value;
|
int av = a.value, bv = b.value;
|
||||||
uint am = a.validMask, bm = b.validMask;
|
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) {
|
public static Int32Value Xor(Int32Value a, Int32Value b) {
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
int av = a.value, bv = b.value;
|
int av = a.value, bv = b.value;
|
||||||
uint am = a.validMask, bm = b.validMask;
|
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) {
|
public static Int32Value Not(Int32Value a) {
|
||||||
|
@ -372,8 +546,8 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
static Int32Value create(Bool3 b) {
|
static Int32Value create(Bool3 b) {
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case Bool3.False: return zero;
|
case Bool3.False: return Zero;
|
||||||
case Bool3.True: return one;
|
case Bool3.True: return One;
|
||||||
default: return CreateUnknownBool();
|
default: return CreateUnknownBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ using System;
|
||||||
|
|
||||||
namespace de4dot.blocks.cflow {
|
namespace de4dot.blocks.cflow {
|
||||||
public class Int64Value : Value {
|
public class Int64Value : Value {
|
||||||
public static readonly Int64Value zero = new Int64Value(0);
|
public static readonly Int64Value Zero = new Int64Value(0);
|
||||||
public static readonly Int64Value one = new Int64Value(1);
|
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 long value;
|
||||||
public readonly ulong validMask;
|
public readonly ulong validMask;
|
||||||
|
|
||||||
|
@ -56,6 +56,10 @@ namespace de4dot.blocks.cflow {
|
||||||
return (validMask & (1UL << n)) != 0;
|
return (validMask & (1UL << n)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AreBitsValid(ulong bitsToTest) {
|
||||||
|
return (validMask & bitsToTest) == bitsToTest;
|
||||||
|
}
|
||||||
|
|
||||||
public static Int64Value CreateUnknown() {
|
public static Int64Value CreateUnknown() {
|
||||||
return new Int64Value(0, 0UL);
|
return new Int64Value(0, 0UL);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +112,114 @@ namespace de4dot.blocks.cflow {
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public static Int64Value Add(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int64Value(a.value + b.value);
|
return new Int64Value(a.value + b.value);
|
||||||
|
@ -120,7 +232,7 @@ namespace de4dot.blocks.cflow {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int64Value(a.value - b.value);
|
return new Int64Value(a.value - b.value);
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +240,7 @@ namespace de4dot.blocks.cflow {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
if (a.AllBitsValid() && b.AllBitsValid())
|
||||||
return new Int64Value(a.value * b.value);
|
return new Int64Value(a.value * b.value);
|
||||||
if (a.IsZero() || b.IsZero())
|
if (a.IsZero() || b.IsZero())
|
||||||
return zero;
|
return Zero;
|
||||||
if (a.HasValue(1))
|
if (a.HasValue(1))
|
||||||
return b;
|
return b;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
|
@ -146,7 +258,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ReferenceEquals(a, b) && a.IsNonZero())
|
if (ReferenceEquals(a, b) && a.IsNonZero())
|
||||||
return one;
|
return One;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
return a;
|
return a;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
|
@ -162,7 +274,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ReferenceEquals(a, b) && a.IsNonZero())
|
if (ReferenceEquals(a, b) && a.IsNonZero())
|
||||||
return one;
|
return One;
|
||||||
if (b.HasValue(1))
|
if (b.HasValue(1))
|
||||||
return a;
|
return a;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
|
@ -178,7 +290,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +304,7 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +314,75 @@ namespace de4dot.blocks.cflow {
|
||||||
return CreateUnknown();
|
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) {
|
public static Int64Value And(Int64Value a, Int64Value b) {
|
||||||
long av = a.value, bv = b.value;
|
long av = a.value, bv = b.value;
|
||||||
ulong am = a.validMask, bm = b.validMask;
|
ulong am = a.validMask, bm = b.validMask;
|
||||||
|
@ -216,7 +397,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Int64Value Xor(Int64Value a, Int64Value b) {
|
public static Int64Value Xor(Int64Value a, Int64Value b) {
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
long av = a.value, bv = b.value;
|
long av = a.value, bv = b.value;
|
||||||
ulong am = a.validMask, bm = b.validMask;
|
ulong am = a.validMask, bm = b.validMask;
|
||||||
return new Int64Value(av ^ bv, am & bm);
|
return new Int64Value(av ^ bv, am & bm);
|
||||||
|
@ -266,8 +447,8 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
static Int32Value Create(Bool3 b) {
|
static Int32Value Create(Bool3 b) {
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case Bool3.False: return Int32Value.zero;
|
case Bool3.False: return Int32Value.Zero;
|
||||||
case Bool3.True: return Int32Value.one;
|
case Bool3.True: return Int32Value.One;
|
||||||
default: return Int32Value.CreateUnknownBool();
|
default: return Int32Value.CreateUnknownBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,5 +49,69 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Real8Value Neg(Real8Value a) {
|
public static Real8Value Neg(Real8Value a) {
|
||||||
return new Real8Value(-a.value);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user