public void Upsert_All_Frames_At_The_Current_Position() { var options = new IndexOptions() { MemoryRanges = new [] { new MemoryRange(0x100, 0x200), } }; var indexMethod = new IndexMethod(); var sc = new ServerClientBuilder(); sc.WithUpsertFrames(() => { }); sc.WithAddMemoryRange(); var ttf = new TimeTravelFacadeBuilder(); ttf.WithPositions(new PositionsResult(new[] { new PositionsRecord(1, new Position(1, 1), true), new PositionsRecord(2, new Position(1, 1), false), })); var dbg = new DebugEngineProxyBuilder(); dbg.WithReadVirtualMemory(new byte[] { 0x00, 0x11 }); indexMethod.ServerClient = sc.Build(); indexMethod.TimeTravelFacade = ttf.Build(); indexMethod.DebugEngineProxy = dbg.Build(); indexMethod.UpsertCurrentPosition(options); sc.Mock.Verify(client => client.UpsertFrames(It.Is <IEnumerable <Frame> >(frames => frames.Count() == 2)), Times.Once); sc.Mock.Verify(client => client.AddMemoryRange(It.IsAny <MemoryChunk>()), Times.Once); }
public void Pass_Correct_Values_To_Server_Client() { // arrange var args = new[] { "-n", "test" }; var initMethod = new InitMethod(); var clientBuilder = new ServerClientBuilder(); var dbg = new DebugEngineProxyBuilder(); var builder = new TimeTravelFacadeBuilder(dbg); builder.WithGetStartingPosition(new Position(0, 0)).WithGetEndingPosition(new Position(1, 0)); initMethod.TimeTravelFacade = builder.Build(); initMethod.ServerClient = clientBuilder.Build(); initMethod.Settings = new Settings { ServerUrl = "http://localhost:5000" }; // act initMethod.Process(args); // assert clientBuilder.Mock.Verify( client => client.InitializeProject("test", new Position(0, 0), new Position(1, 0)), Times.Once); }
public void Get_The_Ending_Position() { // arrange var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult("!tt 100", @"Setting position to the end of the trace Setting position: 2D164:0 ModLoad: 00007ffa`4cc00000 00007ffa`4cc95000 C:\WINDOWS\system32\uxtheme.dll ModLoad: 00007ffa`4cec0000 00007ffa`4ceea000 C:\WINDOWS\SYSTEM32\dwmapi.dll ModLoad: 00007ffa`4fc30000 00007ffa`4fd97000 C:\WINDOWS\System32\MSCTF.dll ModLoad: 00007ffa`51a80000 00007ffa`51b1e000 C:\WINDOWS\System32\clbcatq.dll ModLoad: 00007ffa`4d750000 00007ffa`4d781000 C:\WINDOWS\SYSTEM32\ntmarta.dll ModLoad: 00007ffa`4c1e0000 00007ffa`4c2bc000 C:\WINDOWS\System32\CoreMessaging.dll ModLoad: 00007ffa`49f70000 00007ffa`4a0a6000 C:\WINDOWS\SYSTEM32\wintypes.dll ModLoad: 00007ffa`48270000 00007ffa`4855e000 C:\WINDOWS\System32\CoreUIComponents.dll ModLoad: 00007ffa`33e40000 00007ffa`33ed8000 C:\WINDOWS\System32\TextInputFramework.dll (9b04.7590): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 2D164:0 ntdll!NtTerminateProcess+0x12: 00007ffa`523603f2 0f05 syscall"); var facade = new TimeTravelFacade { DebugEngineProxy = builder.Build() }; // act var position = facade.GetEndingPosition(); // assert position.Should().Be(new Position(0x2D164, 0)); }
public void Print_Command_Listing_When_No_Args() { var helpMethod = new HelpMethod(); var dbg = new DebugEngineProxyBuilder(); string output = null; dbg.WithWriteLine(s => output = s); helpMethod.DebugEngineProxy = dbg.Build(); helpMethod.Methods = new IMcFlyMethod[] { new IndexMethod(), new InitMethod(), new HelpMethod(), new SettingsMethod(), new StartMethod() }; var expected = @"5 Available commands: index Record the state of registers, memory, etc for further analysis init Create a new project using the loaded trace file help Get help and find commands settings Manage application settings start Start the local server Get extended help: !mf help command "; helpMethod.Process("".Split(' ')); output.Should().Be(expected); }
public void Disassemble_The_Correct_Number_Of_Instructions() { // arrange var builder = new DebugEngineProxyBuilder(); builder.With32Bit(false); builder.WithExecuteResult("u rip L2", @"KERNEL32!GetTimeFormatWWorker+0xc43: 00007ffa`51315543 6645898632010000 mov word ptr [r14+132h],r8w 00007ffa`5131554b 498d8630010000 lea rax,[r14+130h] "); var facade = new DisassemblyFacade { DebugEngineProxy = builder.Build() }; var expected = new[] { new DisassemblyLine(0x00007ffa51315543, ByteArrayBuilder.StringToByteArray("6645898632010000"), "mov", "word ptr [r14+132h],r8w"), new DisassemblyLine(0x00007ffa5131554b, ByteArrayBuilder.StringToByteArray("498d8630010000"), "lea", "rax,[r14+130h]") }; // act var lines = facade.GetDisassemblyLines(2); // assert lines.Should().Equal(expected); }
public void Get_The_Correct_Current_Position() { // arrange var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult("!positions", @">Thread ID=0x7590 - Position: 35:0 Thread ID=0x12A0 - Position: 246A:0 Thread ID=0x6CDC - Position: 21D59:0 Thread ID=0x2984 - Position: 21DFE:0 Thread ID=0x3484 - Position: 21ECA:0 Thread ID=0x60B4 - Position: 2414F:0 Thread ID=0x1F54 - Position: 241DE:0 "); var facade = new TimeTravelFacade { DebugEngineProxy = builder.Build() }; // act var position = facade.GetCurrentPosition(); var threadPosition = facade.GetCurrentPosition(0x60b4); // assert position.Should().Be(new Position(0x35, 0)); threadPosition.Should().Be(new Position(0x2414f, 0)); }
public void Set_Breakpoint_By_Mask_Correctly() { // arrange var facade = new BreakpointFacade(); var builder = new DebugEngineProxyBuilder(); facade.DebugEngineProxy = builder.Build(); // act facade.SetBreakpointByMask("kernel32", "createprocess*"); // assert builder.Mock.Verify(proxy => proxy.Execute("bm kernel32!createprocess*"), Times.Once); }
public void Set_Write_Breakpoint_Correctly() { // arrange var facade = new BreakpointFacade(); var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult(""); facade.DebugEngineProxy = builder.Build(); // act facade.SetWriteAccessBreakpoint(8, 0x100); // assert builder.Mock.Verify(proxy => proxy.Execute("ba w8 100"), Times.Once); }
public void Clear_Breakpoints() { // arrange var facade = new BreakpointFacade(); var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult(""); facade.DebugEngineProxy = builder.Build(); // act facade.ClearBreakpoints(); // assert builder.Mock.Verify(proxy => proxy.Execute("bc *"), Times.Once); }
public void Set_The_Position_Correctly() { // arrange var facade = new TimeTravelFacade(); var position = new Position(0, 0); var builder = new DebugEngineProxyBuilder(); facade.DebugEngineProxy = builder.Build(); // act facade.SetPosition(position); // assert builder.Mock.Verify(proxy => proxy.Execute("!tt 0:0"), Times.Once); }
public void Get_The_Current_Frame_Correctly() { // arrange var engBuilder = new DebugEngineProxyBuilder(); engBuilder.WithExecuteResult("!positions", @">Thread ID=0x7590 - Position: 168CC:0 Thread ID=0x12A0 - Position: 211F5:0 Thread ID=0x6CDC - Position: 21D59:0 Thread ID=0x2984 - Position: 21DFE:0 Thread ID=0x3484 - Position: 21ECA:0 Thread ID=0x60B4 - Position: 2414F:0 Thread ID=0x1F54 - Position: 241DE:0 "); engBuilder.With32Bit(false); engBuilder.WithThreadId(0x7590); var stackBuilder = new StackFacadeBuilder(); var stackTrace = new StackTrace(new List <StackFrame>()); stackBuilder.WithGetCurrentStackTrace(stackTrace); var registerSet = new RegisterSet(); var registerBuilder = new RegisterFacadeBuilder(); registerBuilder.WithGetCurrentRegisterSet(Register.All, registerSet); var disassemblyLine = new DisassemblyLine(0x00007ffa51315595, ByteArrayBuilder.StringToByteArray("4d3bd1"), "cmp", "r10,r9"); var disBuilder = new DisassemblyFacadeBuilder(); disBuilder.WithGetDisassemblyLines(1, new[] { disassemblyLine }); var facade = new TimeTravelFacade { DebugEngineProxy = engBuilder.Build(), StackFacade = stackBuilder.Build(), RegisterFacade = registerBuilder.Build(), DisassemblyFacade = disBuilder.Build() }; // act var frame = facade.GetCurrentFrame(); // assert frame.Position.Should().Be(new Position(0x168CC, 0)); frame.DisassemblyLine.Should().Be(disassemblyLine); frame.RegisterSet.Should().Be(registerSet); frame.StackTrace.Should().Be(stackTrace); frame.ThreadId.Should().Be(0x7590); }
public void Enforce_Length_Restrictions() { // arrange var facade = new BreakpointFacade(); var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult(""); facade.DebugEngineProxy = builder.Build(); Action shouldThrow = () => facade.SetReadAccessBreakpoint(10, 0x100); Action shouldThrow2 = () => facade.SetWriteAccessBreakpoint(10, 0x100); // act // assert shouldThrow.Should().Throw <ArgumentOutOfRangeException>(); shouldThrow2.Should().Throw <ArgumentOutOfRangeException>(); }
public void Throw_If_Time_Travel_Position_Cant_Be_Determined() { var facade = new TimeTravelFacade(); var position = new Position(0, 0); var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult(@"Setting position to the beginning of the trace Setting position: E:0 Breakpoint 0 hit Time Travel Position E:0 ntdll!NtSetInformationWorkerFactory+0x14: 00007ffc`f0ee3554 c3 ret"); facade.DebugEngineProxy = builder.Build(); Action a = () => facade.SetPosition(position); a.Should().Throw <ApplicationException>(); }
public void Upsert_Frames_From_Breaks() { var dbg = new DebugEngineProxyBuilder(); var tt = new TimeTravelFacadeBuilder(dbg); var sc = new ServerClientBuilder(); var bp = new BreakpointFacadeBuilder(); dbg.WithRunUntilBreak(); var count = 0; dbg.SetRunUntilBreakCallback(() => { if (count++ > 0) { tt.AdvanceToNextPosition(); } }); var dbgEngProxy = dbg.Build(); var timeTravelFacade = tt.Build(); var serverClient = sc.Build(); var bpFacade = bp.Build(); dbg.CurrentThreadId = MockFrames.SingleThreaded0.First().ThreadId; tt.WithFrames(MockFrames.SingleThreaded0); sc.WithUpsertFrames(() => { }); var indexMethod = new IndexMethod { DebugEngineProxy = dbgEngProxy, TimeTravelFacade = timeTravelFacade, ServerClient = serverClient, BreakpointFacade = bpFacade }; indexMethod.ProcessInternal(new Position(0, 0), MockFrames.SingleThreaded0.Max(x => x.Position), new IndexOptions()); sc.Mock.Verify(client => client.UpsertFrames( It.Is <IEnumerable <Frame> >(frames => frames.SequenceEqual(MockFrames.SingleThreaded0)))); }
public void Identify_32_And_64_Bit_Arch() { // Arrange var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult("!peb", @"PEB at 00000000003b9000 InheritedAddressSpace: No ReadImageFileExecOptions: No BeingDebugged: No ... ImageBaseAddress: 0000000140000000 _NT_SYMBOL_PATH=SRV*c:\symbols*http://msdl.microsoft.com/download/symbols"); var proxy = builder.Build(); // Act var indexMethod = new IndexMethod(); indexMethod.DebugEngineProxy = builder.Build(); var is32 = indexMethod.Is32Bit(); // Assert is32.Should().BeFalse("00000000003b9000 is 16 characters and thus 64bit"); }
public void Add_Tags_Correctly() { var tagMethod = new TagMethod(); var dbg = new DebugEngineProxyBuilder(); tagMethod.TimeTravelFacade = new TimeTravelFacadeBuilder(dbg) .WithPositions(new PositionsResult(new[] { new PositionsRecord(1, new Position(0, 0), true), new PositionsRecord(2, new Position(0, 0), false) })).Build(); var serverClientBuilder = new ServerClientBuilder(); tagMethod.ServerClient = serverClientBuilder .WithAddTag(new Position(0, 0), new[] { 1 }, "This is a note") .WithAddTag(new Position(0, 0), new[] { 1, 2 }, "This is a note") .Build(); tagMethod.Settings = new Settings { ProjectName = "test" }; var options = new AddTagOptions { Text = "This is a note", IsAllThreadsAtPosition = false }; var options2 = new AddTagOptions { Text = "This is a note", IsAllThreadsAtPosition = true }; tagMethod.AddTag(options); tagMethod.AddTag(options2); serverClientBuilder.Mock.Verify(client => client.AddTag(new Position(0, 0), new[] { 1 }, "This is a note"), Times.Once); serverClientBuilder.Mock.Verify( client => client.AddTag(new Position(0, 0), new[] { 1, 2 }, "This is a note"), Times.Once); }
public void Get_The_Starting_Position() { // arrange var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult("!tt 0", @"Setting position to the beginning of the trace Setting position: 35:0 (9b04.7590): Break instruction exception - code 80000003 (first/second chance not available) Time Travel Position: 35:0 ntdll!NtSetInformationWorkerFactory+0x14: 00007ffa`52363104 c3 ret"); var facade = new TimeTravelFacade { DebugEngineProxy = builder.Build() }; // act var position = facade.GetStartingPosition(); // assert position.Should().Be(new Position(0x35, 0)); }
public void Set_The_Position_Correctly() { // arrange var facade = new TimeTravelFacade(); var position = new Position(0, 0); var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult(@"Setting position to the beginning of the trace Setting position: E:0 Breakpoint 0 hit Time Travel Position: E:0 ntdll!NtSetInformationWorkerFactory+0x14: 00007ffc`f0ee3554 c3 ret"); facade.DebugEngineProxy = builder.Build(); // act var posResult = facade.SetPosition(position); // assert builder.Mock.Verify(proxy => proxy.Execute("!tt 0:0"), Times.Once); posResult.ActualPosition.Should().Be(new Position(0xe, 0)); posResult.BreakpointHit.Should().Be(0); }
public void Get_The_Current_StackTrace_Correctly() { // arrange var builder = new DebugEngineProxyBuilder(); builder.WithExecuteResult("k", @"Child-SP RetAddr Call Site 00000000`0014d180 00007ffa`513150ed KERNEL32!GetTimeFormatWWorker+0xc43 00000000`0014d1d0 00007ffa`513138e6 KERNEL32!GetTimeFormatWWorker+0x7ed 00000000`0014ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x21"); builder.WithExecuteResult("~~[7590] k", @"Child-SP RetAddr Call Site 00000000`0014d180 00007ffa`513150ed KERNEL32!GetTimeFormatWWorker+0xc43 00000000`0014d1d0 00007ffa`513138e6 KERNEL32!GetTimeFormatWWorker+0x7ed 00000000`0014ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x21"); builder.WithThreadId(0x7590); var stackFacade = new StackFacade { DebugEngineProxy = builder.Build() }; // act var stackTrace = stackFacade.GetCurrentStackTrace(); var stackTrace2 = stackFacade.GetCurrentStackTrace(0x7590); // assert stackTrace.Should().Be(new StackTrace(new[] { new StackFrame(0x000000000014d180, 0x00007ffa513150ed, "KERNEL32", "GetTimeFormatWWorker", 0xc43), new StackFrame(0x000000000014d1d0, 0x00007ffa513138e6, "KERNEL32", "GetTimeFormatWWorker", 0x7ed), new StackFrame(0x000000000014ff90, 0x0000000000000000, "ntdll", "RtlUserThreadStart", 0x21) })); stackTrace2.Should().Be(new StackTrace(new[] { new StackFrame(0x000000000014d180, 0x00007ffa513150ed, "KERNEL32", "GetTimeFormatWWorker", 0xc43), new StackFrame(0x000000000014d1d0, 0x00007ffa513138e6, "KERNEL32", "GetTimeFormatWWorker", 0x7ed), new StackFrame(0x000000000014ff90, 0x0000000000000000, "ntdll", "RtlUserThreadStart", 0x21) })); }
public void Identify_Correct_Starting_Position() { // Arrange var options = new IndexOptions { Start = new Position(0x35, 0x1) }; var dbg = new DebugEngineProxyBuilder(); var indexMethod = new IndexMethod(); indexMethod.DebugEngineProxy = dbg.Build(); var builder = new TimeTravelFacadeBuilder(dbg); builder.WithGetStartingPosition(new Position(0x35, 0)); indexMethod.TimeTravelFacade = builder.Build(); // Act var startingPosition = indexMethod.GetStartingPosition(options); // Assert startingPosition.Should().Be(new Position(0x35, 1), "35:1 means that the high portion is 35 and the low portion is 1"); }
public void Print_Command_Help_If_A_Single_Command_Is_Specified() { var helpMethod = new HelpMethod(); var dbg = new DebugEngineProxyBuilder(); string output = null; dbg.WithWriteLine(s => output = s); helpMethod.DebugEngineProxy = dbg.Build(); helpMethod.Methods = new IMcFlyMethod[] { new TestMethod() }; var expected = @"test Testing method Switches: -weird Weird switch --double Double switch Subcommands: test sub1 First subcommand test sub2 Second subcommand Examples: Example 1 test -weird something --double 2 Test weird something with 2 Example 2 test Run default test "; helpMethod.Process("test".Split(' ')); output.Should().Be(expected); }