public SlicerResult VisitProcedureConstant(ProcedureConstant pc, BackwardSlicerContext ctx) { return(new SlicerResult { LiveExprs = new Dictionary <Expression, BackwardSlicerContext>(), SrcExpr = pc, }); }
public SlicerResult VisitIdentifier(Identifier id, BackwardSlicerContext ctx) { var sr = new SlicerResult { LiveExprs = { { id, ctx } }, SrcExpr = id, }; return(sr); }
public SlicerResult VisitGoto(RtlGoto go) { var sr = go.Target.Accept(this, BackwardSlicerContext.Cond(RangeOf(go.Target))); if (JumpTableFormat == null) { JumpTableFormat = go.Target; } return(sr); }
public SlicerResult VisitConditionOf(ConditionOf cof, BackwardSlicerContext ctx) { var se = cof.Expression.Accept(this, BackwardSlicerContext.Cond(RangeOf(cof.Expression))); if (se != null && !se.Stop) { se.SrcExpr = cof; this.JumpTableIndex = cof.Expression; this.JumpTableIndexToUse = cof.Expression; } return(se); }
public SlicerResult VisitMkSequence(MkSequence seq, BackwardSlicerContext ctx) { var srExprs = seq.Expressions .Select(e => e.Accept(this, ctx)) .ToArray(); return(new SlicerResult { LiveExprs = srExprs[1].LiveExprs, SrcExpr = new MkSequence(seq.DataType, srExprs.Select(s => s.SrcExpr).ToArray()), Stop = srExprs.Any(s => s.Stop) }); }
public SlicerResult VisitMemoryAccess(MemoryAccess access, BackwardSlicerContext ctx) { var rangeEa = new BitRange(0, (short)access.EffectiveAddress.DataType.BitSize); var srEa = access.EffectiveAddress.Accept(this, new BackwardSlicerContext(ctx.Type, rangeEa)); srEa.LiveExprs[access] = new BackwardSlicerContext(ctx.Type, ctx.BitRange); return(new SlicerResult { LiveExprs = srEa.LiveExprs, SrcExpr = srEa.SrcExpr != null ? new MemoryAccess(srEa.SrcExpr, access.DataType) : null, Stop = srEa.Stop }); }
public SlicerResult VisitBranch(RtlBranch branch) { var se = branch.Condition.Accept(this, BackwardSlicerContext.Cond(new BitRange(0, 0))); var addrTarget = branch.Target as Address; if (addrTarget == null) { throw new NotImplementedException(); //$REVIEW: do we ever see this? } if (this.addrSucc != addrTarget) { this.invertCondition = true; } return(se); }
/// <summary> /// Start the analysis with the expression in the indirect jump. /// Detect any live expressions, and place them in the `Live` /// collection. /// </summary> /// <param name="indirectJump"></param> /// <returns></returns> public bool Start(Expression indirectJump) { var sr = indirectJump.Accept(this, BackwardSlicerContext.Jump(RangeOf(indirectJump))); if (JumpTableFormat == null) { JumpTableFormat = indirectJump; } this.Live = sr.LiveExprs; if (!sr.LiveExprs.Keys.OfType <Identifier>().Any()) { // Couldn't find any indirect registers, so there is no work to do. DebugEx.Warn(BackwardSlicer.trace, "Bwslc: No indirect registers?"); return(false); } DebugEx.Verbose(BackwardSlicer.trace, " live: {0}", DumpLive(this.Live)); return(true); }
/// <summary> /// Start the analysis with the expression in the indirect jump. /// Detect any live expressions, and place them in the `Live` /// collection. /// </summary> /// <param name="indirectJump"></param> /// <returns></returns> public bool Start(Expression indirectJump) { var sr = indirectJump.Accept(this, BackwardSlicerContext.Jump(RangeOf(indirectJump))); if (JumpTableFormat == null) { JumpTableFormat = indirectJump; } this.Live = sr.LiveExprs; if (sr.LiveExprs.Count == 0) { // Couldn't find any indirect registers, so there is no work to do. DebugEx.PrintIf(BackwardSlicer.trace.TraceWarning, " No indirect registers?"); return(false); } DebugEx.PrintIf(BackwardSlicer.trace.TraceVerbose, " live: {0}", DumpLive(this.Live)); return(true); }
public SlicerResult VisitBinaryExpression(BinaryExpression binExp, BackwardSlicerContext ctx) { if (binExp.Operator == Operator.Eq || binExp.Operator == Operator.Ne) { // Equality comparisons cannot contribute to determining the size // of the jump table; stop processing this instruction. return(null); } if ((binExp.Operator == Operator.Xor || binExp.Operator == Operator.ISub) && this.slicer.AreEqual(binExp.Left, binExp.Right)) { // XOR r,r (or SUB r,r) clears a register. Is it part of a live register? var regDst = this.assignLhs as Identifier; var regHi = binExp.Left as Identifier; if (regHi != null && regDst != null && DomainOf(regDst) == regHi.Storage.Domain && regDst.Storage.OffsetOf(regHi.Storage) == 8) { // The 8086 didn't have a MOVZX instruction, so clearing the high byte of a // register BX was done by issuing XOR BH,BH var seXor = new SlicerResult { SrcExpr = new Cast(regDst.DataType, new Cast(PrimitiveType.Byte, this.assignLhs)), LiveExprs = new Dictionary <Expression, BackwardSlicerContext> { { this.assignLhs, BackwardSlicerContext.Jump(new BitRange(0, 8)) } } }; return(seXor); } } var seLeft = binExp.Left.Accept(this, ctx); var seRight = binExp.Right.Accept(this, ctx); if (seLeft == null && seRight == null) { return(null); } if (binExp.Operator == Operator.ISub && this.Live != null && (ctx.Type & ContextType.Condition) != 0) { var domLeft = DomainOf(seLeft.SrcExpr); if (Live.Count > 0) { foreach (var live in Live) { if (live.Value.Type != ContextType.Jumptable) { continue; } if ((domLeft != StorageDomain.Memory && DomainOf(live.Key) == domLeft) || (this.slicer.AreEqual(live.Key, binExp.Left))) { //$TODO: if jmptableindex and jmptableindextouse not same, inject a statement. this.JumpTableIndex = live.Key; this.JumpTableIndexToUse = binExp.Left; this.JumpTableIndexInterval = MakeInterval_ISub(live.Key, binExp.Right as Constant); DebugEx.Verbose(BackwardSlicer.trace, " Found range of {0}: {1}", live, JumpTableIndexInterval); return(new SlicerResult { SrcExpr = binExp, Stop = true }); } } } else { // We have no live variables, which means this subtraction instruction // is both computing the jumptable index and also performing the // comparison. this.JumpTableIndex = assignLhs; this.JumpTableIndexToUse = assignLhs; this.JumpTableIndexInterval = MakeInterval_ISub(assignLhs, binExp.Right as Constant); DebugEx.Verbose(BackwardSlicer.trace, " Found range of {0}: {1}", assignLhs, JumpTableIndexInterval); return(new SlicerResult { SrcExpr = null, // the jump table expression already has the correct shape. Stop = true }); } } else if (binExp.Operator == Operator.And) { this.JumpTableIndex = binExp.Left; this.JumpTableIndexToUse = binExp.Left; this.JumpTableIndexInterval = MakeInterval_And(binExp.Left, binExp.Right as Constant); return(new SlicerResult { SrcExpr = binExp, Stop = true, }); } IEnumerable <KeyValuePair <Expression, BackwardSlicerContext> > liveExpr = seLeft.LiveExprs; if (seRight != null) { liveExpr = liveExpr.Concat(seRight.LiveExprs); } var se = new SlicerResult { LiveExprs = liveExpr .GroupBy(e => e.Key) .ToDictionary(k => k.Key, v => v.Max(vv => vv.Value)), SrcExpr = binExp, }; return(se); }
public SlicerResult VisitUnaryExpression(UnaryExpression unary, BackwardSlicerContext ctx) { var sr = unary.Expression.Accept(this, ctx); return(sr); }
public SlicerResult VisitDereference(Dereference deref, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitConditionalExpression(ConditionalExpression c, BackwardSlicerContext ctx) { return(null); }
public SlicerResult VisitOutArgument(OutArgument outArgument, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitMemberPointerSelector(MemberPointerSelector mps, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitSlice(Slice slice, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitConditionalExpression(ConditionalExpression c, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitCast(Cast cast, BackwardSlicerContext ctx) { var range = new BitRange(0, (short)cast.DataType.BitSize); return(cast.Expression.Accept(this, new BackwardSlicerContext(ctx.Type, range))); }
public SlicerResult VisitPhiFunction(PhiFunction phi, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitPointerAddition(PointerAddition pa, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitBinaryExpression(BinaryExpression binExp, BackwardSlicerContext ctx) { if (binExp.Operator == Operator.Eq || binExp.Operator == Operator.Ne) { // Equality comparisons cannot contribute to determining the size // of the jump table; stop processing this instruction. return(null); } if ((binExp.Operator == Operator.Xor || binExp.Operator == Operator.ISub) && this.slicer.AreEqual(binExp.Left, binExp.Right)) { // XOR r,r (or SUB r,r) clears a register. Is it part of a live register? var regDst = this.assignLhs as Identifier; var regHi = binExp.Left as Identifier; if (regHi != null && regDst != null && DomainOf(regDst) == regHi.Storage.Domain && regDst.Storage.OffsetOf(regHi.Storage) == 8) { // The 8086 didn't have a MOVZX instruction, so clearing the high byte of a // register BX was done by issuing XOR BH,BH var seXor = new SlicerResult { SrcExpr = new Cast(regDst.DataType, new Cast(PrimitiveType.Byte, this.assignLhs)), LiveExprs = new Dictionary <Expression, BackwardSlicerContext> { { this.assignLhs, BackwardSlicerContext.Jump(new BitRange(0, 8)) } } }; return(seXor); } } var seLeft = binExp.Left.Accept(this, ctx); var seRight = binExp.Right.Accept(this, ctx); if (seLeft == null && seRight == null) { return(null); } if (binExp.Operator == Operator.ISub && Live != null) { var domLeft = DomainOf(seLeft.SrcExpr); foreach (var live in Live.Keys) { if (DomainOf(live) == domLeft) { if (slicer.AreEqual(this.assignLhs, this.JumpTableIndex)) { //$TODO: if jmptableindex and jmptableindextouse not same, inject a statement. this.JumpTableIndex = live; this.JumpTableIndexToUse = binExp.Left; this.JumpTableIndexInterval = MakeInterval_ISub(live, binExp.Right as Constant); DebugEx.PrintIf(BackwardSlicer.trace.TraceVerbose, " Found range of {0}: {1}", live, JumpTableIndexInterval); return(new SlicerResult { SrcExpr = binExp, Stop = true }); } } if (this.slicer.AreEqual(live, binExp.Left)) { this.JumpTableIndex = live; this.JumpTableIndexToUse = binExp.Left; this.JumpTableIndexInterval = MakeInterval_ISub(live, binExp.Right as Constant); return(new SlicerResult { SrcExpr = binExp, Stop = true, }); } } } else if (binExp.Operator == Operator.And) { this.JumpTableIndex = binExp.Left; this.JumpTableIndexToUse = binExp.Left; this.JumpTableIndexInterval = MakeInterval_And(binExp.Left, binExp.Right as Constant); return(new SlicerResult { SrcExpr = binExp, Stop = true, }); } var se = new SlicerResult { LiveExprs = seLeft.LiveExprs.Concat(seRight.LiveExprs) .GroupBy(e => e.Key) .ToDictionary(k => k.Key, v => v.Max(vv => vv.Value)), SrcExpr = binExp, }; return(se); }
public SlicerResult VisitFieldAccess(FieldAccess acc, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitSegmentedAccess(SegmentedAccess access, BackwardSlicerContext ctx) { var sr = access.EffectiveAddress.Accept(this, ctx); return(sr); }
public SlicerResult VisitScopeResolution(ScopeResolution scopeResolution, BackwardSlicerContext ctx) { throw new NotImplementedException(); }
public SlicerResult VisitProcedureConstant(ProcedureConstant pc, BackwardSlicerContext ctx) { throw new NotImplementedException(); }