Example #1
0
        private bool TryGetNoDecompiledProcedure(Address addr, out ExternalProcedure ep)
        {
            Procedure_v1 sProc;

            if (!program.User.Procedures.TryGetValue(addr, out sProc) ||
                sProc.Decompile)
            {
                ep = null;
                return(false);
            }

            ProcedureSignature sig = null;

            if (!string.IsNullOrEmpty(sProc.CSignature))
            {
                var usb      = new UserSignatureBuilder(program);
                var procDecl = usb.ParseFunctionDeclaration(sProc.CSignature);
                if (procDecl != null)
                {
                    var ser = program.CreateProcedureSerializer();
                    sig = ser.Deserialize(
                        procDecl.Signature,
                        program.Architecture.CreateFrame());
                }
            }
            else
            {
                Warn(addr, "The user-defined procedure at address {0} did not have a signature.", addr);
            }

            ep = new ExternalProcedure(sProc.Name, sig);
            return(true);
        }
Example #2
0
        public void Usb_ParseFunctionDeclaration_UserDefinedTypes()
        {
            program.EnvironmentMetadata.Types.Add(
                "BYTE", PrimitiveType.Create(PrimitiveType.Byte.Domain, 8));

            Given_Procedure(0x1000);

            var usb = new UserSignatureBuilder(program);

            //should accept user defined type USRDEF1
            program.EnvironmentMetadata.Types.Add(
                "USRDEF1", PrimitiveType.Create(PrimitiveType.Int16.Domain, 16));

            var sProc = usb.ParseFunctionDeclaration("BYTE foo(USRDEF1 a, BYTE b)");

            Assert.AreEqual(
                "fn(arg(BYTE),(arg(a,USRDEF1),arg(b,BYTE)))",
                sProc.Signature.ToString());

            //should not accept undefined type USRDEF2
            sProc = usb.ParseFunctionDeclaration("BYTE foo(USRDEF1 a, USRDEF2 b)");
            Assert.AreEqual(null, sProc);

            //define USRDEF2 so parser should accept it

            program.EnvironmentMetadata.Types.Add(
                "USRDEF2", PrimitiveType.Create(PrimitiveType.Int16.Domain, 16));

            sProc = usb.ParseFunctionDeclaration("BYTE foo(USRDEF1 a, USRDEF2 b)");

            Assert.AreEqual(
                "fn(arg(BYTE),(arg(a,USRDEF1),arg(b,USRDEF2)))",
                sProc.Signature.ToString());
        }
