示例#1
0
        public void GcrStackArguments()
        {
            Frame f = program.Architecture.CreateFrame();

            f.ReturnAddressKnown = true;
            f.ReturnAddressSize  = PrimitiveType.Word16.Size;

            var uses = new List <KeyValuePair <Storage, BitRange> >
            {
                new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(8, PrimitiveType.Word16), new BitRange(0, 16)),
                new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(6, PrimitiveType.Word16), new BitRange(0, 16)),
                new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(0xE, PrimitiveType.Word32), new BitRange(0, 32))
            };

            CallRewriter gcr = new CallRewriter(null, null, new FakeDecompilerEventListener());

            using (FileUnitTester fut = new FileUnitTester("Analysis/GcrStackParameters.txt"))
            {
                foreach ((int, Identifier)de in gcr.GetSortedStackArguments(f, uses))
                {
                    fut.TextWriter.Write("{0:X4} ", de.Item1);
                    de.Item2.Write(true, fut.TextWriter);
                    fut.TextWriter.WriteLine();
                }
                fut.AssertFilesEqual();
            }
        }
示例#2
0
        public void CrwMakeSig_Sequence_InArg()
        {
            flow.BitsUsed.Add(new SequenceStorage(Registers.edx, Registers.eax), new BitRange(0, 64));
            var crw = new CallRewriter(program.Platform, new ProgramDataFlow(), eventListener);
            var sig = crw.MakeSignature(new SsaState(proc), proc.Frame, flow);

            Assert.AreEqual("(fn void (word64))", sig.ToString());
        }
示例#3
0
        private CallRewriter When_CallRewriterCreated()
        {
            var program = pb.BuildProgram();
            var flow    = new ProgramDataFlow(program);
            var crw     = new CallRewriter(
                program.Platform,
                flow,
                new FakeDecompilerEventListener());

            return(crw);
        }
示例#4
0
 public void Setup()
 {
     program = new Program();
     program.Architecture = new X86ArchitectureFlat32("x86-protected-32");
     program.Platform     = new DefaultPlatform(null, program.Architecture);
     crw           = new CallRewriter(program.Platform, new ProgramDataFlow(), new FakeDecompilerEventListener());
     proc          = new Procedure(program.Architecture, "foo", Address.Ptr32(0x00123400), program.Architecture.CreateFrame());
     flow          = new ProcedureFlow(proc);
     ssa           = new SsaState(proc);
     pb            = new ProgramBuilder();
     ssaStates     = new List <SsaState>();
     eventListener = new FakeDecompilerEventListener();
 }
示例#5
0
        public void CrwSinglePredecessorToExitBlock()
        {
            var m   = new ProcedureBuilder("CrwSinglePredecessorToExitBlock");
            var eax = m.Frame.EnsureRegister(Registers.eax);

            m.Assign(eax, m.Mem32(eax));
            m.Return();

            var flow = new ProgramDataFlow(program);
            var sst  = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow());

            sst.Transform();
            sst.AddUsesToExitBlock();
            sst.SsaState.Procedure.Signature = FunctionType.Func(
                new Identifier("", PrimitiveType.Word32, Registers.eax),
                new Identifier("eax", PrimitiveType.Word32, Registers.eax));

            var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener());

            crw.RewriteReturns(sst.SsaState);
            crw.RemoveStatementsFromExitBlock(sst.SsaState);

            var sExp =
                #region Expected
                @"eax:eax
    def:  def eax
    uses: eax_3 = Mem0[eax:word32]
Mem0:Mem
    def:  def Mem0
    uses: eax_3 = Mem0[eax:word32]
eax_3: orig: eax
    def:  eax_3 = Mem0[eax:word32]
    uses: return eax_3
// CrwSinglePredecessorToExitBlock
// Return size: 0
word32 CrwSinglePredecessorToExitBlock(word32 eax)
CrwSinglePredecessorToExitBlock_entry:
	def eax
	def Mem0
	// succ:  l1
l1:
	eax_3 = Mem0[eax:word32]
	return eax_3
	// succ:  CrwSinglePredecessorToExitBlock_exit
CrwSinglePredecessorToExitBlock_exit:
";

            #endregion
            AssertExpected(sExp, sst.SsaState);
        }
