Ejemplo n.º 1
0
 public SlicerResult VisitProcedureConstant(ProcedureConstant pc, BackwardSlicerContext ctx)
 {
     return(new SlicerResult
     {
         LiveExprs = new Dictionary <Expression, BackwardSlicerContext>(),
         SrcExpr = pc,
     });
 }
Ejemplo n.º 2
0
        public SlicerResult VisitIdentifier(Identifier id, BackwardSlicerContext ctx)
        {
            var sr = new SlicerResult
            {
                LiveExprs = { { id, ctx } },
                SrcExpr   = id,
            };

            return(sr);
        }
Ejemplo n.º 3
0
        public SlicerResult VisitGoto(RtlGoto go)
        {
            var sr = go.Target.Accept(this, BackwardSlicerContext.Cond(RangeOf(go.Target)));

            if (JumpTableFormat == null)
            {
                JumpTableFormat = go.Target;
            }
            return(sr);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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)
            });
        }
Ejemplo n.º 6
0
        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
            });
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        public SlicerResult VisitUnaryExpression(UnaryExpression unary, BackwardSlicerContext ctx)
        {
            var sr = unary.Expression.Accept(this, ctx);

            return(sr);
        }
Ejemplo n.º 12
0
 public SlicerResult VisitDereference(Dereference deref, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 13
0
 public SlicerResult VisitConditionalExpression(ConditionalExpression c, BackwardSlicerContext ctx)
 {
     return(null);
 }
Ejemplo n.º 14
0
 public SlicerResult VisitOutArgument(OutArgument outArgument, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 15
0
 public SlicerResult VisitMemberPointerSelector(MemberPointerSelector mps, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 16
0
 public SlicerResult VisitSlice(Slice slice, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 17
0
 public SlicerResult VisitConditionalExpression(ConditionalExpression c, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 18
0
        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)));
        }
Ejemplo n.º 19
0
 public SlicerResult VisitPhiFunction(PhiFunction phi, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 20
0
 public SlicerResult VisitPointerAddition(PointerAddition pa, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
 public SlicerResult VisitFieldAccess(FieldAccess acc, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 23
0
        public SlicerResult VisitSegmentedAccess(SegmentedAccess access, BackwardSlicerContext ctx)
        {
            var sr = access.EffectiveAddress.Accept(this, ctx);

            return(sr);
        }
Ejemplo n.º 24
0
 public SlicerResult VisitScopeResolution(ScopeResolution scopeResolution, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 25
0
 public SlicerResult VisitProcedureConstant(ProcedureConstant pc, BackwardSlicerContext ctx)
 {
     throw new NotImplementedException();
 }