Example #3
0
        protected override void RunTest(Program program, TextWriter writer)
        {
            var eventListener = new FakeDecompilerEventListener();
            var sc            = new ServiceContainer();

            sc.AddService <DecompilerEventListener>(eventListener);
            var dfa = new DataFlowAnalysis(
                program,
                dynamicLinker.Object,
                sc);

            program.User.Procedures = userSigs;
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignatures(eventListener);

            IntraBlockDeadRegisters.Apply(program, eventListener);

            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();
            DumpProcedureFlows(program, dfa, writer);
        }
        protected void Signature_TextChanged(object sender, EventArgs e)
        {
            // Attempt to parse the signature.
            var CSignature         = dlg.Signature.Text.Trim();
            ProcedureBase_v1 sProc = null;
            bool             isValid;

            if (!string.IsNullOrEmpty(CSignature))
            {
                var usb = new UserSignatureBuilder(program);
                sProc   = usb.ParseFunctionDeclaration(CSignature);
                isValid = (sProc != null);
            }
            else
            {
                CSignature = null;
                isValid    = true;
            }
            EnableControls(isValid);
            if (isValid)
            {
                if (sProc != null)
                {
                    dlg.ProcedureName.Text = sProc.Name;
                }
                EnableProcedureName();
            }
        }
        public void Dfa2_UserDefinedStackArgs()
        {
            var arch = new X86ArchitectureFlat32(new ServiceContainer(), "x86-protected-32", new Dictionary <string, object>());
            var pb   = new ProgramBuilder(arch);
            var test = pb.Add(
                new UserProcedure(pb.NextAddress(), "test")
            {
                CSignature = "void test(int a, int b)"
            },
                m => {
                var r1 = m.Reg32("r1", 1);
                var r2 = m.Reg32("r2", 2);
                var fp = m.Frame.FramePointer;
                m.Assign(r1, m.Mem32(m.IAdd(fp, 4)));
                m.Assign(r2, m.Mem32(m.IAdd(fp, 8)));
                m.Assign(r1, m.IAdd(r1, r2));
                m.MStore(m.Ptr32(0x010008), r1);
                m.Return();
            });
            var program  = pb.BuildProgram();
            var platform = new Mock <IPlatform>();

            platform.Setup(p => p.Architecture).Returns(arch);
            platform.Setup(p => p.IsImplicitArgumentRegister(It.IsAny <RegisterStorage>()))
            .Returns(false);
            platform.Setup(p => p.DefaultCallingConvention).Returns("__cdecl");
            platform.Setup(p => p.GetCallingConvention(null))
            .Returns(new X86CallingConvention(4, 4, 4, true, false));
            platform.Setup(p => p.GetBitSizeFromCBasicType(CBasicType.Int)).Returns(32);
            platform.Setup(p => p.PointerType).Returns(PrimitiveType.Ptr32);
            platform.Setup(p => p.CreateCParser(It.IsAny <TextReader>(), It.IsAny <ParserState>()))
            .Returns(new Func <TextReader, ParserState, CParser>((r, s) =>
            {
                var lex = new CLexer(r, CLexer.MsvcKeywords);
                return(new CParser(s ?? new ParserState(), lex));
            }));

            var dynamicLinker = new Mock <IDynamicLinker>().Object;

            program.Platform = platform.Object;
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignatures(new FakeDecompilerEventListener());
            var dfa = new DataFlowAnalysis(program, dynamicLinker, sc);

            dfa.AnalyzeProgram();
            var sExp = @"// test
// Return size: 4
void test(int32 a, int32 b)
test_entry:
	// succ:  l1
l1:
	Mem6[0x00010008<p32>:word32] = a + b
	return
	// succ:  test_exit
test_exit:
";

            AssertProgram(sExp, pb.Program);
        }
Example #6
0
        private bool TryGetNoDecompiledParsedProcedure(Address addr, out Procedure_v1 parsedProc)
        {
            if (!TryGetNoDecompiledProcedure(addr, out Procedure_v1 sProc))
            {
                parsedProc = null;
                return(false);
            }
            if (noDecompiledProcs.TryGetValue(addr, out parsedProc))
            {
                return(true);
            }
            parsedProc = new Procedure_v1()
            {
                Name = sProc.Name,
            };
            noDecompiledProcs[addr] = parsedProc;
            if (string.IsNullOrEmpty(sProc.CSignature))
            {
                Warn(addr, "The user-defined procedure at address {0} did not have a signature.", addr);
                return(true);
            }
            var usb      = new UserSignatureBuilder(Program);
            var procDecl = usb.ParseFunctionDeclaration(sProc.CSignature);

            if (procDecl == null)
            {
                Warn(addr, "The user-defined procedure signature at address {0} could not be parsed.", addr);
                return(true);
            }
            parsedProc.Signature = procDecl.Signature;
            return(true);
        }
Example #7
0
        public void Usb_BuildSignatures_UserDefinedTypes()
        {
            program.EnvironmentMetadata.Types.Add(
                "PLATFORMDEF",
                PrimitiveType.Create(PrimitiveType.Byte.Domain, 8));
            program.EnvironmentMetadata.Types.Add(
                "USRDEF",
                PrimitiveType.Create(PrimitiveType.Int16.Domain, 16));
            Given_Procedure(0x1000);
            Given_UserSignature(0x01000, "int test(PLATFORMDEF a, USRDEF b)");

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignatures(new FakeDecompilerEventListener());

            var sigExp =
                @"Register int32 test(Stack PLATFORMDEF a, Stack USRDEF b)
// stackDelta: 4; fpuStackDelta: 0; fpuMaxParam: -1
";

            Assert.AreEqual(sigExp, proc.Signature.ToString("test", FunctionType.EmitFlags.AllDetails));

            Assert.AreEqual(2, proc.Signature.Parameters.Length);
            Assert.AreEqual("int32", proc.Signature.ReturnValue.DataType.ToString());
            Assert.AreEqual("a", proc.Signature.Parameters[0].Name);
            Assert.AreEqual("byte", (proc.Signature.Parameters[0].DataType as TypeReference).Referent.ToString());
            Assert.AreEqual("b", proc.Signature.Parameters[1].Name);
            Assert.AreEqual("int16", (proc.Signature.Parameters[1].DataType as TypeReference).Referent.ToString());
        }
