public static Value[] getInitializedArray(int arraySize, MethodDefinition method, ref int newarrIndex, Code stelemOpCode) { var resultValueArray = new Value[arraySize]; var emulator = new InstructionEmulator(method.HasThis, false, method.Parameters, method.Body.Variables); var theArray = new UnknownValue(); emulator.push(theArray); var instructions = method.Body.Instructions; int i; for (i = newarrIndex + 1; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.FlowControl != FlowControl.Next) break; if (instr.OpCode.Code == Code.Newarr) break; if (instr.OpCode.Code == stelemOpCode) { var value = emulator.pop(); var index = emulator.pop() as Int32Value; var array = emulator.pop(); if (ReferenceEquals(array, theArray) && index != null && index.allBitsValid()) { if (0 <= index.value && index.value < resultValueArray.Length) resultValueArray[index.value] = value; } } else emulator.emulate(instr); } if (i != newarrIndex + 1) i--; newarrIndex = i; return resultValueArray; }
void setLocal(int index, Value value) { if (0 <= index && index < locals.Count) locals[index] = truncateValue(value, variableDefinitions[index].VariableType); }
void setArg(int index, Value value) { if (0 <= index && index < args.Count) args[index] = truncateValue(value, getArgType(index)); }
Block getSwitchTarget(IList<Block> targets, Block fallThrough, Block source, Value value) { if (!value.isInt32()) return null; return CflowUtils.getSwitchTarget(targets, fallThrough, (Int32Value)value); }
bool EmulateToReturn(int index, Instruction lastInstr) { int pushes, pops; lastInstr.CalculateStackUsage(false, out pushes, out pops); instructionEmulator.Pop(pops); returnValue = null; if (pushes != 0) { returnValue = new UnknownValue(); instructionEmulator.SetProtected(returnValue); instructionEmulator.Push(returnValue); } if (!EmulateInstructions(ref index, true)) return false; if (index >= methodToInline.Body.Instructions.Count) return false; if (methodToInline.Body.Instructions[index].OpCode.Code != Code.Ret) return false; if (returnValue != null) { if (instructionEmulator.Pop() != returnValue) return false; } return instructionEmulator.StackSize() == 0; }
static Block GetSwitchTarget(IList<Block> targets, Block fallThrough, Value value) { if (!value.IsInt32()) return null; return CflowUtils.GetSwitchTarget(targets, fallThrough, (Int32Value)value); }
bool FixLoadInstruction(Block block, int index, Value value) { if (value.IsInt32()) { var intValue = (Int32Value)value; if (!intValue.AllBitsValid()) return false; block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.Value)); return true; } else if (value.IsInt64()) { var intValue = (Int64Value)value; if (!intValue.AllBitsValid()) return false; block.Instructions[index] = new Instr(OpCodes.Ldc_I8.ToInstruction(intValue.Value)); return true; } return false; }
void SetLocal(int index, Value value) { if (0 <= index && index < locals.Count) locals[index] = TruncateValue(value, localDefs[index].Type); }
public void Push(Value value) { valueStack.Push(value); }
public void SetArg(Parameter arg, Value value) { if (arg != null) SetArg(arg.Index, value); }
public void SetLocal(Local local, Value value) { if (local != null) SetLocal(local.Index, value); }
Value TruncateValue(Value value, TypeSig type) { if (type == null) return value; if (protectedStackValues.ContainsKey(value)) return value; switch (type.ElementType) { case ElementType.Boolean: if (value.IsInt32()) return ((Int32Value)value).ToBoolean(); return Int32Value.CreateUnknownBool(); case ElementType.I1: if (value.IsInt32()) return ((Int32Value)value).ToInt8(); return Int32Value.CreateUnknown(); case ElementType.U1: if (value.IsInt32()) return ((Int32Value)value).ToUInt8(); return Int32Value.CreateUnknownUInt8(); case ElementType.I2: if (value.IsInt32()) return ((Int32Value)value).ToInt16(); return Int32Value.CreateUnknown(); case ElementType.U2: if (value.IsInt32()) return ((Int32Value)value).ToUInt16(); return Int32Value.CreateUnknownUInt16(); case ElementType.I4: case ElementType.U4: if (value.IsInt32()) return value; return Int32Value.CreateUnknown(); case ElementType.I8: case ElementType.U8: if (value.IsInt64()) return value; return Int64Value.CreateUnknown(); case ElementType.R4: if (value.IsReal8()) return ((Real8Value)value).ToSingle(); return new UnknownValue(); case ElementType.R8: if (value.IsReal8()) return value; return new UnknownValue(); } return value; }
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; }
object createCecilOperand(OpCode opcode, Value op) { if (op is Int32Value) return ((Int32Value)op).value; if (op is StringValue) return ((StringValue)op).value; return null; }
public static Value[] GetInitializedArray(int arraySize, MethodDef method, ref int newarrIndex, Code stelemOpCode) { var resultValueArray = new Value[arraySize]; var emulator = new InstructionEmulator(method); var theArray = new UnknownValue(); emulator.Push(theArray); var instructions = method.Body.Instructions; int i; for (i = newarrIndex + 1; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.FlowControl != FlowControl.Next) break; if (instr.OpCode.Code == Code.Newarr) break; switch (instr.OpCode.Code) { case Code.Newarr: case Code.Newobj: goto done; case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Starg: case Code.Starg_S: case Code.Stsfld: case Code.Stfld: if (emulator.Peek() == theArray && i != newarrIndex + 1 && i != newarrIndex + 2) goto done; break; } if (instr.OpCode.Code == stelemOpCode) { var value = emulator.Pop(); var index = emulator.Pop() as Int32Value; var array = emulator.Pop(); if (ReferenceEquals(array, theArray) && index != null && index.AllBitsValid()) { if (0 <= index.Value && index.Value < resultValueArray.Length) resultValueArray[index.Value] = value; } } else emulator.Emulate(instr); } done: if (i != newarrIndex + 1) i--; newarrIndex = i; return resultValueArray; }
public void SetProtected(Value value) { protectedStackValues[value] = true; }
object CreateDNLibOperand(OpCode opcode, Value op) { if (op is Int32Value) return ((Int32Value)op).Value; if (op is StringValue) return ((StringValue)op).value; return null; }
public void push(Value value) { valueStack.push(value); }
static bool VerifyValidArg(Value value) { if (value.IsInt32()) return ((Int32Value)value).AllBitsValid(); if (value.IsInt64()) return ((Int64Value)value).AllBitsValid(); if (value.IsReal8()) return ((Real8Value)value).IsValid; return false; }
public void setArg(ParameterDefinition arg, Value value) { setArg(index(arg), value); }
bool fixLoadInstruction(Block block, int index, Value value) { if (value.isInt32()) { var intValue = (Int32Value)value; if (!intValue.allBitsValid()) return false; block.Instructions[index] = new Instr(DotNetUtils.createLdci4(intValue.value)); return true; } else if (value.isInt64()) { var intValue = (Int64Value)value; if (!intValue.allBitsValid()) return false; block.Instructions[index] = new Instr(Instruction.Create(OpCodes.Ldc_I8, intValue.value)); return true; } return false; }
public void setLocal(VariableDefinition local, Value value) { setLocal(local.Index, value); }
public void push(Value value) { stack.Add(value); }
static Value truncateValue(Value value, TypeReference typeReference) { if (typeReference == null) return value; switch (typeReference.EType) { case ElementType.Boolean: if (value.isInt32()) return ((Int32Value)value).toBoolean(); return Int32Value.createUnknownBool(); case ElementType.I1: if (value.isInt32()) return ((Int32Value)value).toInt8(); return Int32Value.createUnknown(); case ElementType.U1: if (value.isInt32()) return ((Int32Value)value).toUInt8(); return Int32Value.createUnknownUInt8(); case ElementType.I2: if (value.isInt32()) return ((Int32Value)value).toInt16(); return Int32Value.createUnknown(); case ElementType.U2: if (value.isInt32()) return ((Int32Value)value).toUInt16(); return Int32Value.createUnknownUInt16(); case ElementType.I4: case ElementType.U4: if (value.isInt32()) return value; return Int32Value.createUnknown(); case ElementType.I8: case ElementType.U8: if (value.isInt64()) return value; return Int64Value.createUnknown(); } return value; }
bool InlineMethod(MethodDef methodToInline, int instrIndex, int const1, int const2) { this.methodToInline = methodToInline = cflowDeobfuscator.Deobfuscate(methodToInline); parameters = methodToInline.Parameters; arg1 = parameters[parameters.Count - 2]; arg2 = parameters[parameters.Count - 1]; returnValue = null; instructionEmulator.Initialize(methodToInline); foreach (var arg in parameters) { if (!arg.IsNormalMethodParameter) continue; if (arg.Type.ElementType >= ElementType.Boolean && arg.Type.ElementType <= ElementType.U4) instructionEmulator.SetArg(arg, new Int32Value(0)); } instructionEmulator.SetArg(arg1, new Int32Value(const1)); instructionEmulator.SetArg(arg2, new Int32Value(const2)); int index = 0; if (!EmulateInstructions(ref index, false)) return false; var patcher = TryInlineOtherMethod(instrIndex, methodToInline, methodToInline.Body.Instructions[index], index + 1, 2); if (patcher == null) return false; if (!EmulateToReturn(patcher.afterIndex, patcher.lastInstr)) return false; patcher.Patch(block); block.Insert(instrIndex, OpCodes.Pop.ToInstruction()); block.Insert(instrIndex, OpCodes.Pop.ToInstruction()); return true; }
Value truncateValue(Value value, TypeReference typeReference) { if (typeReference == null) return value; if (protectedStackValues.ContainsKey(value)) return value; switch (typeReference.EType) { case ElementType.Boolean: if (value.isInt32()) return ((Int32Value)value).toBoolean(); return Int32Value.createUnknownBool(); case ElementType.I1: if (value.isInt32()) return ((Int32Value)value).toInt8(); return Int32Value.createUnknown(); case ElementType.U1: if (value.isInt32()) return ((Int32Value)value).toUInt8(); return Int32Value.createUnknownUInt8(); case ElementType.I2: if (value.isInt32()) return ((Int32Value)value).toInt16(); return Int32Value.createUnknown(); case ElementType.U2: if (value.isInt32()) return ((Int32Value)value).toUInt16(); return Int32Value.createUnknownUInt16(); case ElementType.I4: case ElementType.U4: if (value.isInt32()) return value; return Int32Value.createUnknown(); case ElementType.I8: case ElementType.U8: if (value.isInt64()) return value; return Int64Value.createUnknown(); case ElementType.R4: if (value.isReal8()) return new Real8Value((float)((Real8Value)value).value); return new UnknownValue(); case ElementType.R8: if (value.isReal8()) return value; return new UnknownValue(); } return value; }