private bool Solve_Blt(CflowStack stack) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && val2 is BitVecExpr) { FinalExpr = ctx.MkBVSLT(val1 as BitVecExpr, val2 as BitVecExpr); if ((val1 as BitVecExpr).Simplify().IsNumeral&& (val2 as BitVecExpr).Simplify().IsNumeral) { Microsoft.Z3.Solver s1 = ctx.MkSolver(); Microsoft.Z3.Solver s2 = ctx.MkSolver(); s1.Add(FinalExpr); s2.Add(ctx.MkNot(FinalExpr)); return(this.CheckBranch(s1, s2)); } } return(false); }
private void Translate_Ldlen(CflowStack stack, Instruction instr) { var val = stack.Pop(); if (val is IField) { if ((val as IField).FullName == "System.Type[] System.Type::EmptyTypes") { stack.Push(ctx.MkBV(0, 32)); return; } } stack.PushUnknown(); }
private void UpdateStack(CflowStack stack, Instruction instr) { int pushes, pops; instr.CalculateStackUsage(out pushes, out pops); if (pops == -1) { stack.Clear(); } else { stack.Pop(pops); stack.Push(pushes); } }
private bool Solve_Switch(CflowStack stack) { Block target; List <Block> targets; bool modified = false; int index; var val1 = stack.Pop(); if (val1 is BitVecExpr && (val1 as BitVecExpr).Simplify().IsNumeral != true) { var cfg = CflowCFG.ControlFlow; foreach (List <Block> list in cfg) { token.ThrowIfCancellationRequested(); CflowTranslatorCtx translator = TranslatorInit(true); List <Instr> instructions = new List <Instr>(); foreach (Block b in list) { instructions.AddRange(b.Instructions); } for (int i = 0; i < instructions.Count - 1; i++) { var instr = instructions[i].Instruction; TranslateInstruction(translator, instr); } object val2 = translator.Stack.Pop(); if (val2 is BitVecExpr && (val2 as BitVecExpr).Simplify().IsNumeral == true) { this.BifurcateBlocks(cfg, list); if (!int.TryParse((val2 as BitVecExpr).Simplify().ToString(), out index)) { index = -1; } var beforeSwitch = list[list.Count - 2]; if (beforeSwitch.LastInstr.IsConditionalBranch()) { var newBlock = new Block(); for (int i = 0; i < list.Last().Instructions.Count - 1; i++) { var instr = list.Last().Instructions[i]; if (instr.OpCode != OpCodes.Nop) { newBlock.Instructions.Add(true ? new Instr(instr.Instruction.Clone()) : instr); } } newBlock.Insert(newBlock.Instructions.Count, OpCodes.Pop.ToInstruction()); // for switch if (beforeSwitch.FallThrough != null && beforeSwitch.FallThrough == list.Last()) { targets = block.Targets; if (targets == null || index < 0 || index >= targets.Count) { target = block.FallThrough; } else { target = targets[index]; } beforeSwitch.FallThrough.Parent.Add(newBlock); beforeSwitch.SetNewFallThrough(newBlock); newBlock.SetNewFallThrough(target); modified = true; } if (beforeSwitch.Targets != null && beforeSwitch.Targets[0] == list.Last()) { targets = block.Targets; if (targets == null || index < 0 || index >= targets.Count) { target = block.FallThrough; } else { target = targets[index]; } beforeSwitch.FallThrough.Parent.Add(newBlock); beforeSwitch.SetNewTarget(0, newBlock); newBlock.SetNewFallThrough(target); modified = true; } } else if (beforeSwitch.LastInstr.OpCode.Code == Code.Switch) { //just skip } else { var newBlock = new Block(); for (int i = 0; i < list.Last().Instructions.Count - 1; i++) { var instr = list.Last().Instructions[i]; if (instr.OpCode != OpCodes.Nop) { newBlock.Instructions.Add(true ? new Instr(instr.Instruction.Clone()) : instr); } } newBlock.Insert(newBlock.Instructions.Count, OpCodes.Pop.ToInstruction()); // for switch targets = block.Targets; if (targets == null || index < 0 || index >= targets.Count) { target = block.FallThrough; } else { target = targets[index]; } beforeSwitch.FallThrough.Parent.Add(newBlock); beforeSwitch.SetNewFallThrough(newBlock); newBlock.SetNewFallThrough(target); modified = true; } if (modified == true) { break; } } } return(modified); } else if (val1 is BitVecExpr) { index = int.Parse((val1 as BitVecExpr).Simplify().ToString()); targets = block.Targets; if (targets == null || index < 0 || index >= targets.Count) { target = block.FallThrough; } else { target = targets[index]; } block.Insert(block.Instructions.Count - 1, OpCodes.Pop.ToInstruction()); block.ReplaceSwitchWithBranch(target); return(true); } return(false); }