Example #8
0
        public void SetUserProcedure(ulong linearAddress, string decl)
        {
            var    addr = Addr(linearAddress);
            string name;
            string?CSignature;

            if (UserSignatureBuilder.IsValidCIdentifier(decl))
            {
                name       = decl;
                CSignature = null;
            }
            else
            {
                var usb   = new UserSignatureBuilder(program);
                var sProc = usb.ParseFunctionDeclaration(decl);
                if (sProc is null || sProc.Name is null)
                {
                    throw new ArgumentException(
                              $"Failed to parse procedure declaration: '{decl}'");
                }
                name       = sProc.Name;
                CSignature = decl;
            }
            program.User.Procedures[addr] = new UserProcedure(addr, name)
            {
                CSignature = CSignature,
            };
            if (program.Procedures.TryGetValue(addr, out var proc))
            {
                proc.Name = name;
            }
        }
Example #9
0
        private void EnableControls()
        {
            ProcedureBase_v1  sProc;
            GlobalDataItem_v2 global;
            var procText = declarationForm.TextBox.Text;

            if (TryParseSignature(procText, out sProc))
            {
                declarationForm.TextBox.ForeColor = SystemColors.ControlText;
                return;
            }
            if (!editProcedure && TryParseGlobal(procText, out global))
            {
                declarationForm.TextBox.ForeColor = SystemColors.ControlText;
                return;
            }
            // If parser failed, perhaps it's simply a valid name?
            if (UserSignatureBuilder.IsValidCIdentifier(procText))
            {
                declarationForm.TextBox.ForeColor = SystemColors.ControlText;;
                return;
            }
            // Not valid name either, die.
            declarationForm.TextBox.ForeColor = Color.Red;
        }
Example #10
0
        public ProcedureBase ScanProcedure(IProcessorArchitecture arch, Address addr, string?procedureName, ProcessorState state)
        {
            TerminateAnyBlockAt(addr);
            if (TryGetNoDecompiledProcedure(addr, out var ep))
            {
                return(ep);
            }
            if (Program.InterceptedCalls.TryGetValue(addr, out ep))
            {
                return(ep);
            }
            var trampoline = GetTrampoline(arch, addr);

            if (trampoline != null)
            {
                return(trampoline);
            }

            var imp = GetImportedProcedure(arch, addr, addr);

            if (imp != null)
            {
                return(imp);
            }
            Procedure proc = Program.EnsureProcedure(arch, addr, procedureName);

            if (visitedProcs.Contains(proc))
            {
                return(proc);
            }

            visitedProcs.Add(proc);
            trace.Inform("Scanning procedure at {0}", addr);

            var st = state.Clone();

            EstablishInitialState(addr, st, proc);

            //$REFACTOR: make the stack explicit?
            var oldQueue = procQueue;

            procQueue = new PriorityQueue <WorkItem>();
            var block = EnqueueJumpTarget(addr, addr, proc, st);

            if (proc.EntryBlock.Succ.Count == 0)
            {
                proc.ControlGraph.AddEdge(proc.EntryBlock, block !);
            }
            ProcessQueue();

            procQueue = oldQueue;

            InjectProcedureEntryInstructions(addr, proc);
            var usb = new UserSignatureBuilder(Program);

            usb.BuildSignature(addr, proc);
            cinj.InjectComments(proc);
            return(proc);
        }
