diff --git a/blocks/cflow/BranchEmulator.cs b/blocks/cflow/BranchEmulator.cs index 3964cb75..d5e3a8c4 100644 --- a/blocks/cflow/BranchEmulator.cs +++ b/blocks/cflow/BranchEmulator.cs @@ -220,6 +220,8 @@ namespace de4dot.blocks.cflow { return emulateBranch(1, Int64Value.compareFalse((Int64Value)val1)); else if (val1.isNull()) return emulateBranch(1, true); + else if (val1.isObject() || val1.isString() || val1.isBoxed()) + return emulateBranch(1, false); else return false; } @@ -233,6 +235,8 @@ namespace de4dot.blocks.cflow { return emulateBranch(1, Int64Value.compareTrue((Int64Value)val1)); else if (val1.isNull()) return emulateBranch(1, false); + else if (val1.isObject() || val1.isString() || val1.isBoxed()) + return emulateBranch(1, true); else return false; } diff --git a/blocks/cflow/InstructionEmulator.cs b/blocks/cflow/InstructionEmulator.cs index 7eb0e648..6ca70268 100644 --- a/blocks/cflow/InstructionEmulator.cs +++ b/blocks/cflow/InstructionEmulator.cs @@ -385,6 +385,12 @@ namespace de4dot.blocks.cflow { case Code.Ldfld: emulate_Ldfld(instr); break; case Code.Ldsfld: emulate_Ldsfld(instr); break; + case Code.Ldftn: valueStack.push(new ObjectValue(instr.Operand)); break; + case Code.Ldsflda: valueStack.push(new ObjectValue(instr.Operand)); break; + case Code.Ldtoken: valueStack.push(new ObjectValue(instr.Operand)); break; + case Code.Ldvirtftn:valueStack.pop(); valueStack.push(new ObjectValue()); break; + case Code.Ldflda: valueStack.pop(); valueStack.push(new ObjectValue()); break; + case Code.Unbox: case Code.Conv_R_Un: @@ -440,16 +446,11 @@ namespace de4dot.blocks.cflow { case Code.Ldelem_R4: case Code.Ldelem_R8: case Code.Ldelem_Ref: - case Code.Ldflda: - case Code.Ldftn: case Code.Ldind_I: case Code.Ldind_R4: case Code.Ldind_R8: case Code.Ldind_Ref: case Code.Ldobj: - case Code.Ldsflda: - case Code.Ldtoken: - case Code.Ldvirtftn: case Code.Leave: case Code.Leave_S: case Code.Localloc: diff --git a/blocks/cflow/Value.cs b/blocks/cflow/Value.cs index 46abe5d8..daf741ea 100644 --- a/blocks/cflow/Value.cs +++ b/blocks/cflow/Value.cs @@ -21,6 +21,7 @@ namespace de4dot.blocks.cflow { public enum ValueType : byte { Unknown, Null, + Object, Boxed, Int32, Int64, @@ -45,6 +46,10 @@ namespace de4dot.blocks.cflow { return valueType == ValueType.Null; } + public bool isObject() { + return valueType == ValueType.Object; + } + public bool isBoxed() { return valueType == ValueType.Boxed; } @@ -80,6 +85,23 @@ namespace de4dot.blocks.cflow { } } + public class ObjectValue : Value { + public readonly object obj; // can be null but that doesn't mean that this ObjectValue instance is null + + public ObjectValue() + : this(null) { + } + + public ObjectValue(object obj) + : base(ValueType.Object) { + this.obj = obj; + } + + public override string ToString() { + return ""; + } + } + public class NullValue : Value { // There's only one type of null public static readonly NullValue Instance = new NullValue();