Merge branch 'df' into merged
Conflicts: de4dot.code/deobfuscators/Eazfuscator_NET/StringDecrypter.cs
This commit is contained in:
commit
cec4519635
|
@ -25,7 +25,7 @@ namespace de4dot.blocks.cflow {
|
||||||
if (!intValue.AllBitsValid())
|
if (!intValue.AllBitsValid())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
int index = intValue.value;
|
int index = intValue.Value;
|
||||||
if (targets == null || index < 0 || index >= targets.Count)
|
if (targets == null || index < 0 || index >= targets.Count)
|
||||||
return fallThrough;
|
return fallThrough;
|
||||||
else
|
else
|
||||||
|
|
|
@ -89,14 +89,14 @@ namespace de4dot.blocks.cflow {
|
||||||
var intValue = (Int32Value)value;
|
var intValue = (Int32Value)value;
|
||||||
if (!intValue.AllBitsValid())
|
if (!intValue.AllBitsValid())
|
||||||
return false;
|
return false;
|
||||||
block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.value));
|
block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.Value));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (value.IsInt64()) {
|
else if (value.IsInt64()) {
|
||||||
var intValue = (Int64Value)value;
|
var intValue = (Int64Value)value;
|
||||||
if (!intValue.AllBitsValid())
|
if (!intValue.AllBitsValid())
|
||||||
return false;
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
case ElementType.R4:
|
case ElementType.R4:
|
||||||
if (value.IsReal8())
|
if (value.IsReal8())
|
||||||
return new Real8Value((float)((Real8Value)value).value);
|
return ((Real8Value)value).ToSingle();
|
||||||
return new UnknownValue();
|
return new UnknownValue();
|
||||||
|
|
||||||
case ElementType.R8:
|
case ElementType.R8:
|
||||||
|
@ -324,8 +324,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;
|
||||||
|
@ -374,29 +374,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;
|
||||||
|
@ -622,6 +622,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();
|
||||||
|
@ -729,6 +889,90 @@ 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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Add_Ovf((Real8Value)val1, (Real8Value)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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Add_Ovf_Un((Real8Value)val1, (Real8Value)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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Sub_Ovf((Real8Value)val1, (Real8Value)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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Sub_Ovf_Un((Real8Value)val1, (Real8Value)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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Mul_Ovf((Real8Value)val1, (Real8Value)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 if (val1.IsReal8() && val2.IsReal8())
|
||||||
|
valueStack.Push(Real8Value.Mul_Ovf_Un((Real8Value)val1, (Real8Value)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();
|
||||||
|
@ -821,7 +1065,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,27 +21,27 @@ 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;
|
||||||
|
|
||||||
public Int32Value(int value)
|
public Int32Value(int value)
|
||||||
: base(ValueType.Int32) {
|
: base(ValueType.Int32) {
|
||||||
this.value = value;
|
this.Value = value;
|
||||||
this.validMask = NO_UNKNOWN_BITS;
|
this.ValidMask = NO_UNKNOWN_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int32Value(int value, uint validMask)
|
public Int32Value(int value, uint validMask)
|
||||||
: base(ValueType.Int32) {
|
: base(ValueType.Int32) {
|
||||||
this.value = value;
|
this.Value = value;
|
||||||
this.validMask = validMask;
|
this.ValidMask = validMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasUnknownBits() {
|
public bool HasUnknownBits() {
|
||||||
return validMask != NO_UNKNOWN_BITS;
|
return ValidMask != NO_UNKNOWN_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AllBitsValid() {
|
public bool AllBitsValid() {
|
||||||
|
@ -49,13 +49,17 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBitValid(int n) {
|
bool IsBitValid(int n) {
|
||||||
return IsBitValid(validMask, n);
|
return IsBitValid(ValidMask, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsBitValid(uint validMask, int n) {
|
static bool IsBitValid(uint validMask, int n) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -77,11 +81,11 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNonZero() {
|
public bool IsNonZero() {
|
||||||
return (value & validMask) != 0;
|
return ((uint)Value & ValidMask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasValue(int value) {
|
public bool HasValue(int value) {
|
||||||
return AllBitsValid() && this.value == value;
|
return AllBitsValid() && this.Value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasValue(uint value) {
|
public bool HasValue(uint value) {
|
||||||
|
@ -113,11 +117,11 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U1(Int32Value a) {
|
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) {
|
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) {
|
public static Int32Value Conv_U1(int value, uint validMask) {
|
||||||
|
@ -127,15 +131,17 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U1(Real8Value a) {
|
public static Int32Value Conv_U1(Real8Value a) {
|
||||||
return new Int32Value((int)(byte)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknownUInt8();
|
||||||
|
return new Int32Value((int)(byte)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I1(Int32Value a) {
|
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) {
|
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) {
|
public static Int32Value Conv_I1(int value, uint validMask) {
|
||||||
|
@ -148,15 +154,17 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I1(Real8Value a) {
|
public static Int32Value Conv_I1(Real8Value a) {
|
||||||
return new Int32Value((int)(sbyte)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Int32Value((int)(sbyte)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U2(Int32Value a) {
|
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) {
|
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) {
|
public static Int32Value Conv_U2(int value, uint validMask) {
|
||||||
|
@ -166,15 +174,17 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U2(Real8Value a) {
|
public static Int32Value Conv_U2(Real8Value a) {
|
||||||
return new Int32Value((int)(ushort)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknownUInt16();
|
||||||
|
return new Int32Value((int)(ushort)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I2(Int32Value a) {
|
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) {
|
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) {
|
public static Int32Value Conv_I2(int value, uint validMask) {
|
||||||
|
@ -187,7 +197,9 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I2(Real8Value a) {
|
public static Int32Value Conv_I2(Real8Value a) {
|
||||||
return new Int32Value((int)(short)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Int32Value((int)(short)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U4(Int32Value a) {
|
public static Int32Value Conv_U4(Int32Value a) {
|
||||||
|
@ -195,11 +207,13 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_U4(Int64Value a) {
|
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) {
|
public static Int32Value Conv_U4(Real8Value a) {
|
||||||
return new Int32Value((int)(uint)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Int32Value((int)(uint)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I4(Int32Value a) {
|
public static Int32Value Conv_I4(Int32Value a) {
|
||||||
|
@ -207,34 +221,137 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Conv_I4(Int64Value a) {
|
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) {
|
public static Int32Value Conv_I4(Real8Value a) {
|
||||||
return new Int32Value((int)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
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);
|
||||||
if (ReferenceEquals(a, b))
|
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();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Sub(Int32Value a, Int32Value b) {
|
public static Int32Value Sub(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);
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Mul(Int32Value a, Int32Value b) {
|
public static Int32Value Mul(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);
|
||||||
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))
|
||||||
|
@ -245,14 +362,14 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int32Value Div(Int32Value a, Int32Value b) {
|
public static Int32Value Div(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int32Value(a.value / b.value);
|
return new Int32Value(a.Value / b.Value);
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
@ -261,14 +378,14 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int32Value Div_Un(Int32Value a, Int32Value b) {
|
public static Int32Value Div_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int32Value((int)((uint)a.value / (uint)b.value));
|
return new Int32Value((int)((uint)a.Value / (uint)b.Value));
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
@ -277,150 +394,219 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int32Value Rem(Int32Value a, Int32Value b) {
|
public static Int32Value Rem(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int32Value(a.value % b.value);
|
return new Int32Value(a.Value % b.Value);
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Rem_Un(Int32Value a, Int32Value b) {
|
public static Int32Value Rem_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int32Value((int)((uint)a.value % (uint)b.value));
|
return new Int32Value((int)((uint)a.Value % (uint)b.Value));
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Neg(Int32Value a) {
|
public static Int32Value Neg(Int32Value a) {
|
||||||
if (a.AllBitsValid())
|
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));
|
||||||
|
}
|
||||||
|
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();
|
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) {
|
||||||
return new Int32Value(~a.value, a.validMask);
|
return new Int32Value(~a.Value, a.ValidMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Shl(Int32Value a, Int32Value b) {
|
public static Int32Value Shl(Int32Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(int) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(int) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
uint validMask = (a.validMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift));
|
uint validMask = (a.ValidMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift));
|
||||||
return new Int32Value(a.value << shift, validMask);
|
return new Int32Value(a.Value << shift, validMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Shr(Int32Value a, Int32Value b) {
|
public static Int32Value Shr(Int32Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(int) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(int) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
uint validMask = a.validMask >> shift;
|
uint validMask = a.ValidMask >> shift;
|
||||||
if (a.IsBitValid(sizeof(int) * 8 - 1))
|
if (a.IsBitValid(sizeof(int) * 8 - 1))
|
||||||
validMask |= (uint.MaxValue << (sizeof(int) * 8 - shift));
|
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) {
|
public static Int32Value Shr_Un(Int32Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(int) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(int) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
uint validMask = (a.validMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift));
|
uint validMask = (a.ValidMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift));
|
||||||
return new Int32Value((int)((uint)a.value >> shift), validMask);
|
return new Int32Value((int)((uint)a.Value >> shift), validMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int32Value Ceq(Int32Value a, Int32Value b) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
public static Bool3 CompareEq(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (ReferenceEquals(a, b))
|
||||||
return Bool3.True;
|
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.False;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareNeq(Int32Value a, Int32Value b) {
|
public static Bool3 CompareNeq(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (ReferenceEquals(a, b))
|
||||||
return Bool3.False;
|
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.True;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareGt(Int32Value a, Int32Value b) {
|
public static Bool3 CompareGt(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(int.MinValue))
|
||||||
return Bool3.False; // min > x => false
|
return Bool3.False; // min > x => false
|
||||||
if (b.HasValue(int.MaxValue))
|
if (b.HasValue(int.MaxValue))
|
||||||
|
@ -430,7 +616,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGt_Un(Int32Value a, Int32Value b) {
|
public static Bool3 CompareGt_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(uint.MinValue))
|
||||||
return Bool3.False; // min > x => false
|
return Bool3.False; // min > x => false
|
||||||
if (b.HasValue(uint.MaxValue))
|
if (b.HasValue(uint.MaxValue))
|
||||||
|
@ -440,7 +626,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGe(Int32Value a, Int32Value b) {
|
public static Bool3 CompareGe(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(int.MaxValue))
|
||||||
return Bool3.True; // max >= x => true
|
return Bool3.True; // max >= x => true
|
||||||
if (b.HasValue(int.MinValue))
|
if (b.HasValue(int.MinValue))
|
||||||
|
@ -450,7 +636,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGe_Un(Int32Value a, Int32Value b) {
|
public static Bool3 CompareGe_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(uint.MaxValue))
|
||||||
return Bool3.True; // max >= x => true
|
return Bool3.True; // max >= x => true
|
||||||
if (b.HasValue(uint.MinValue))
|
if (b.HasValue(uint.MinValue))
|
||||||
|
@ -460,7 +646,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLe(Int32Value a, Int32Value b) {
|
public static Bool3 CompareLe(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(int.MinValue))
|
||||||
return Bool3.True; // min <= x => true
|
return Bool3.True; // min <= x => true
|
||||||
if (b.HasValue(int.MaxValue))
|
if (b.HasValue(int.MaxValue))
|
||||||
|
@ -470,7 +656,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) {
|
public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(uint.MinValue))
|
||||||
return Bool3.True; // min <= x => true
|
return Bool3.True; // min <= x => true
|
||||||
if (b.HasValue(uint.MaxValue))
|
if (b.HasValue(uint.MaxValue))
|
||||||
|
@ -480,7 +666,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLt(Int32Value a, Int32Value b) {
|
public static Bool3 CompareLt(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(int.MaxValue))
|
||||||
return Bool3.False; // max < x => false
|
return Bool3.False; // max < x => false
|
||||||
if (b.HasValue(int.MinValue))
|
if (b.HasValue(int.MinValue))
|
||||||
|
@ -490,7 +676,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) {
|
public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(uint.MaxValue))
|
||||||
return Bool3.False; // max < x => false
|
return Bool3.False; // max < x => false
|
||||||
if (b.HasValue(uint.MinValue))
|
if (b.HasValue(uint.MinValue))
|
||||||
|
@ -500,24 +686,24 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareTrue(Int32Value a) {
|
public static Bool3 CompareTrue(Int32Value a) {
|
||||||
if (a.AllBitsValid())
|
if (a.AllBitsValid())
|
||||||
return a.value != 0 ? Bool3.True : Bool3.False;
|
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.True;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareFalse(Int32Value a) {
|
public static Bool3 CompareFalse(Int32Value a) {
|
||||||
if (a.AllBitsValid())
|
if (a.AllBitsValid())
|
||||||
return a.value == 0 ? Bool3.True : Bool3.False;
|
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.False;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
if (AllBitsValid())
|
if (AllBitsValid())
|
||||||
return value.ToString();
|
return Value.ToString();
|
||||||
return string.Format("0x{0:X8}({1:X8})", value, validMask);
|
return string.Format("0x{0:X8}({1:X8})", Value, ValidMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,27 +21,27 @@ 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;
|
||||||
|
|
||||||
public Int64Value(long value)
|
public Int64Value(long value)
|
||||||
: base(ValueType.Int64) {
|
: base(ValueType.Int64) {
|
||||||
this.value = value;
|
this.Value = value;
|
||||||
this.validMask = NO_UNKNOWN_BITS;
|
this.ValidMask = NO_UNKNOWN_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Int64Value(long value, ulong validMask)
|
public Int64Value(long value, ulong validMask)
|
||||||
: base(ValueType.Int64) {
|
: base(ValueType.Int64) {
|
||||||
this.value = value;
|
this.Value = value;
|
||||||
this.validMask = validMask;
|
this.ValidMask = validMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasUnknownBits() {
|
bool HasUnknownBits() {
|
||||||
return validMask != NO_UNKNOWN_BITS;
|
return ValidMask != NO_UNKNOWN_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AllBitsValid() {
|
public bool AllBitsValid() {
|
||||||
|
@ -49,13 +49,17 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBitValid(int n) {
|
bool IsBitValid(int n) {
|
||||||
return IsBitValid(validMask, n);
|
return IsBitValid(ValidMask, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsBitValid(ulong validMask, int n) {
|
static bool IsBitValid(ulong validMask, int n) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -65,11 +69,11 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsNonZero() {
|
public bool IsNonZero() {
|
||||||
return ((ulong)value & validMask) != 0;
|
return ((ulong)Value & ValidMask) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasValue(long value) {
|
public bool HasValue(long value) {
|
||||||
return AllBitsValid() && this.value == value;
|
return AllBitsValid() && this.Value == value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasValue(ulong value) {
|
public bool HasValue(ulong value) {
|
||||||
|
@ -77,8 +81,8 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Conv_U8(Int32Value a) {
|
public static Int64Value Conv_U8(Int32Value a) {
|
||||||
long value = (long)(ulong)(uint)a.value;
|
long value = (long)(ulong)(uint)a.Value;
|
||||||
ulong validMask = a.validMask | (NO_UNKNOWN_BITS << 32);
|
ulong validMask = a.ValidMask | (NO_UNKNOWN_BITS << 32);
|
||||||
return new Int64Value(value, validMask);
|
return new Int64Value(value, validMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +91,14 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Conv_U8(Real8Value a) {
|
public static Int64Value Conv_U8(Real8Value a) {
|
||||||
return new Int64Value((long)(ulong)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Int64Value((long)(ulong)a.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Conv_I8(Int32Value a) {
|
public static Int64Value Conv_I8(Int32Value a) {
|
||||||
long value = a.value;
|
long value = a.Value;
|
||||||
ulong validMask = a.validMask;
|
ulong validMask = a.ValidMask;
|
||||||
if (IsBitValid(validMask, 31))
|
if (IsBitValid(validMask, 31))
|
||||||
validMask |= NO_UNKNOWN_BITS << 32;
|
validMask |= NO_UNKNOWN_BITS << 32;
|
||||||
else
|
else
|
||||||
|
@ -105,30 +111,140 @@ namespace de4dot.blocks.cflow {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Conv_I8(Real8Value a) {
|
public static Int64Value Conv_I8(Real8Value a) {
|
||||||
return new Int64Value((long)a.value);
|
if (!a.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
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);
|
||||||
if (ReferenceEquals(a, b))
|
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();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Sub(Int64Value a, Int64Value b) {
|
public static Int64Value Sub(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);
|
||||||
if (ReferenceEquals(a, b))
|
if (ReferenceEquals(a, b))
|
||||||
return zero;
|
return Zero;
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Mul(Int64Value a, Int64Value b) {
|
public static Int64Value Mul(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);
|
||||||
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))
|
||||||
|
@ -139,14 +255,14 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int64Value Div(Int64Value a, Int64Value b) {
|
public static Int64Value Div(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int64Value(a.value / b.value);
|
return new Int64Value(a.Value / b.Value);
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
@ -155,14 +271,14 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int64Value Div_Un(Int64Value a, Int64Value b) {
|
public static Int64Value Div_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int64Value((long)((ulong)a.value / (ulong)b.value));
|
return new Int64Value((long)((ulong)a.Value / (ulong)b.Value));
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
@ -171,103 +287,172 @@ namespace de4dot.blocks.cflow {
|
||||||
public static Int64Value Rem(Int64Value a, Int64Value b) {
|
public static Int64Value Rem(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int64Value(a.value % b.value);
|
return new Int64Value(a.Value % b.Value);
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Rem_Un(Int64Value a, Int64Value b) {
|
public static Int64Value Rem_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid()) {
|
if (a.AllBitsValid() && b.AllBitsValid()) {
|
||||||
try {
|
try {
|
||||||
return new Int64Value((long)((ulong)a.value % (ulong)b.value));
|
return new Int64Value((long)((ulong)a.Value % (ulong)b.Value));
|
||||||
}
|
}
|
||||||
catch (ArithmeticException) {
|
catch (ArithmeticException) {
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Neg(Int64Value a) {
|
public static Int64Value Neg(Int64Value a) {
|
||||||
if (a.AllBitsValid())
|
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));
|
||||||
|
}
|
||||||
|
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();
|
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;
|
||||||
return new Int64Value(av & bv, (am & bm) | (((ulong)av & am) ^ am) | (((ulong)bv & bm) ^ bm));
|
return new Int64Value(av & bv, (am & bm) | (((ulong)av & am) ^ am) | (((ulong)bv & bm) ^ bm));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Or(Int64Value a, Int64Value b) {
|
public static Int64Value Or(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;
|
||||||
return new Int64Value(av | bv, (am & bm) | ((ulong)av & am) | ((ulong)bv & bm));
|
return new Int64Value(av | bv, (am & bm) | ((ulong)av & am) | ((ulong)bv & bm));
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Not(Int64Value a) {
|
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) {
|
public static Int64Value Shl(Int64Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(long) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(long) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
ulong validMask = (a.validMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift));
|
ulong validMask = (a.ValidMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift));
|
||||||
return new Int64Value(a.value << shift, validMask);
|
return new Int64Value(a.Value << shift, validMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int64Value Shr(Int64Value a, Int32Value b) {
|
public static Int64Value Shr(Int64Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(long) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(long) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
ulong validMask = a.validMask >> shift;
|
ulong validMask = a.ValidMask >> shift;
|
||||||
if (a.IsBitValid(sizeof(long) * 8 - 1))
|
if (a.IsBitValid(sizeof(long) * 8 - 1))
|
||||||
validMask |= (ulong.MaxValue << (sizeof(long) * 8 - shift));
|
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) {
|
public static Int64Value Shr_Un(Int64Value a, Int32Value b) {
|
||||||
if (b.HasUnknownBits())
|
if (b.HasUnknownBits())
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
if (b.value == 0)
|
if (b.Value == 0)
|
||||||
return a;
|
return a;
|
||||||
if (b.value < 0 || b.value >= sizeof(long) * 8)
|
if (b.Value < 0 || b.Value >= sizeof(long) * 8)
|
||||||
return CreateUnknown();
|
return CreateUnknown();
|
||||||
int shift = b.value;
|
int shift = b.Value;
|
||||||
ulong validMask = (a.validMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift));
|
ulong validMask = (a.ValidMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift));
|
||||||
return new Int64Value((long)((ulong)a.value >> shift), validMask);
|
return new Int64Value((long)((ulong)a.Value >> shift), validMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,27 +479,27 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareEq(Int64Value a, Int64Value b) {
|
public static Bool3 CompareEq(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (ReferenceEquals(a, b))
|
||||||
return Bool3.True;
|
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.False;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareNeq(Int64Value a, Int64Value b) {
|
public static Bool3 CompareNeq(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (ReferenceEquals(a, b))
|
||||||
return Bool3.False;
|
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.True;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareGt(Int64Value a, Int64Value b) {
|
public static Bool3 CompareGt(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(long.MinValue))
|
||||||
return Bool3.False; // min > x => false
|
return Bool3.False; // min > x => false
|
||||||
if (b.HasValue(long.MaxValue))
|
if (b.HasValue(long.MaxValue))
|
||||||
|
@ -324,7 +509,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGt_Un(Int64Value a, Int64Value b) {
|
public static Bool3 CompareGt_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(ulong.MinValue))
|
||||||
return Bool3.False; // min > x => false
|
return Bool3.False; // min > x => false
|
||||||
if (b.HasValue(ulong.MaxValue))
|
if (b.HasValue(ulong.MaxValue))
|
||||||
|
@ -334,7 +519,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGe(Int64Value a, Int64Value b) {
|
public static Bool3 CompareGe(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(long.MaxValue))
|
||||||
return Bool3.True; // max >= x => true
|
return Bool3.True; // max >= x => true
|
||||||
if (b.HasValue(long.MinValue))
|
if (b.HasValue(long.MinValue))
|
||||||
|
@ -344,7 +529,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareGe_Un(Int64Value a, Int64Value b) {
|
public static Bool3 CompareGe_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(ulong.MaxValue))
|
||||||
return Bool3.True; // max >= x => true
|
return Bool3.True; // max >= x => true
|
||||||
if (b.HasValue(ulong.MinValue))
|
if (b.HasValue(ulong.MinValue))
|
||||||
|
@ -354,7 +539,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLe(Int64Value a, Int64Value b) {
|
public static Bool3 CompareLe(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(long.MinValue))
|
||||||
return Bool3.True; // min <= x => true
|
return Bool3.True; // min <= x => true
|
||||||
if (b.HasValue(long.MaxValue))
|
if (b.HasValue(long.MaxValue))
|
||||||
|
@ -364,7 +549,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLe_Un(Int64Value a, Int64Value b) {
|
public static Bool3 CompareLe_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(ulong.MinValue))
|
||||||
return Bool3.True; // min <= x => true
|
return Bool3.True; // min <= x => true
|
||||||
if (b.HasValue(ulong.MaxValue))
|
if (b.HasValue(ulong.MaxValue))
|
||||||
|
@ -374,7 +559,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLt(Int64Value a, Int64Value b) {
|
public static Bool3 CompareLt(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(long.MaxValue))
|
||||||
return Bool3.False; // max < x => false
|
return Bool3.False; // max < x => false
|
||||||
if (b.HasValue(long.MinValue))
|
if (b.HasValue(long.MinValue))
|
||||||
|
@ -384,7 +569,7 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareLt_Un(Int64Value a, Int64Value b) {
|
public static Bool3 CompareLt_Un(Int64Value a, Int64Value b) {
|
||||||
if (a.AllBitsValid() && b.AllBitsValid())
|
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))
|
if (a.HasValue(ulong.MaxValue))
|
||||||
return Bool3.False; // max < x => false
|
return Bool3.False; // max < x => false
|
||||||
if (b.HasValue(ulong.MinValue))
|
if (b.HasValue(ulong.MinValue))
|
||||||
|
@ -394,24 +579,24 @@ namespace de4dot.blocks.cflow {
|
||||||
|
|
||||||
public static Bool3 CompareTrue(Int64Value a) {
|
public static Bool3 CompareTrue(Int64Value a) {
|
||||||
if (a.AllBitsValid())
|
if (a.AllBitsValid())
|
||||||
return a.value != 0 ? Bool3.True : Bool3.False;
|
return a.Value != 0 ? Bool3.True : Bool3.False;
|
||||||
if (((ulong)a.value & a.validMask) != 0)
|
if (((ulong)a.Value & a.ValidMask) != 0)
|
||||||
return Bool3.True;
|
return Bool3.True;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bool3 CompareFalse(Int64Value a) {
|
public static Bool3 CompareFalse(Int64Value a) {
|
||||||
if (a.AllBitsValid())
|
if (a.AllBitsValid())
|
||||||
return a.value == 0 ? Bool3.True : Bool3.False;
|
return a.Value == 0 ? Bool3.True : Bool3.False;
|
||||||
if (((ulong)a.value & a.validMask) != 0)
|
if (((ulong)a.Value & a.ValidMask) != 0)
|
||||||
return Bool3.False;
|
return Bool3.False;
|
||||||
return Bool3.Unknown;
|
return Bool3.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
if (AllBitsValid())
|
if (AllBitsValid())
|
||||||
return value.ToString();
|
return Value.ToString();
|
||||||
return string.Format("0x{0:X8}L({1:X8})", value, validMask);
|
return string.Format("0x{0:X8}L({1:X8})", Value, ValidMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,35 +19,159 @@
|
||||||
|
|
||||||
namespace de4dot.blocks.cflow {
|
namespace de4dot.blocks.cflow {
|
||||||
public class Real8Value : Value {
|
public class Real8Value : Value {
|
||||||
public readonly double value;
|
public readonly double Value;
|
||||||
|
public readonly bool IsValid;
|
||||||
|
|
||||||
public Real8Value(double value)
|
public Real8Value(double value)
|
||||||
: base(ValueType.Real8) {
|
: base(ValueType.Real8) {
|
||||||
this.value = value;
|
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) {
|
public static Real8Value Add(Real8Value a, Real8Value b) {
|
||||||
return new Real8Value(a.value + b.value);
|
if (!a.IsValid || !b.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Real8Value(a.Value + b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Real8Value Sub(Real8Value a, Real8Value b) {
|
public static Real8Value Sub(Real8Value a, Real8Value b) {
|
||||||
return new Real8Value(a.value - b.value);
|
if (!a.IsValid || !b.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Real8Value(a.Value - b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Real8Value Mul(Real8Value a, Real8Value b) {
|
public static Real8Value Mul(Real8Value a, Real8Value b) {
|
||||||
return new Real8Value(a.value * b.value);
|
if (!a.IsValid || !b.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Real8Value(a.Value * b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Real8Value Div(Real8Value a, Real8Value b) {
|
public static Real8Value Div(Real8Value a, Real8Value b) {
|
||||||
return new Real8Value(a.value / b.value);
|
if (!a.IsValid || !b.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Real8Value(a.Value / b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Real8Value Rem(Real8Value a, Real8Value b) {
|
public static Real8Value Rem(Real8Value a, Real8Value b) {
|
||||||
return new Real8Value(a.value % b.value);
|
if (!a.IsValid || !b.IsValid)
|
||||||
|
return CreateUnknown();
|
||||||
|
return new Real8Value(a.Value % b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Real8Value Neg(Real8Value a) {
|
public static Real8Value Neg(Real8Value a) {
|
||||||
return new Real8Value(-a.value);
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
if (!IsValid)
|
||||||
|
return "<INVALID_REAL8>";
|
||||||
|
return Value.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var intValue = resultValueArray[i] as Int32Value;
|
var intValue = resultValueArray[i] as Int32Value;
|
||||||
if (intValue == null || !intValue.AllBitsValid())
|
if (intValue == null || !intValue.AllBitsValid())
|
||||||
return null;
|
return null;
|
||||||
resultArray[i] = (byte)intValue.value;
|
resultArray[i] = (byte)intValue.Value;
|
||||||
}
|
}
|
||||||
return resultArray;
|
return resultArray;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var intValue = resultValueArray[i] as Int32Value;
|
var intValue = resultValueArray[i] as Int32Value;
|
||||||
if (intValue == null || !intValue.AllBitsValid())
|
if (intValue == null || !intValue.AllBitsValid())
|
||||||
return null;
|
return null;
|
||||||
resultArray[i] = (short)intValue.value;
|
resultArray[i] = (short)intValue.Value;
|
||||||
}
|
}
|
||||||
return resultArray;
|
return resultArray;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
var intValue = resultValueArray[i] as Int32Value;
|
var intValue = resultValueArray[i] as Int32Value;
|
||||||
if (intValue == null || !intValue.AllBitsValid())
|
if (intValue == null || !intValue.AllBitsValid())
|
||||||
return null;
|
return null;
|
||||||
resultArray[i] = (int)intValue.value;
|
resultArray[i] = (int)intValue.Value;
|
||||||
}
|
}
|
||||||
return resultArray;
|
return resultArray;
|
||||||
}
|
}
|
||||||
|
@ -168,8 +168,8 @@ namespace de4dot.code.deobfuscators {
|
||||||
var index = emulator.Pop() as Int32Value;
|
var index = emulator.Pop() as Int32Value;
|
||||||
var array = emulator.Pop();
|
var array = emulator.Pop();
|
||||||
if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid()) {
|
if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid()) {
|
||||||
if (0 <= index.value && index.value < resultValueArray.Length)
|
if (0 <= index.Value && index.Value < resultValueArray.Length)
|
||||||
resultValueArray[index.value] = value;
|
resultValueArray[index.Value] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -64,8 +64,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return false;
|
return false;
|
||||||
var instr = instructions[emulateIndex];
|
var instr = instructions[emulateIndex];
|
||||||
var targets = (Instruction[])instr.Operand;
|
var targets = (Instruction[])instr.Operand;
|
||||||
if (switchIndex.value >= 0 && switchIndex.value < targets.Length)
|
if (switchIndex.Value >= 0 && switchIndex.Value < targets.Length)
|
||||||
emulateIndex = instructions.IndexOf(targets[switchIndex.value]);
|
emulateIndex = instructions.IndexOf(targets[switchIndex.Value]);
|
||||||
else
|
else
|
||||||
emulateIndex++;
|
emulateIndex++;
|
||||||
return true;
|
return true;
|
||||||
|
@ -221,7 +221,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var retValue2 = (Int32Value)retValue;
|
var retValue2 = (Int32Value)retValue;
|
||||||
if (!retValue2.AllBitsValid())
|
if (!retValue2.AllBitsValid())
|
||||||
return false;
|
return false;
|
||||||
newValue = retValue2.value;
|
newValue = retValue2.Value;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
emulator.Push(new Int32Value(offset));
|
emulator.Push(new Int32Value(offset));
|
||||||
foreach (var instr in OffsetCalcInstructions)
|
foreach (var instr in OffsetCalcInstructions)
|
||||||
emulator.Emulate(instr);
|
emulator.Emulate(instr);
|
||||||
return ((Int32Value)emulator.Pop()).value;
|
return ((Int32Value)emulator.Pop()).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Decrypt(object[] args) {
|
public string Decrypt(object[] args) {
|
||||||
|
@ -348,7 +348,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
case Code.Newarr:
|
case Code.Newarr:
|
||||||
var arrayType = (ITypeDefOrRef)instr.Operand;
|
var arrayType = (ITypeDefOrRef)instr.Operand;
|
||||||
int arrayCount = ((Int32Value)emulator.Pop()).value;
|
int arrayCount = ((Int32Value)emulator.Pop()).Value;
|
||||||
if (arrayType.FullName == "System.Char")
|
if (arrayType.FullName == "System.Char")
|
||||||
emulator.Push(new UserValue(new char[arrayCount]));
|
emulator.Push(new UserValue(new char[arrayCount]));
|
||||||
else
|
else
|
||||||
|
@ -362,7 +362,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldelem_U1:
|
case Code.Ldelem_U1:
|
||||||
arrayIndex = ((Int32Value)emulator.Pop()).value;
|
arrayIndex = ((Int32Value)emulator.Pop()).Value;
|
||||||
array = (Value)emulator.Pop();
|
array = (Value)emulator.Pop();
|
||||||
if (array is UserValue)
|
if (array is UserValue)
|
||||||
emulator.Push(new Int32Value(((byte[])((UserValue)array).obj)[arrayIndex]));
|
emulator.Push(new Int32Value(((byte[])((UserValue)array).obj)[arrayIndex]));
|
||||||
|
@ -372,22 +372,22 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
case Code.Stelem_I1:
|
case Code.Stelem_I1:
|
||||||
value = emulator.Pop();
|
value = emulator.Pop();
|
||||||
arrayIndex = ((Int32Value)emulator.Pop()).value;
|
arrayIndex = ((Int32Value)emulator.Pop()).Value;
|
||||||
array = (Value)emulator.Pop();
|
array = (Value)emulator.Pop();
|
||||||
if (array is UserValue)
|
if (array is UserValue)
|
||||||
((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).value;
|
((byte[])((UserValue)array).obj)[arrayIndex] = (byte)((Int32Value)value).Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Stelem_I2:
|
case Code.Stelem_I2:
|
||||||
value = emulator.Pop();
|
value = emulator.Pop();
|
||||||
arrayIndex = ((Int32Value)emulator.Pop()).value;
|
arrayIndex = ((Int32Value)emulator.Pop()).Value;
|
||||||
array = (Value)emulator.Pop();
|
array = (Value)emulator.Pop();
|
||||||
if (array is UserValue)
|
if (array is UserValue)
|
||||||
((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).value;
|
((char[])((UserValue)array).obj)[arrayIndex] = (char)((Int32Value)value).Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldelem_Ref:
|
case Code.Ldelem_Ref:
|
||||||
arrayIndex = ((Int32Value)emulator.Pop()).value;
|
arrayIndex = ((Int32Value)emulator.Pop()).Value;
|
||||||
array = (Value)emulator.Pop();
|
array = (Value)emulator.Pop();
|
||||||
var userValue = array as UserValue;
|
var userValue = array as UserValue;
|
||||||
if (userValue != null && userValue.obj is string[])
|
if (userValue != null && userValue.obj is string[])
|
||||||
|
@ -451,7 +451,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
object CreateDNLibOperand(OpCode opcode, Value op) {
|
object CreateDNLibOperand(OpCode opcode, Value op) {
|
||||||
if (op is Int32Value)
|
if (op is Int32Value)
|
||||||
return ((Int32Value)op).value;
|
return ((Int32Value)op).Value;
|
||||||
if (op is StringValue)
|
if (op is StringValue)
|
||||||
return ((StringValue)op).value;
|
return ((StringValue)op).value;
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -191,8 +191,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
|
||||||
if (value == null || !value.AllBitsValid())
|
if (value == null || !value.AllBitsValid())
|
||||||
return false;
|
return false;
|
||||||
var targets = (Instruction[])instr.Operand;
|
var targets = (Instruction[])instr.Operand;
|
||||||
if (value.value >= 0 && value.value < targets.Length)
|
if (value.Value >= 0 && value.Value < targets.Length)
|
||||||
index = instrs.IndexOf(targets[value.value]);
|
index = instrs.IndexOf(targets[value.Value]);
|
||||||
else
|
else
|
||||||
index++;
|
index++;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -73,15 +73,23 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
simpleDeobfuscator.Deobfuscate(method);
|
simpleDeobfuscator.Deobfuscate(method);
|
||||||
var instructions = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i <= instructions.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
var ldci4 = method.Body.Instructions[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())
|
if (!ldci4.IsLdcI4())
|
||||||
continue;
|
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());
|
var info = new StringDecrypterInfo(method, ldci4.GetLdcI4Value());
|
||||||
stringDecrypterMethods.Add(info.method, info);
|
stringDecrypterMethods.Add(info.method, info);
|
||||||
|
|
|
@ -626,7 +626,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
if (val == null || !val.AllBitsValid())
|
if (val == null || !val.AllBitsValid())
|
||||||
fields[field] = null;
|
fields[field] = null;
|
||||||
else
|
else
|
||||||
fields[field] = val.value;
|
fields[field] = val.Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Call:
|
case Code.Call:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user