Example #11
0
        public void Usb_ParseGlobalDeclaration_Int()
        {
            var usb = new UserSignatureBuilder(program);
            var gbl = usb.ParseGlobalDeclaration("int test123");

            Assert.AreEqual("test123", gbl.Name);
            Assert.AreEqual("prim(SignedInt,4)", gbl.DataType.ToString());
        }
Example #12
0
        public void Usb_ParseGlobalDeclaration_ArrayOfDouble()
        {
            var usb = new UserSignatureBuilder(program);
            var gbl = usb.ParseGlobalDeclaration("double dArr[12]");

            Assert.AreEqual("dArr", gbl.Name);
            Assert.AreEqual("arr(prim(Real,8),12)", gbl.DataType.ToString());
        }
Example #13
0
        public void Usb_ParseGlobalDeclaration_PointerToUnsignedInt()
        {
            var usb = new UserSignatureBuilder(program);
            var gbl = usb.ParseGlobalDeclaration("unsigned int *uiPtr");

            Assert.AreEqual("uiPtr", gbl.Name);
            Assert.AreEqual("ptr(prim(UnsignedInt,4))", gbl.DataType.ToString());
        }
Example #14
0
        public void Usb_NameWithoutSignature()
        {
            Given_Procedure(0x1000);
            Given_UserName(0x1000, "usrName");
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
            Assert.AreEqual("usrName", proc.Name);
        }
Example #15
0
        /// <summary>
        /// Performs a scan of the blocks that constitute a procedure named <paramref name="procedureName"/>
        /// </summary>
        /// <param name="addr">Address of the code from which we will start scanning.</param>
        /// <param name="procedureName"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public ProcedureBase ScanProcedure(Address addr, string procedureName, ProcessorState state)
        {
            TerminateAnyBlockAt(addr);
            ExternalProcedure ep;

            if (TryGetNoDecompiledProcedure(addr, out ep))
            {
                return(ep);
            }
            if (program.InterceptedCalls.TryGetValue(addr, out ep))
            {
                return(ep);
            }
            var trampoline = GetTrampoline(addr);

            if (trampoline != null)
            {
                return(trampoline);
            }

            var imp = GetImportedProcedure(addr, addr);

            if (imp != null)
            {
                return(imp);
            }
            Procedure proc = EnsureProcedure(addr, procedureName);

            if (visitedProcs.Contains(proc))
            {
                return(proc);
            }

            visitedProcs.Add(proc);
            Debug.WriteLineIf(trace.TraceInfo, string.Format("Scanning procedure at {0}", addr));

            var st = state.Clone();

            EstablishInitialState(addr, st, proc);

            //$REFACTOR: make the stack explicit?
            var oldQueue = queue;

            queue = new PriorityQueue <WorkItem>();
            var block = EnqueueJumpTarget(addr, addr, proc, st);

            proc.ControlGraph.AddEdge(proc.EntryBlock, block);
            ProcessQueue();

            queue = oldQueue;

            InjectProcedureEntryInstructions(addr, proc);
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(addr, proc);
            return(proc);
        }
Example #16
0
        public void Usb_EmptyUserSignature()
        {
            Given_Procedure(0x1000);

            var oldSig = proc.Signature;
            var usb    = new UserSignatureBuilder(program);

            usb.BuildSignatures();
            Assert.AreSame(oldSig, proc.Signature);
        }
Example #17
0
        public void Usb_Word32()
        {
            Given_Procedure(0x1000);
            Given_UserSignature(0x1000, "void test(word32 foo)");
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
            Assert.AreEqual("(fn void (word32))", proc.Signature.ToString());
            Assert.AreSame(PrimitiveType.Word32, proc.Signature.Parameters[0].DataType);
        }
Example #18
0
        public void Usb_NoDecompileProcedure()
        {
            Given_UnscannedProcedure(0x1000);
            Given_UserSignature(0x01000, "void test([[reko::arg(register,\"ecx\")]] float f)");
            Given_UserProcDecompileFlag(0x1000, false);

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);
        }