示例#6
0
 public void Setup()
 {
     program = new Program();
     sc      = new ServiceContainer();
     program.Architecture = new X86ArchitectureFlat32(sc, "x86-protected-32", new Dictionary <string, object>());
     program.Platform     = new DefaultPlatform(sc, program.Architecture);
     crw           = new CallRewriter(program.Platform, new ProgramDataFlow(), new FakeDecompilerEventListener());
     proc          = new Procedure(program.Architecture, "foo", Address.Ptr32(0x00123400), program.Architecture.CreateFrame());
     flow          = new ProcedureFlow(proc);
     ssa           = new SsaState(proc);
     pb            = new ProgramBuilder();
     ssaStates     = new List <SsaState>();
     eventListener = new FakeDecompilerEventListener();
     sc.AddService <DecompilerEventListener>(eventListener);
 }
示例#7
0
        protected override void RunTest(Program program, TextWriter writer)
        {
            var dynamicLinker = new Mock <IDynamicLinker>();

            dfa = new DataFlowAnalysis(program, dynamicLinker.Object, sc);
            var ssts = dfa.RewriteProceduresToSsa();

            // Discover ssaId's that are live out at each call site.
            // Delete all others.
            var uvr = new UnusedOutValuesRemover(
                program,
                ssts.Select(sst => sst.SsaState),
                dfa.ProgramDataFlow,
                dynamicLinker.Object,
                eventListener);

            uvr.Transform();

            foreach (var p in program.Procedures.Values)
            {
                p.Dump(true);
                Debug.Print("====");
            }

            // At this point, the exit blocks contain only live out registers.
            // We can create signatures from that.
            CallRewriter.Rewrite(program.Platform, ssts, dfa.ProgramDataFlow, eventListener);
            foreach (var proc in program.Procedures.Values)
            {
                var flow = dfa.ProgramDataFlow[proc];
                proc.Signature.Emit(proc.Name, FunctionType.EmitFlags.ArgumentKind, new TextFormatter(writer));
                writer.WriteLine();
                flow.Emit(program.Architecture, writer);
                proc.Write(true, writer);
                writer.Flush();
            }
            ssts.ForEach(sst => sst.SsaState.Validate(s => Assert.Fail(s)));
        }
示例#8
0
        public void CrwManyPredecessorsToExitBlock()
        {
            var m   = new ProcedureBuilder("CrwManyPredecessorsToExitBlock");
            var eax = m.Frame.EnsureRegister(Registers.eax);

            m.BranchIf(m.Ge0(eax), "m2Ge");

            m.Label("m1Lt");
            m.Assign(eax, -1);
            m.Return();

            m.Label("m2Ge");
            m.BranchIf(m.Ne0(eax), "m4Gt");

            m.Label("m3Eq");
            m.Return();

            m.Label("m4Gt");
            m.Assign(eax, 1);
            m.Return();

            var flow = new ProgramDataFlow(program);
            var sst  = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow());

            sst.Transform();
            sst.AddUsesToExitBlock();
            sst.SsaState.Procedure.Signature = FunctionType.Func(
                new Identifier("", PrimitiveType.Word32, Registers.eax),
                new Identifier("eax", PrimitiveType.Word32, Registers.eax));

            var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener());

            crw.RewriteReturns(sst.SsaState);
            crw.RemoveStatementsFromExitBlock(sst.SsaState);

            var sExp =
                #region Expected
                @"eax:eax
    def:  def eax
    uses: branch eax >= 0<32> m2Ge
          branch eax != 0<32> m4Gt
          return eax
eax_2: orig: eax
    def:  eax_2 = 1<32>
    uses: return eax_2
eax_3: orig: eax
    def:  eax_3 = 0xFFFFFFFF<32>
    uses: return eax_3
eax_4: orig: eax
// CrwManyPredecessorsToExitBlock
// Return size: 0
word32 CrwManyPredecessorsToExitBlock(word32 eax)
CrwManyPredecessorsToExitBlock_entry:
	def eax
	// succ:  l1
l1:
	branch eax >= 0<32> m2Ge
	// succ:  m1Lt m2Ge
m1Lt:
	eax_3 = 0xFFFFFFFF<32>
	return eax_3
	// succ:  CrwManyPredecessorsToExitBlock_exit
m2Ge:
	branch eax != 0<32> m4Gt
	// succ:  m3Eq m4Gt
m3Eq:
	return eax
	// succ:  CrwManyPredecessorsToExitBlock_exit
m4Gt:
	eax_2 = 1<32>
	return eax_2
	// succ:  CrwManyPredecessorsToExitBlock_exit
CrwManyPredecessorsToExitBlock_exit:
";

            #endregion
            AssertExpected(sExp, sst.SsaState);
        }