Truncate values when emulating stloc/starg
This commit is contained in:
parent
c1290ec3ee
commit
4b3c52c44f
|
@ -59,11 +59,11 @@ namespace de4dot.blocks.cflow {
|
|||
else if (DotNetUtils.isAssembly(typeReference.Scope, "mscorlib")) {
|
||||
switch (typeReference.FullName) {
|
||||
case "System.Boolean":
|
||||
case "System.Byte":
|
||||
case "System.SByte":
|
||||
case "System.Byte":
|
||||
case "System.Int16":
|
||||
case "System.Int32":
|
||||
case "System.UInt16":
|
||||
case "System.Int32":
|
||||
case "System.UInt32":
|
||||
return new Int32Value(0);
|
||||
case "System.Int64":
|
||||
|
@ -83,11 +83,11 @@ namespace de4dot.blocks.cflow {
|
|||
if (DotNetUtils.isAssembly(typeReference.Scope, "mscorlib")) {
|
||||
switch (typeReference.FullName) {
|
||||
case "System.Boolean": return Int32Value.createUnknownBool();
|
||||
case "System.Byte": return Int32Value.createUnknownUInt8();
|
||||
case "System.SByte": return Int32Value.createUnknown();
|
||||
case "System.Byte": return Int32Value.createUnknownUInt8();
|
||||
case "System.Int16": return Int32Value.createUnknown();
|
||||
case "System.Int32": return Int32Value.createUnknown();
|
||||
case "System.UInt16": return Int32Value.createUnknownUInt16();
|
||||
case "System.Int32": return Int32Value.createUnknown();
|
||||
case "System.UInt32": return Int32Value.createUnknown();
|
||||
case "System.Int64": return Int64Value.createUnknown();
|
||||
case "System.UInt64": return Int64Value.createUnknown();
|
||||
|
@ -96,6 +96,52 @@ namespace de4dot.blocks.cflow {
|
|||
return new UnknownValue();
|
||||
}
|
||||
|
||||
static Value truncateValue(Value value, TypeReference typeReference) {
|
||||
if (typeReference == null)
|
||||
return value;
|
||||
if (DotNetUtils.isAssembly(typeReference.Scope, "mscorlib")) {
|
||||
switch (typeReference.FullName) {
|
||||
case "System.Boolean":
|
||||
if (value.isInt32())
|
||||
return ((Int32Value)value).toBoolean();
|
||||
return Int32Value.createUnknownBool();
|
||||
|
||||
case "System.SByte":
|
||||
if (value.isInt32())
|
||||
return ((Int32Value)value).toInt8();
|
||||
return Int32Value.createUnknown();
|
||||
|
||||
case "System.Byte":
|
||||
if (value.isInt32())
|
||||
return ((Int32Value)value).toUInt8();
|
||||
return Int32Value.createUnknownUInt8();
|
||||
|
||||
case "System.Int16":
|
||||
if (value.isInt32())
|
||||
return ((Int32Value)value).toInt16();
|
||||
return Int32Value.createUnknown();
|
||||
|
||||
case "System.UInt16":
|
||||
if (value.isInt32())
|
||||
return ((Int32Value)value).toUInt16();
|
||||
return Int32Value.createUnknownUInt16();
|
||||
|
||||
case "System.Int32":
|
||||
case "System.UInt32":
|
||||
if (value.isInt32())
|
||||
return value;
|
||||
return Int32Value.createUnknown();
|
||||
|
||||
case "System.Int64":
|
||||
case "System.UInt64":
|
||||
if (value.isInt64())
|
||||
return value;
|
||||
return Int64Value.createUnknown();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static Value getValue(List<Value> list, int i) {
|
||||
if (0 <= i && i < list.Count)
|
||||
return list[i];
|
||||
|
@ -112,7 +158,7 @@ namespace de4dot.blocks.cflow {
|
|||
|
||||
void setArg(int index, Value value) {
|
||||
if (0 <= index && index < args.Count)
|
||||
args[index] = value;
|
||||
args[index] = truncateValue(value, parameterDefinitions[index].ParameterType);
|
||||
}
|
||||
|
||||
Value getUnknownArg(int index) {
|
||||
|
@ -131,7 +177,7 @@ namespace de4dot.blocks.cflow {
|
|||
|
||||
void setLocal(int index, Value value) {
|
||||
if (0 <= index && index < locals.Count)
|
||||
locals[index] = value;
|
||||
locals[index] = truncateValue(value, variableDefinitions[index].VariableType);
|
||||
}
|
||||
|
||||
Value getUnknownLocal(int index) {
|
||||
|
@ -744,14 +790,10 @@ namespace de4dot.blocks.cflow {
|
|||
}
|
||||
|
||||
void emulate_Starg(int index) {
|
||||
//TODO: You should truncate the value if necessary, eg. from int32 -> bool,
|
||||
// int32 -> int16, double -> float, etc.
|
||||
setArg(index, valueStack.pop());
|
||||
}
|
||||
|
||||
void emulate_Stloc(int index) {
|
||||
//TODO: You should truncate the value if necessary, eg. from int32 -> bool,
|
||||
// int32 -> int16, double -> float, etc.
|
||||
setLocal(index, valueStack.pop());
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,26 @@ namespace de4dot.blocks.cflow {
|
|||
return hasValue((int)value);
|
||||
}
|
||||
|
||||
public Int32Value toBoolean() {
|
||||
return new Int32Value(value & 1, validMask | (NO_UNKNOWN_BITS << 1));
|
||||
}
|
||||
|
||||
public Int32Value toInt8() {
|
||||
return Conv_I1(this);
|
||||
}
|
||||
|
||||
public Int32Value toUInt8() {
|
||||
return Conv_U1(this);
|
||||
}
|
||||
|
||||
public Int32Value toInt16() {
|
||||
return Conv_I2(this);
|
||||
}
|
||||
|
||||
public Int32Value toUInt16() {
|
||||
return Conv_U2(this);
|
||||
}
|
||||
|
||||
public static Int32Value Conv_U1(Int32Value a) {
|
||||
return Conv_U1(a.value, a.validMask);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user