Example #19
0
        public void Usb_EmptyUserSignature()
        {
            Given_Procedure(0x1000);

            var oldSig = proc.Signature;
            var usb    = new UserSignatureBuilder(program);

            usb.BuildSignatures(new FakeDecompilerEventListener());
            Assert.AreSame(oldSig, proc.Signature);
        }
Example #20
0
        public void Usb_ParseFunctionDeclaration()
        {
            Given_Procedure(0x1000);

            var usb   = new UserSignatureBuilder(program);
            var sProc = usb.ParseFunctionDeclaration("int foo(char *)");

            Assert.AreEqual(
                "fn(arg(prim(SignedInt,4)),(arg(ptr(prim(Character,1)))))",
                sProc.Signature.ToString());
        }
Example #21
0
        private void ModifyDeclaration()
        {
            var       declText = declarationForm.TextBox.Text.Trim();
            Procedure proc;

            if (!program.Procedures.TryGetValue(address, out proc))
            {
                proc = null;
            }
            ProcedureBase_v1  sProc;
            GlobalDataItem_v2 parsedGlobal;
            string            procName   = null;
            string            CSignature = null;

            if (TryParseSignature(declText, out sProc))
            {
                procName   = sProc.Name;
                CSignature = declText;
            }
            else if (UserSignatureBuilder.IsValidCIdentifier(declText) &&
                     (proc == null || proc.Name != declText))
            {
                procName = declText;
            }
            else if (!editProcedure && TryParseGlobal(declText, out parsedGlobal))
            {
                program.User.Procedures.Remove(address);
                program.ModifyUserGlobal(
                    program.Architecture,
                    address,
                    parsedGlobal.DataType,
                    parsedGlobal.Name
                    );
            }

            if (procName != null)
            {
                program.RemoveUserGlobal(address);
                var up = program.EnsureUserProcedure(address, procName);
                if (CSignature != null)
                {
                    up.CSignature = CSignature;
                }
                if (proc != null)
                {
                    proc.Name = procName;
                }
                else
                {
                    var pAddr = new ProgramAddress(program, address);
                    services.RequireService <ICommandFactory>().MarkProcedure(pAddr).Do();
                }
            }
        }
Example #22
0
        public void Usb_BuildSignature_Stdcall()
        {
            Given_Procedure(0x1000);
            Given_UserSignature(0x01000, "char * __stdcall test(int i, float f, double d)");

            var usb = new UserSignatureBuilder(program);

            usb.BuildSignature(Address.Ptr32(0x1000), proc);

            Assert.AreEqual(20, proc.Signature.StackDelta);
        }
Example #23
0
        public void Dfa2_UserDefinedStackArgs()
        {
            var arch = new X86ArchitectureFlat32(new ServiceContainer(), "x86-protected-32");
            var pb   = new ProgramBuilder(arch);
            var test = pb.Add(
                new Procedure_v1
            {
                CSignature = "void test(int a, int b)"
            },
                m => {
                var r1 = m.Reg32("r1", 1);
                var r2 = m.Reg32("r2", 2);
                var fp = m.Frame.FramePointer;
                m.Assign(r1, m.Mem32(m.IAdd(fp, 4)));
                m.Assign(r2, m.Mem32(m.IAdd(fp, 8)));
                m.Assign(r1, m.IAdd(r1, r2));
                m.MStore(m.Ptr32(0x010008), r1);
                m.Return();
            });
            var program  = pb.BuildProgram();
            var platform = new Mock <IPlatform>();

            platform.Setup(p => p.Architecture).Returns(arch);
            platform.Setup(p => p.CreateImplicitArgumentRegisters()).Returns(
                new HashSet <RegisterStorage>());
            platform.Setup(p => p.DefaultCallingConvention).Returns("__cdecl");
            platform.Setup(p => p.GetCallingConvention(null))
            .Returns(new X86CallingConvention(4, 4, 4, true, false));
            platform.Setup(p => p.GetByteSizeFromCBasicType(CBasicType.Int)).Returns(4);

            var dynamicLinker = new Mock <IDynamicLinker>().Object;

            program.Platform = platform.Object;
            var usb = new UserSignatureBuilder(program);

            usb.BuildSignatures(new FakeDecompilerEventListener());
            var dfa = new DataFlowAnalysis(program, dynamicLinker, sc);

            dfa.AnalyzeProgram();
            var sExp = @"// test
// Return size: 4
void test(int32 a, int32 b)
test_entry:
	// succ:  l1
l1:
	Mem6[0x00010008<p32>:word32] = a + b
	return
	// succ:  test_exit
test_exit:
";

            AssertProgram(sExp, pb.Program);
        }
