private bool Solve_Brtrue(CflowStack stack) { var val1 = stack.Pop(); if (val1 is BitVecExpr) { FinalExpr = ctx.MkEq(val1 as BitVecExpr, ctx.MkBV(0, 32)); if ((val1 as BitVecExpr).Simplify().IsNumeral) { Microsoft.Z3.Solver s = ctx.MkSolver(); s.Assert(FinalExpr); if (s.Check() == Status.UNSATISFIABLE) { this.PopPushedArgs(1); block.ReplaceBccWithBranch(true); return(true); } else { this.PopPushedArgs(1); block.ReplaceBccWithBranch(false); return(true); } } } return(false); }
public CflowTranslatorCtx(Context ctx, CflowStack stack, List <BitVecExpr> args, List <BitVecExpr> locals) { this.Stack = stack; this.Stack.ctx = ctx; this.Args = args; this.Locals = locals; }
private BitVecExpr GetLocal(CflowStack stack, List <BitVecExpr> locals, Local local) { if (local == null) { return(GetUnknownLocal(stack)); } return(GetLocal(stack, locals, local.Index)); }
private BitVecExpr GetLocal(CflowStack stack, List <BitVecExpr> locals, int i) { if (0 <= i && i < locals.Count) { return(locals[i]); } return(GetUnknownLocal(stack)); }
private BitVecExpr GetArg(CflowStack stack, List <BitVecExpr> args, Parameter arg) { if (arg == null) { return(GetUnknownArg(stack)); } return(GetArg(stack, args, arg.Index)); }
private BitVecExpr GetArg(CflowStack stack, List <BitVecExpr> args, int i) { if (0 <= i && i < args.Count) { return(args[i]); } return(GetUnknownArg(stack)); }
private void Translate_Stloc(CflowStack stack, List <BitVecExpr> locals, int index) { var val = stack.Pop(); if (val is BitVecExpr) { SetLocal(locals, index, val as BitVecExpr); } else { SetLocal(locals, index, GetUnknownLocal(stack)); } }
private void Translate_Ldind_I4(CflowStack stack, Instruction instr) { var addr = stack.Pop(); if (addr is Address && (addr as Address).Value is BitVecExpr) { stack.Push((addr as Address).Value); } else { stack.PushUnknown(); } }
private void Translate_Starg(CflowStack stack, List <BitVecExpr> args, Parameter arg) { var val = stack.Pop(); if (val is BitVecExpr) { SetArg(args, arg == null ? -1 : arg.Index, val as BitVecExpr); } else { SetArg(args, arg == null ? -1 : arg.Index, GetUnknownArg(stack)); } }
private void Translate_Not(CflowStack stack, Instruction instr) { var val1 = stack.Pop(); if (val1 is BitVecExpr) { stack.Push(ctx.MkBVNot(val1 as BitVecExpr)); } else { stack.PushUnknown(); } }
private void Translate_Clt_Un(CflowStack stack, Instruction instr) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && (val1 as BitVecExpr).Simplify().IsNumeral&& val2 is BitVecExpr && (val2 as BitVecExpr).Simplify().IsNumeral) { stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVULT(val1 as BitVecExpr, val2 as BitVecExpr), ctx.MkBV(1, 32), ctx.MkBV(0, 32))); } else { stack.PushUnknown(); } }
private void Translate_Mul_Ovf_Un(CflowStack stack, Instruction instr) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && val2 is BitVecExpr) { stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVMulNoOverflow(val1 as BitVecExpr, val2 as BitVecExpr, false), ctx.MkBVMul(val1 as BitVecExpr, val2 as BitVecExpr), stack.Unknown() as BitVecExpr)); } else { stack.PushUnknown(); } }
private void Translate_Sub_Ovf(CflowStack stack, Instruction instr) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && val2 is BitVecExpr) { stack.Push((BitVecExpr)ctx.MkITE(ctx.MkBVSubNoUnderflow(val1 as BitVecExpr, val2 as BitVecExpr, true), ctx.MkBVSub(val1 as BitVecExpr, val2 as BitVecExpr), stack.Unknown() as BitVecExpr)); } else { stack.PushUnknown(); } }
private void Translate_Shr_Un(CflowStack stack, Instruction instr) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && val2 is BitVecExpr) { stack.Push(ctx.MkBVLSHR(val1 as BitVecExpr, val2 as BitVecExpr)); } else { 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 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 bool Solve_Bne_Un(CflowStack stack) { var val2 = stack.Pop(); var val1 = stack.Pop(); if (val1 is BitVecExpr && val2 is BitVecExpr) { FinalExpr = ctx.MkNot(ctx.MkEq(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 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); }
private BitVecExpr GetUnknownLocal(CflowStack stack) { return(stack.Unknown() as BitVecExpr); }
private void Translate_Stloc(CflowStack stack, List <BitVecExpr> locals, Local local) { Translate_Stloc(stack, locals, local == null ? -1 : local.Index); }
private void Translate_Ldloca(CflowStack stack, List <BitVecExpr> locals, Local local) { stack.Push(new Address(GetLocal(stack, locals, local))); SetLocal(locals, local == null ? -1 : local.Index, GetUnknownLocal(stack)); }
private void Translate_Sizeof(CflowStack stack, Instruction instr) { if (instr.Operand is TypeRef) { if ((instr.Operand as TypeRef).FullName == "System.Boolean") { stack.Push(ctx.MkBV(sizeof(System.Boolean), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Byte") { stack.Push(ctx.MkBV(sizeof(System.Byte), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.SByte") { stack.Push(ctx.MkBV(sizeof(System.SByte), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Char") { stack.Push(ctx.MkBV(sizeof(System.Char), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Int16") { stack.Push(ctx.MkBV(sizeof(System.Int16), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Int32") { stack.Push(ctx.MkBV(sizeof(System.Int32), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Int64") { stack.Push(ctx.MkBV(sizeof(System.Int64), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.UInt16") { stack.Push(ctx.MkBV(sizeof(System.UInt16), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.UInt32") { stack.Push(ctx.MkBV(sizeof(System.UInt32), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.UInt64") { stack.Push(ctx.MkBV(sizeof(System.UInt64), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Single") { stack.Push(ctx.MkBV(sizeof(System.Single), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Double") { stack.Push(ctx.MkBV(sizeof(System.Double), 32)); return; } else if ((instr.Operand as TypeRef).FullName == "System.Guid") { stack.Push(ctx.MkBV(0x10, 32)); return; } } stack.PushUnknown(); }
private void Translate_Ldsfld(CflowStack stack, Instruction instr) { stack.Push(instr.Operand as IField); }