├── .gitattributes
├── .gitignore
├── Images
├── logo.png
└── screen.gif
├── LICENSE
├── README.md
├── Source
└── Swiddler
│ ├── App.manifest
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppIcon.ico
│ ├── AppResources.cs
│ ├── Behaviors
│ ├── Button.cs
│ ├── FrameworkElement.cs
│ ├── TextBox.cs
│ └── Window.cs
│ ├── Channels
│ ├── Channel.cs
│ ├── MonitorChannel.cs
│ ├── RemoteChildChannel.cs
│ ├── RewriteChannel.cs
│ ├── SessionChannel.cs
│ ├── SnifferChannel.cs
│ ├── SslChannel.cs
│ ├── SslListenerChannel.cs
│ ├── TcpChannel.cs
│ ├── TcpListenerChannel.cs
│ └── UdpChannel.cs
│ ├── ChunkViews
│ ├── ChunkViewItem.cs
│ ├── Message.cs
│ ├── RawData.cs
│ └── Selection.cs
│ ├── Commands
│ ├── CertificateCommands.cs
│ └── MiscCommands.cs
│ ├── Common
│ ├── BindableBase.cs
│ ├── ConnectionBanner.cs
│ ├── DeferredDataObject.cs
│ ├── DelayedInvoker.cs
│ ├── Injector.cs
│ ├── Monitor.cs
│ ├── ObservableRangeCollection.cs
│ ├── ReloadableCollection.cs
│ ├── Session.cs
│ ├── TrafficFlow.cs
│ └── ValueException.cs
│ ├── Controls
│ ├── ChunkView.cs
│ ├── ChunkView.xaml
│ ├── ComboBoxEx.cs
│ ├── CrispImage.cs
│ ├── CrispImage.xaml
│ ├── LockableToggleButton.cs
│ ├── SearchTextBox.cs
│ ├── SearchTextBox.xaml
│ ├── SessionListView.cs
│ ├── SessionListView.xaml
│ ├── TileButton.cs
│ ├── TileButton.xaml
│ ├── TreeToggleButton.cs
│ └── TreeToggleButton.xaml
│ ├── Converters
│ ├── AssignableTypeConverter.cs
│ ├── CertificateNameConverter.cs
│ ├── CertificateThumbprintConverter.cs
│ ├── CertificateValidityConverter.cs
│ ├── CrispImageConverter.cs
│ ├── EmptyStringConverter.cs
│ ├── FormatConverter.cs
│ ├── IntEnumConverter.cs
│ ├── InvertBoolConverter.cs
│ ├── LazyBindingConverter.cs
│ ├── ScrollBarVisibility.cs
│ ├── SslVersionStringConverter.cs
│ └── TreeIndentConverter.cs
│ ├── DataChunks
│ ├── MessageData.cs
│ └── Packet.cs
│ ├── IO
│ ├── BlockReader.cs
│ ├── BlockWriter.cs
│ ├── CachedBlockIterator.cs
│ ├── ChunkDictionary.cs
│ ├── ChunkWriter.cs
│ ├── Constants.cs
│ ├── DataTransfer.cs
│ ├── IDataChunk.cs
│ ├── StorageHandle.cs
│ ├── SyncedFileStream.cs
│ └── Test.cs
│ ├── Images
│ ├── Adapter.xaml
│ ├── Binary.xaml
│ ├── Certificate.xaml
│ ├── Close.xaml
│ ├── Connect.xaml
│ ├── Connect_16x.png
│ ├── Connect_20x.png
│ ├── Connect_32x.png
│ ├── Connecting.xaml
│ ├── Delete.xaml
│ ├── Disconnect.xaml
│ ├── Disconnected.xaml
│ ├── Disconnected_32x.png
│ ├── Edit_16x.png
│ ├── Edit_20x.png
│ ├── Error.xaml
│ ├── ExportShark.xaml
│ ├── Eye.xaml
│ ├── Forward.xaml
│ ├── Gear.xaml
│ ├── GearBlack.xaml
│ ├── Gear_32x.png
│ ├── Go.xaml
│ ├── Help_16x.png
│ ├── Help_24x.png
│ ├── HintIcon.xaml
│ ├── Info.xaml
│ ├── Invalid.xaml
│ ├── LockInvalid.xaml
│ ├── LockValid.xaml
│ ├── OpenFolder.xaml
│ ├── OpenFolder_16x.png
│ ├── Port.xaml
│ ├── Port_20x.png
│ ├── Port_32x.png
│ ├── Process.xaml
│ ├── Process_20x.png
│ ├── Process_32x.png
│ ├── Run.xaml
│ ├── Save.xaml
│ ├── Search.xaml
│ ├── Search_20x.png
│ ├── Star.xaml
│ ├── Stop.xaml
│ ├── Trash.xaml
│ ├── Tunnel.xaml
│ ├── Tunnel_32x.png
│ ├── Valid.xaml
│ ├── Watermark.png
│ └── Watermark.xaml
│ ├── MarkupExtensions
│ ├── CertificateSource.cs
│ ├── DpiExtensions.cs
│ ├── GroupedIPAddresses.cs
│ ├── ShadowGlassFrameThickness.cs
│ └── SslProtocolSupport.cs
│ ├── NetworkSniffer
│ ├── IPFragment.cs
│ ├── IPParser.cs
│ ├── PacketFilter.cs
│ ├── PacketReassembly.cs
│ ├── RawPacket.cs
│ ├── TCPParser.cs
│ ├── TCPState.cs
│ └── UDPParser.cs
│ ├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
│ ├── Rendering
│ ├── ConnectionFragment.cs
│ ├── DrawingFragment.cs
│ ├── FilledFragment.cs
│ ├── Fragment.cs
│ ├── FragmentLayer.cs
│ ├── FragmentView.cs
│ ├── FragmentViewContent.cs
│ ├── FragmentViewMetrics.cs
│ ├── MessageFragment.cs
│ ├── PolygonFigure.cs
│ ├── SelectionLayer.cs
│ ├── SslHandshakeFragment.cs
│ ├── TextFragment.cs
│ └── VisualPool.cs
│ ├── Resources
│ ├── Brushes.xaml
│ ├── CustomStyles.xaml
│ ├── Misc.xaml
│ ├── SocketToggles.xaml
│ ├── netprobe32.dll
│ ├── netprobe64.dll
│ └── port_numbers.csv
│ ├── Security
│ ├── CertProvider.cs
│ ├── SslAlert.cs
│ ├── SslCiphers.cs
│ ├── SslClientHello.cs
│ ├── SslExtension.cs
│ ├── SslHelloBase.cs
│ ├── SslServerHello.cs
│ ├── SslStreamExt.cs
│ ├── StreamExtensions.cs
│ └── X509.cs
│ ├── Serialization
│ ├── FileHeaderXml.cs
│ ├── IPBuilder.cs
│ ├── Pcap
│ │ ├── Disposable.cs
│ │ ├── LinkType.cs
│ │ ├── PcapPacket.cs
│ │ ├── PcapWriter.cs
│ │ ├── ReverseByteOrderExtension.cs
│ │ └── SectionHeader.cs
│ ├── Rtf
│ │ ├── RtfAbstract.cs
│ │ ├── RtfBasics.cs
│ │ ├── RtfBlockList.cs
│ │ ├── RtfCharFormat.cs
│ │ ├── RtfDocument.cs
│ │ ├── RtfParagraph.cs
│ │ └── RtfUtility.cs
│ ├── SessionXml.cs
│ ├── SslHandshake.cs
│ └── UserSettings.cs
│ ├── SocketSettings
│ ├── ClientSettingsBase.cs
│ ├── RewriteSettings.cs
│ ├── ServerSettingsBase.cs
│ ├── SettingsBase.cs
│ ├── SnifferSettings.cs
│ ├── TCPClientSettings.cs
│ ├── TCPServerSettings.cs
│ ├── UDPClientSettings.cs
│ └── UDPServerSettings.cs
│ ├── Swiddler.csproj
│ ├── Themes
│ └── Generic.xaml
│ ├── Utils
│ ├── AssemblyExtensions.cs
│ ├── ChannelExtensions.cs
│ ├── ControlExtensions.cs
│ ├── DateTimeExtensions.cs
│ ├── DependencyObjectExtensions.cs
│ ├── Firewall.cs
│ ├── ImagingExtensions.cs
│ ├── MiscExtensions.cs
│ ├── Net.cs
│ ├── Shell
│ │ ├── IImageList.cs
│ │ ├── IMAGEINFO.cs
│ │ ├── IMAGELISTDRAWPARAMS.cs
│ │ ├── POINT.cs
│ │ ├── RECT.cs
│ │ └── SHFILEINFO.cs
│ ├── ShellApi.cs
│ ├── TaskbarProgress.cs
│ ├── VisualExtensions.cs
│ └── WindowExtensions.cs
│ ├── ViewModels
│ ├── Certificate.cs
│ ├── ConnectionSettings.cs
│ ├── IPAdapterHeader.cs
│ ├── IPAddressItem.cs
│ ├── ImageButton.cs
│ ├── ProcessInfo.cs
│ ├── QuickActionItem.cs
│ ├── RecentlyUsedItem.cs
│ ├── SessionListItem.cs
│ └── SessionTree.cs
│ └── Views
│ ├── Fragments
│ ├── ConnectionView.xaml
│ ├── ConnectionView.xaml.cs
│ ├── MessageView.xaml
│ ├── MessageView.xaml.cs
│ ├── SslHandshakeView.xaml
│ └── SslHandshakeView.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── NewCertificate.xaml
│ ├── NewCertificate.xaml.cs
│ ├── NewConnection.xaml
│ ├── NewConnection.xaml.cs
│ ├── NewSessionExpress.xaml
│ ├── NewSessionExpress.xaml.cs
│ ├── SocketSettings
│ ├── Client.xaml
│ ├── Client.xaml.cs
│ ├── Listener.xaml
│ ├── Listener.xaml.cs
│ ├── Rewrite.xaml
│ ├── Rewrite.xaml.cs
│ ├── Sniffer.xaml
│ ├── Sniffer.xaml.cs
│ ├── UDPClient.xaml
│ ├── UDPClient.xaml.cs
│ ├── UDPServer.xaml
│ └── UDPServer.xaml.cs
│ ├── SslHandshakeDetails.xaml
│ └── SslHandshakeDetails.xaml.cs
└── Swiddler.sln
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlucansky/Swiddler/5ff34a126c481f8757c7e40acd8507ac55359895/Images/logo.png
--------------------------------------------------------------------------------
/Images/screen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlucansky/Swiddler/5ff34a126c481f8757c7e40acd8507ac55359895/Images/screen.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # TCP/UDP debugging tool
6 |
7 | 
8 |
9 | # Features
10 | ### Capture & Inspect
11 | - Capture virtually unlimited amount of data
12 | - Export captured raw data (drag selection to file)
13 |
14 | ### Create TCP/UDP server
15 | - Bind to any local IP
16 | - Supported IPv4/IPv6 dual stack
17 | - Allow reuse same address & port
18 |
19 | ### Connect to remote host
20 | - Specify source address
21 | - Broadcast or join multicast groups
22 |
23 | ### Rewrite traffic
24 | - Replace matched content
25 | - Match arbitrary data in binary mode
26 |
27 | ### SSL/TLS client & server
28 | - Supported SSL/3.0, TLS/1.0, TLS/1.1, TLS/1.2
29 | - Send custom Server Name Indication (SNI)
30 | - Create certificates and self-signed CA
31 | - Auto generate server certificates based on SNI
32 | - Export negotiated certificate chain
33 | - Observe SSL/TLS client & server hello messages
34 | - Request or send client certificate
35 |
36 |
37 | # Minimum requirements
38 | - .NET Framework 4.5
39 | - Windows 7 SP1 or higher
40 | - Windows Server 2008 SP2 or higher
41 |
42 | # License
43 | This project is made available under the Apache License 2.0
44 |
45 | See [LICENSE](LICENSE) for details.
46 |
--------------------------------------------------------------------------------
/Source/Swiddler/App.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Source/Swiddler/AppIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlucansky/Swiddler/5ff34a126c481f8757c7e40acd8507ac55359895/Source/Swiddler/AppIcon.ico
--------------------------------------------------------------------------------
/Source/Swiddler/Behaviors/Button.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 | using System.Windows.Controls.Primitives;
4 |
5 | namespace Swiddler.Behaviors
6 | {
7 | public static class Button
8 | {
9 | private static readonly DependencyProperty ClickOpensContextMenuProperty =
10 | DependencyProperty.RegisterAttached("ClickOpensContextMenu", typeof(bool), typeof(Button),
11 | new PropertyMetadata(false, new PropertyChangedCallback(HandlePropertyChanged)));
12 |
13 | public static bool GetClickOpensContextMenu(DependencyObject obj) => (bool)obj.GetValue(ClickOpensContextMenuProperty);
14 |
15 | public static void SetClickOpensContextMenu(DependencyObject obj, bool value) => obj.SetValue(ClickOpensContextMenuProperty, value);
16 |
17 | private static void HandlePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
18 | {
19 | if (obj is ButtonBase btn)
20 | {
21 | btn.Click -= ExecuteClick;
22 | btn.Click += ExecuteClick;
23 | }
24 | }
25 |
26 | private static void ExecuteClick(object sender, RoutedEventArgs args)
27 | {
28 | if (sender is ButtonBase btn && GetClickOpensContextMenu(btn))
29 | {
30 | if (btn.ContextMenu != null)
31 | {
32 | btn.ContextMenu.PlacementTarget = btn;
33 | btn.ContextMenu.Placement = ContextMenuService.GetPlacement(btn);
34 | btn.ContextMenu.IsOpen = true;
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Swiddler/Behaviors/FrameworkElement.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace Swiddler.Behaviors
4 | {
5 | public static class FrameworkElement
6 | {
7 | public static bool GetSetDpi(System.Windows.FrameworkElement element) => (bool)element.GetValue(SetDpiProperty);
8 | public static void SetSetDpi(System.Windows.FrameworkElement element, bool value) => element.SetValue(SetDpiProperty, value);
9 |
10 | public static readonly DependencyProperty SetDpiProperty =
11 | DependencyProperty.RegisterAttached("SetDpi",
12 | typeof(bool), typeof(FrameworkElement),
13 | new UIPropertyMetadata(false, OnSetDpiChanged));
14 |
15 | private static void OnSetDpiChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
16 | {
17 | if (d is System.Windows.FrameworkElement elm && e.NewValue is bool == true)
18 | App.Current?.Res.AttachDpiProperties(elm);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Source/Swiddler/Behaviors/Window.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Utils;
2 | using System.Windows;
3 |
4 | namespace Swiddler.Behaviors
5 | {
6 | public static class Window
7 | {
8 | public static bool GetDisableControls(System.Windows.Window wnd) => (bool)wnd.GetValue(DisableControlsProperty);
9 | public static void SetDisableControls(System.Windows.Window wnd, bool value) => wnd.SetValue(DisableControlsProperty, value);
10 |
11 | public static readonly DependencyProperty DisableControlsProperty =
12 | DependencyProperty.RegisterAttached("DisableControls",
13 | typeof(bool), typeof(Window),
14 | new UIPropertyMetadata(false, OnDisableControlsChanged));
15 |
16 | private static void OnDisableControlsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
17 | {
18 | if (d is System.Windows.Window wnd && e.NewValue is bool == true)
19 | wnd.SourceInitialized += (_, __) => wnd.DisableWindowControls();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Source/Swiddler/Channels/RemoteChildChannel.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Common;
2 | using Swiddler.DataChunks;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Net;
6 |
7 | namespace Swiddler.Channels
8 | {
9 | ///
10 | /// For every remote EndPoint creates a new child Session
11 | ///
12 | public class RemoteChildChannel : Channel
13 | {
14 | readonly Dictionary ChildrenSessions = new Dictionary();
15 |
16 | private class Mediator : Channel, IDisposable
17 | {
18 | readonly Action ownerNotify;
19 | readonly IPEndPoint ep;
20 | Action disposed;
21 | public Mediator(Session session, Action ownerNotify, IPEndPoint ep, Action disposed) : base(session)
22 | {
23 | this.ownerNotify = ownerNotify;
24 | this.disposed = disposed;
25 | this.ep = ep;
26 | }
27 |
28 | protected override void OnReceiveNotification(Packet packet) // send to UdpChannel from session editor
29 | {
30 | packet.Destination = ep;
31 | ownerNotify(packet);
32 | }
33 |
34 | public void Send(Packet packet)
35 | {
36 | if (DefaultFlow != TrafficFlow.Undefined)
37 | packet.Flow = DefaultFlow;
38 | NotifyObservers(packet);
39 | }
40 |
41 | public void Dispose()
42 | {
43 | Observers.Clear();
44 | var disposedCopy = disposed;
45 | disposed = null;
46 | disposedCopy?.Invoke(ep);
47 | }
48 | }
49 |
50 | public RemoteChildChannel(Session session) : base(session) { }
51 | protected override void OnReceiveNotification(Packet packet) => GetChild(packet.Source).Send(packet);
52 |
53 | private Mediator GetChild(IPEndPoint ep)
54 | {
55 | lock (ChildrenSessions)
56 | {
57 | if (ChildrenSessions.TryGetValue(ep, out var item) == false)
58 | {
59 | var child = Session.NewChildSession("Received from " + ep,
60 | s => item = new Mediator(s, NotifyObservers, ep, RemoveChild));
61 |
62 | child.Name = $"{ep}";
63 | child.Start();
64 | ChildrenSessions.Add(ep, item);
65 | }
66 | return item;
67 | }
68 | }
69 |
70 | private void RemoveChild(IPEndPoint ep)
71 | {
72 | lock (ChildrenSessions)
73 | ChildrenSessions.Remove(ep);
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Source/Swiddler/Channels/SessionChannel.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Common;
2 | using Swiddler.DataChunks;
3 |
4 | namespace Swiddler.Channels
5 | {
6 | public class SessionChannel : Channel
7 | {
8 | public bool IsActive => Observers.Count > 0;
9 |
10 | public SessionChannel(Session session) : base(session)
11 | {
12 | DefaultFlow = TrafficFlow.Outbound;
13 | }
14 |
15 | ///
16 | /// Append packet to session log
17 | ///
18 | protected override void OnReceiveNotification(Packet packet)
19 | {
20 | Session.WriteChunk(packet);
21 | }
22 |
23 | ///
24 | /// User can send packet interactively
25 | ///
26 | public void Submit(byte[] data)
27 | {
28 | if (IsActive)
29 | {
30 | var packet = new Packet() { Payload = data };
31 | NotifyObservers(packet);
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Source/Swiddler/Channels/SslListenerChannel.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Common;
2 | using System.Net.Sockets;
3 | using System.Security.Authentication;
4 | using System.Security.Cryptography.X509Certificates;
5 |
6 | namespace Swiddler.Channels
7 | {
8 | public class SslListenerChannel : TcpListenerChannel
9 | {
10 | public SslProtocols SslProtocols { get; set; }
11 | public bool RequireClientCertificate { get; set; }
12 | public bool IgnoreInvalidClientCertificate { get; set; }
13 | public X509Certificate2 ServerCertificate { get; set; }
14 | public X509Certificate2 CertificateAuthority { get; set; }
15 | public bool AutoGenerateServerCertificate { get; set; }
16 | public string GeneratedServerCertificatePrefix { get; set; }
17 |
18 |
19 | public SslListenerChannel(Session session, TcpListener listener) : base(session, listener) { }
20 |
21 | protected override Channel CreateChildChannel(Session childSession, TcpClient acceptedClient)
22 | {
23 | var sslChannel = (SslChannel)childSession.CreateTcpChannel(acceptedClient, ssl: true);
24 |
25 | sslChannel.AuthenticateAsServer = true;
26 | sslChannel.SslProtocols = SslProtocols;
27 | sslChannel.RequireClientCertificate = RequireClientCertificate;
28 | sslChannel.IgnoreInvalidClientCertificate = IgnoreInvalidClientCertificate;
29 | sslChannel.ServerCertificate = ServerCertificate;
30 | sslChannel.CertificateAuthority = CertificateAuthority;
31 | sslChannel.AutoGenerateServerCertificate = AutoGenerateServerCertificate;
32 | sslChannel.GeneratedServerCertificatePrefix = GeneratedServerCertificatePrefix;
33 |
34 | return sslChannel;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Source/Swiddler/Channels/TcpListenerChannel.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Common;
2 | using Swiddler.DataChunks;
3 | using System;
4 | using System.Net;
5 | using System.Net.Sockets;
6 |
7 | namespace Swiddler.Channels
8 | {
9 | public class TcpListenerChannel : Channel, IDisposable
10 | {
11 | public TcpListener Listener { get; }
12 |
13 | public TcpListenerChannel(Session session, TcpListener listener) : base(session)
14 | {
15 | Listener = listener;
16 | }
17 |
18 | protected override void OnReceiveNotification(Packet packet)
19 | {
20 | throw new NotImplementedException(); // channel is not intended to send packets into
21 | }
22 |
23 | protected override void StartOverride()
24 | {
25 | BeginAcceptTcpClient();
26 | }
27 |
28 | void BeginAcceptTcpClient()
29 | {
30 | Listener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
31 | }
32 |
33 | private void AcceptTcpClientCallback(IAsyncResult result)
34 | {
35 | TcpClient client = null;
36 | try
37 | {
38 | client = Listener.EndAcceptTcpClient(result);
39 | var remoteEP = (IPEndPoint)client.Client.RemoteEndPoint;
40 | var child = Session.NewChildSession("Accepted connection from " + remoteEP, newSession => CreateChildChannel(newSession, client));
41 | var tcpChannel = (TcpChannel)child.ServerChannel;
42 | tcpChannel.IsServerChannel = true;
43 | child.Name = $"{remoteEP}";
44 | child.ResolveProcessIdAsync(remoteEP);
45 | child.StartAsync();
46 | }
47 | catch (Exception ex)
48 | {
49 | HandleError(ex);
50 | }
51 | finally
52 | {
53 | if (client != null) BeginAcceptTcpClient(); // accept another one
54 | }
55 | }
56 |
57 | protected virtual Channel CreateChildChannel(Session childSession, TcpClient acceptedClient)
58 | {
59 | return childSession.CreateTcpChannel(acceptedClient);
60 | }
61 |
62 | public void Dispose()
63 | {
64 | Listener.Stop();
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Source/Swiddler/Channels/UdpChannel.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.Common;
2 | using Swiddler.DataChunks;
3 | using System;
4 | using System.Net;
5 | using System.Net.Sockets;
6 |
7 | namespace Swiddler.Channels
8 | {
9 | public class UdpChannel : Channel, IDisposable
10 | {
11 | public UdpClient Client { get; }
12 | public IPEndPoint RemoteEndpoint { get; set; }
13 | public IPEndPoint LocalEndPoint { get; set; }
14 |
15 | bool connected;
16 |
17 | public UdpChannel(Session session, UdpClient client) : base(session)
18 | {
19 | Client = client;
20 | DefaultFlow = TrafficFlow.Inbound;
21 | }
22 |
23 | protected override void StartOverride()
24 | {
25 | connected = Client.Client.Connected;
26 | if (connected) RemoteEndpoint = (IPEndPoint)Client.Client.RemoteEndPoint;
27 | LocalEndPoint = (IPEndPoint)Client.Client.LocalEndPoint;
28 | BeginRead();
29 | }
30 |
31 | void BeginRead()
32 | {
33 | try
34 | {
35 | Client.BeginReceive(ReceiveCallback, null);
36 | }
37 | catch (Exception ex)
38 | {
39 | HandleError(ex);
40 | }
41 | }
42 |
43 | private void ReceiveCallback(IAsyncResult result)
44 | {
45 | try
46 | {
47 | IPEndPoint remote = null;
48 | byte[] data = Client.EndReceive(result, ref remote);
49 |
50 | var packet = new Packet()
51 | {
52 | Payload = data,
53 | Source = remote,
54 | Destination = LocalEndPoint,
55 | };
56 |
57 | NotifyObservers(packet);
58 |
59 | BeginRead();
60 | }
61 | catch (Exception ex)
62 | {
63 | HandleError(ex);
64 | }
65 | }
66 |
67 | protected override void OnReceiveNotification(Packet packet)
68 | {
69 | try
70 | {
71 | if (packet.Source == null) packet.Source = LocalEndPoint;
72 | if (packet.Destination == null) packet.Destination = RemoteEndpoint;
73 |
74 | if (connected)
75 | {
76 | packet.Destination = RemoteEndpoint;
77 | Client.Send(packet.Payload, packet.Payload.Length);
78 | }
79 | else
80 | {
81 | Client.Send(packet.Payload, packet.Payload.Length, packet.Destination);
82 | }
83 | }
84 | catch (Exception ex)
85 | {
86 | HandleError(ex);
87 | }
88 | }
89 |
90 | public void Dispose()
91 | {
92 | Client.Close();
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Source/Swiddler/ChunkViews/ChunkViewItem.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.IO;
2 | using Swiddler.Rendering;
3 | using System;
4 | using System.Windows;
5 |
6 | namespace Swiddler.ChunkViews
7 | {
8 | public abstract class ChunkViewItem
9 | {
10 | public int FirstFragmentIndex { get; set; } = -1;
11 | public int LastFragmentIndex { get; set; } = -1;
12 |
13 | public Point Location { get; set; }
14 |
15 | public long BlockIndex { get; set; }
16 |
17 | public FragmentViewContent ViewContent { get; set; }
18 |
19 | public abstract IDataChunk BaseChunk { get; }
20 |
21 | ///
22 | /// Append fragments to
23 | ///
24 | public abstract void Build();
25 |
26 | ///
27 | /// Method should resolve missing properties or and update .
28 | ///
29 | public virtual void PrepareSelectionAnchor(SelectionAnchorCaret caret) => throw new NotImplementedException();
30 | }
31 |
32 | public abstract class ChunkViewItem : ChunkViewItem
33 | where TDataChunk : IDataChunk
34 | {
35 | public sealed override IDataChunk BaseChunk => Chunk;
36 |
37 | public TDataChunk Chunk { get; set; }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Swiddler/ChunkViews/Selection.cs:
--------------------------------------------------------------------------------
1 | using Swiddler.DataChunks;
2 | using Swiddler.IO;
3 | using Swiddler.Rendering;
4 | using System;
5 | using System.Windows;
6 |
7 | namespace Swiddler.ChunkViews
8 | {
9 | public class SelectionAnchorCaret
10 | {
11 | public Rect Bounds { get; set; }
12 | public Fragment Fragment { get; set; }
13 | public SelectionAnchor Anchor { get; set; }
14 |
15 | public bool IsResolved => Fragment != null && Anchor != null;
16 |
17 | public override bool Equals(object obj)
18 | {
19 | var other = obj as SelectionAnchorCaret;
20 | var fragEquals = (Fragment == null && other?.Fragment == null ) || (Fragment?.Equals(other?.Fragment) ?? false);
21 |
22 | return
23 | Bounds.Equals(other?.Bounds) &&
24 | Anchor.Equals(other?.Anchor) &&
25 | fragEquals;
26 | }
27 |
28 | public override int GetHashCode()
29 | {
30 | return Bounds.GetHashCode() ^ Anchor.GetHashCode() ^ (Fragment?.GetHashCode() ?? 0);
31 | }
32 | }
33 |
34 | public class SelectionAnchor : IComparable
35 | {
36 | public IDataChunk Chunk { get; set; }
37 | ///
38 | /// Exact offset within chunk
39 | ///
40 | public int Offset { get; set; }
41 |
42 | public int CompareTo(SelectionAnchor other)
43 | {
44 | var seqCmp = Chunk.SequenceNumber.CompareTo(other.Chunk.SequenceNumber);
45 | return seqCmp == 0 ? Offset.CompareTo(other.Offset) : seqCmp;
46 | }
47 |
48 | public override bool Equals(object obj)
49 | {
50 | var other = obj as SelectionAnchor;
51 | return
52 | Chunk.SequenceNumber.Equals(other?.Chunk.SequenceNumber) &&
53 | Offset.Equals(other?.Offset);
54 | }
55 |
56 | public override int GetHashCode()
57 | {
58 | return Chunk.SequenceNumber.GetHashCode() ^ Offset.GetHashCode();
59 | }
60 |
61 | public override string ToString()
62 | {
63 | return $"Seq = {Chunk.SequenceNumber}; Offset = {Offset}";
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/Source/Swiddler/Commands/MiscCommands.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Input;
2 |
3 | namespace Swiddler.Commands
4 | {
5 | public static class MiscCommands
6 | {
7 | public static RoutedCommand QuickConnect { get; } = new RoutedCommand(nameof(QuickConnect), typeof(MiscCommands));
8 | public static RoutedCommand Send { get; } = new RoutedCommand(nameof(Send), typeof(MiscCommands));
9 | public static RoutedCommand Disconnect { get; } = new RoutedCommand(nameof(Disconnect), typeof(MiscCommands));
10 | public static RoutedCommand Search { get; } = new RoutedCommand(nameof(Search), typeof(MiscCommands));
11 | public static RoutedCommand SelectAll { get; } = new RoutedCommand(nameof(SelectAll), typeof(MiscCommands));
12 | public static RoutedCommand GoToStart { get; } = new RoutedCommand(nameof(GoToStart), typeof(MiscCommands));
13 | public static RoutedCommand GoToEnd { get; } = new RoutedCommand(nameof(GoToEnd), typeof(MiscCommands));
14 | public static RoutedCommand ToggleHex { get; } = new RoutedCommand(nameof(ToggleHex), typeof(MiscCommands));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Source/Swiddler/Common/BindableBase.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Runtime.CompilerServices;
3 |
4 | namespace Swiddler.Common
5 | {
6 | ///
7 | /// Implementation of to simplify models.
8 | ///
9 | public abstract class BindableBase : INotifyPropertyChanged
10 | {
11 | // source: https://www.danrigby.com/2015/09/12/inotifypropertychanged-the-net-4-6-way/
12 |
13 | ///
14 | /// Multicast event for property change notifications.
15 | ///
16 | public event PropertyChangedEventHandler PropertyChanged;
17 |
18 | ///
19 | /// Checks if a property already matches a desired value. Sets the property and
20 | /// notifies listeners only when necessary.
21 | ///
22 | /// Type of the property.
23 | /// Reference to a property with both getter and setter.
24 | /// Desired value for the property.
25 | ///
26 | /// Name of the property used to notify listeners. This
27 | /// value is optional and can be provided automatically when invoked from compilers that
28 | /// support CallerMemberName.
29 | ///
30 | ///
31 | /// True if the value was changed, false if the existing value matched the
32 | /// desired value.
33 | ///
34 | protected bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null)
35 | {
36 | if (Equals(storage, value))
37 | {
38 | return false;
39 | }
40 |
41 | storage = value;
42 | OnPropertyChanged(propertyName);
43 | return true;
44 | }
45 |
46 | ///
47 | /// Notifies listeners that a property value has changed.
48 | ///
49 | ///
50 | /// Name of the property used to notify listeners. This
51 | /// value is optional and can be provided automatically when invoked from compilers
52 | /// that support .
53 | ///
54 | protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
55 | {
56 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Source/Swiddler/Common/DeferredDataObject.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 |
4 | namespace Swiddler.Common
5 | {
6 | public class DeferredDataObject : IDataObject
7 | {
8 | readonly DataObject _innerDataObject = new DataObject();
9 |
10 | public object GetData(string format, bool autoConvert)
11 | {
12 | var data = _innerDataObject.GetData(format, autoConvert);
13 |
14 | if (data is Func