Example #24
0
        public void Usb_ParseFunctionDeclaration_PlatfromTypes()
        {
            program.EnvironmentMetadata.Types.Add(
                "BYTE",
                PrimitiveType.Create(PrimitiveType.Byte.Domain, 8));
            Given_Procedure(0x1000);

            var usb   = new UserSignatureBuilder(program);
            var sProc = usb.ParseFunctionDeclaration("BYTE foo(BYTE a, BYTE b)");

            Assert.AreEqual(
                "fn(arg(BYTE),(arg(a,BYTE),arg(b,BYTE)))",
                sProc.Signature.ToString());
        }
Example #25
0
        private bool TryParseGlobal(string txtGlobal, out GlobalDataItem_v2 global)
        {
            global = null;
            if (program == null || program.Platform == null)
            {
                return(false);
            }

            // Attempt to parse the global declaration.
            var usb = new UserSignatureBuilder(program);

            global = usb.ParseGlobalDeclaration(txtGlobal);
            return(global != null);
        }
Example #26
0
        private bool TryParseSignature(string txtSignature, out ProcedureBase_v1 sProc)
        {
            sProc = null;
            if (program == null || program.Platform == null)
            {
                return(false);
            }

            // Attempt to parse the signature.
            var usb = new UserSignatureBuilder(program);

            sProc = usb.ParseFunctionDeclaration(txtSignature);
            return(sProc != null);
        }
Example #27
0
        public void SetUserGlobal(ulong linearAddress, string decl)
        {
            var addr     = Addr(linearAddress);
            var usb      = new UserSignatureBuilder(program);
            var global   = usb.ParseGlobalDeclaration(decl);
            var name     = global?.Name;
            var dataType = global?.DataType;

            if (name is null || dataType is null)
            {
                throw new ArgumentException(
                          $"Failed to parse global variable declaration: '{decl}'");
            }
            program.User.Globals[addr] = new UserGlobal(addr, name, dataType);
        }
        public void Usb_BuildSignature()
        {
            Given_Procedure(0x1000);
            var ser = mr.Stub <ProcedureSerializer>(arch, null, "cdecl");

            platform.Expect(s => s.CreateProcedureSerializer(null, null)).IgnoreArguments().Return(ser);
            ser.Expect(s => s.Deserialize(
                           Arg <SerializedSignature> .Is.NotNull,
                           Arg <Frame> .Is.NotNull)).Return(new ProcedureSignature());
            mr.ReplayAll();

            var usb = new UserSignatureBuilder(program);
            var sig = usb.BuildSignature("int foo(char *)", proc.Frame);

            mr.ReplayAll();
        }
Example #29
0
        public void SetUserGlobal(Address addr, string decl)
        {
            var usb      = new UserSignatureBuilder(program);
            var global   = usb.ParseGlobalDeclaration(decl);
            var name     = global?.Name;
            var dataType = global?.DataType;

            if (name is null || dataType is null)
            {
                throw new ArgumentException(
                          $"Failed to parse global variable declaration: '{decl}'.");
            }
            var arch = program.Architecture;

            program.ModifyUserGlobal(arch, addr, dataType, name);
        }
Example #30
0
 private void SetCSignatures(Program program)
 {
     foreach (var addr in program.Procedures.Keys)
     {
         program.User.Procedures.Add(
             addr,
             new Procedure_v1
         {
             CSignature = this.CSignature
         });
     }
     if (this.CSignature != null)
     {
         var usb = new UserSignatureBuilder(program);
         usb.BuildSignatures(new FakeDecompilerEventListener());
     }
 }