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); }
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()); }
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); }
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); }
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()); }
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; } }
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; }
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); }
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()); }
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()); }
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()); }
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); }
/// <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); }
public void Usb_EmptyUserSignature() { Given_Procedure(0x1000); var oldSig = proc.Signature; var usb = new UserSignatureBuilder(program); usb.BuildSignatures(); Assert.AreSame(oldSig, proc.Signature); }
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); }
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); }
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); }
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()); }
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(); } } }
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); }
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); }
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()); }
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); }
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); }
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(); }
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); }
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()); } }