Socketing Project

claymore1977

New member
Joined
Sep 19, 2005
Messages
3
Location
Maryland
Programming Experience
1-3
Okay all, still a newbie poster here, and making the transition from VB6/VBA to VB.net.

I have a simple (or at least I think it simple) project that I am trying to work on. I am trying to create an application that is close to a packet sniffer. I have a client & server software package that I would like to be able to record the data stream between the two. I have done tons of research and came up with the following angles of attack:
  • create a ws2_32 proxy .dll that dumps all send() and recv() buffers to a text file every time they are called..... but i couldn't get that to work.
  • use SoftIce or OllyDbg to hook into the send() and recv() calls... but I couldn't make that work for me either.
So now I am going to attempt to write a small proxy app that I can reroute the client to and have the proxy app pass all data obtained from the client to the server and all data from the server to the client... meanwhile logging the databuffers.

Using vb.net I have a class created that contains connect(), listen(), beginreceive(), and send() functions. The class also raises events when Data has arrived on a port, a socket connects, disconnects, or throws an error. I am using a form to initialize two of these classes (ClientSide & ServerSide) and am handling the events from the two classes to swap the data, aka:

ClientSide.onDataArrival(byVal Data() as Byte()) calls the ServerSide.Send(byVal Data() as Byte()) function

ServerSide.onDataArrival(byVal Data() as Byte()) calls the ClientSide.Send(byVal Data() as Byte()) function


My flowpath was planned to be:
  1. ClientSide Socket listens for connection
  2. Once connection is recieved, the event ClientSide_OnGetConnect is raised and that causes the Serverside socket to connect to the server.
  3. CllientSide socket continues on and calls .BeginRecieve
  4. Once ServerSide Socket connects, it calls its own .BeginRecieve
  5. Everytime the ClientSide Socket recieves data, it raises the ClientSide_onDataArrival() event, which the Form responds to by calling ServerSide.Send()
  6. Everytime the ServerSide Socket recieves data, it raises the ServerSide_onDataArrival() event, which the Form responds to by calling ClientSide.Send()
What I have 'sort of' works as the sockets will connect, however the either the client or the server 'hangup' before my code can forward the any data to them.

I have read soooo many tutorials already that I am now confused. I understand there are many ways to skin this cat, but every tutorial seems to answer 33% of the question, and piecing together a solution from fragments of different approaches has me mentally 'wrapped around the axle'

I can post the code if need be, but I am really looking for advice/tutorials/URLs on any methodolgy I might change/use. I won't be opposed to someone taking my code and 'fixing' it, but that seems kinda the wrong way to tackle this.
Am I even on the right track/right approach? Should I consider using threads to handle each of the sockets?
 
Here's the code. (please don't laugh :) )

Form:
VB.NET:
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.text

Public Class Form1
    Inherits System.Windows.Forms.Form

    Private WithEvents SS_Sock As New MySocket()
    Private WithEvents CS_Sock As New MySocket()

    Friend WithEvents ServerPortLabel As System.Windows.Forms.Label
    Friend WithEvents ServerPortTextBox As System.Windows.Forms.TextBox
    Friend WithEvents ServerAddrLabel As System.Windows.Forms.Label
    Friend WithEvents StopServerButton As System.Windows.Forms.Button
    Friend WithEvents ServerAddyTextBox As System.Windows.Forms.TextBox

    Delegate Sub SetAddToList(ByVal [text] As String)

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents ClientPortTextBox As System.Windows.Forms.TextBox
    Friend WithEvents ClientPortLabel As System.Windows.Forms.Label
    Friend WithEvents StartServerButton As System.Windows.Forms.Button
    Friend WithEvents ActivityLogListBox As System.Windows.Forms.ListBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.ClientPortTextBox = New System.Windows.Forms.TextBox
        Me.ClientPortLabel = New System.Windows.Forms.Label
        Me.StartServerButton = New System.Windows.Forms.Button
        Me.ActivityLogListBox = New System.Windows.Forms.ListBox
        Me.ServerPortLabel = New System.Windows.Forms.Label
        Me.ServerPortTextBox = New System.Windows.Forms.TextBox
        Me.ServerAddrLabel = New System.Windows.Forms.Label
        Me.ServerAddyTextBox = New System.Windows.Forms.TextBox
        Me.StopServerButton = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'ClientPortTextBox
        '
        Me.ClientPortTextBox.Location = New System.Drawing.Point(829, 67)
        Me.ClientPortTextBox.Name = "ClientPortTextBox"
        Me.ClientPortTextBox.Size = New System.Drawing.Size(100, 20)
        Me.ClientPortTextBox.TabIndex = 0
        Me.ClientPortTextBox.Text = "6001"
        '
        'ClientPortLabel
        '
        Me.ClientPortLabel.Location = New System.Drawing.Point(757, 71)
        Me.ClientPortLabel.Name = "ClientPortLabel"
        Me.ClientPortLabel.Size = New System.Drawing.Size(66, 13)
        Me.ClientPortLabel.TabIndex = 1
        Me.ClientPortLabel.Text = "Client Port"
        '
        'StartServerButton
        '
        Me.StartServerButton.Location = New System.Drawing.Point(787, 93)
        Me.StartServerButton.Name = "StartServerButton"
        Me.StartServerButton.Size = New System.Drawing.Size(75, 23)
        Me.StartServerButton.TabIndex = 2
        Me.StartServerButton.Text = "Start Server"
        '
        'ActivityLogListBox
        '
        Me.ActivityLogListBox.HorizontalScrollbar = True
        Me.ActivityLogListBox.Location = New System.Drawing.Point(16, 17)
        Me.ActivityLogListBox.Name = "ActivityLogListBox"
        Me.ActivityLogListBox.ScrollAlwaysVisible = True
        Me.ActivityLogListBox.Size = New System.Drawing.Size(735, 212)
        Me.ActivityLogListBox.TabIndex = 3
        '
        'ServerPortLabel
        '
        Me.ServerPortLabel.Location = New System.Drawing.Point(757, 40)
        Me.ServerPortLabel.Name = "ServerPortLabel"
        Me.ServerPortLabel.Size = New System.Drawing.Size(66, 13)
        Me.ServerPortLabel.TabIndex = 5
        Me.ServerPortLabel.Text = "Server Port"
        '
        'ServerPortTextBox
        '
        Me.ServerPortTextBox.Location = New System.Drawing.Point(829, 36)
        Me.ServerPortTextBox.Name = "ServerPortTextBox"
        Me.ServerPortTextBox.Size = New System.Drawing.Size(100, 20)
        Me.ServerPortTextBox.TabIndex = 4
        Me.ServerPortTextBox.Text = "6000"
        '
        'ServerAddrLabel
        '
        Me.ServerAddrLabel.Location = New System.Drawing.Point(757, 17)
        Me.ServerAddrLabel.Name = "ServerAddrLabel"
        Me.ServerAddrLabel.Size = New System.Drawing.Size(68, 13)
        Me.ServerAddrLabel.TabIndex = 7
        Me.ServerAddrLabel.Text = "Server Addr"
        '
        'ServerAddyTextBox
        '
        Me.ServerAddyTextBox.Location = New System.Drawing.Point(829, 13)
        Me.ServerAddyTextBox.Name = "ServerAddyTextBox"
        Me.ServerAddyTextBox.Size = New System.Drawing.Size(155, 20)
        Me.ServerAddyTextBox.TabIndex = 6
        Me.ServerAddyTextBox.Text = "216.98.58.104"
        '
        'StopServerButton
        '
        Me.StopServerButton.Location = New System.Drawing.Point(880, 93)
        Me.StopServerButton.Name = "StopServerButton"
        Me.StopServerButton.Size = New System.Drawing.Size(75, 23)
        Me.StopServerButton.TabIndex = 8
        Me.StopServerButton.Text = "Stop Server"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(1000, 246)
        Me.Controls.Add(Me.StopServerButton)
        Me.Controls.Add(Me.ServerAddrLabel)
        Me.Controls.Add(Me.ServerAddyTextBox)
        Me.Controls.Add(Me.ServerPortLabel)
        Me.Controls.Add(Me.ServerPortTextBox)
        Me.Controls.Add(Me.ActivityLogListBox)
        Me.Controls.Add(Me.StartServerButton)
        Me.Controls.Add(Me.ClientPortLabel)
        Me.Controls.Add(Me.ClientPortTextBox)
        Me.Name = "Form1"
        Me.Text = "SBScout v0.01"
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

#End Region

 
    Private Sub StartServerButton_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles StartServerButton.Click
        StartServer()
    End Sub

    Private Sub StartServer()
        Dim strPortListenTo As String = Me.ClientPortTextBox.Text
        Dim intPortListenTo As Int32

        'SS_Sock = New MySocket
        'CS_Sock = New MySocket

        AddToList("Starting Proxy Server....")
        Me.StartServerButton.Enabled = False
        Me.StopServerButton.Enabled = True
        Me.Refresh()

        intPortListenTo = Val(strPortListenTo)
        AddToList("Listening on port " & intPortListenTo & "...")


        CS_Sock.Listen("127.0.0.1", intPortListenTo)
        If SS_Sock.Connected = False Then
            SS_Sock.Connect(Me.ServerAddyTextBox.Text, CType(Me.ServerPortTextBox.Text, Int32))
        End If

    End Sub


    Private Sub StopServerButton_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles StopServerButton.Click
        StopServer()
    End Sub

    Private Sub StopServer()
        AddToList("Stopping server...")

        If SS_Sock.Connected = True Then SS_Sock.Disconnect()
        If CS_Sock.Connected = True Then CS_Sock.Disconnect()

        If Not SS_Sock Is Nothing Then SS_Sock = Nothing
        If Not CS_Sock Is Nothing Then CS_Sock = Nothing

        StartServerButton.Enabled = True
        StopServerButton.Enabled = False
        Me.Refresh()

        AddToList("Server has stopped.")
    End Sub

    Private Sub CS_Sock_onReceiveConnect() Handles CS_Sock.onReceiveConnect
        AddToList("Received Connection from SBClient.exe")
        If SS_Sock.Connected = False Then
            SS_Sock.Connect(Me.ServerAddyTextBox.Text, CType(Me.ServerPortTextBox.Text, Int32))
        End If
    End Sub

    Private Sub SS_Sock_onGetConnect() Handles SS_Sock.onGetConnect
        AddToList("Connected to SBServer.exe")
    End Sub



    Private Sub SS_sock_onDataArrival(ByVal inData() As Byte, ByVal totBytes As Integer) Handles SS_Sock.onDataArrival
        CS_Sock.SendData(inData)
        AddToList("Detected " & Str(inData.Length) & " bytes Inbound: " & CS_Sock.BytestoString(inData))
        Logger("InBound:" & vbCrLf & inData.ToString)
    End Sub

    Private Sub CS_sock_onDataArrival(ByVal inData() As Byte, ByVal totBytes As Integer) Handles CS_Sock.onDataArrival
        If SS_Sock.Connected = False Then
            SS_Sock.Connect(Me.ServerAddyTextBox.Text, CType(Me.ServerPortTextBox.Text, Int32))
        End If

        Do Until SS_Sock.Connected = True

        Loop

        SS_Sock.SendData(inData)
        AddToList("Detected " & Str(inData.Length) & " bytes Outbound: " & SS_Sock.BytestoString(inData))
        Logger("OutBound:" & vbCrLf & inData.ToString)
    End Sub



    Private Sub SS_Sock_onError(ByVal Description As String) Handles SS_Sock.onError
        AddToList("SS_Sock Error: " & Description)
    End Sub

    Private Sub CS_Sock_onError(ByVal Description As String) Handles CS_Sock.onError
        AddToList("CS_Sock Error: " & Description)
    End Sub



    Private Sub SS_Sock_onDisconnect() Handles SS_Sock.onDisconnect
        AddToList("SS_Sock Disconnection!")
    End Sub

    Private Sub CS_Sock_onDisconnect() Handles CS_Sock.onDisconnect
        AddToList("CS_Sock Disconnection!")
        SS_Sock.Disconnect()
    End Sub


    Private Sub AddToList(ByVal Data As String)

        Debug.Print([Data])

        If Me.ActivityLogListBox.InvokeRequired Then
            Dim d As New SetAddToList(AddressOf AddToList)
            Me.Invoke(d, New Object() {[Data]})
        Else
            Me.ActivityLogListBox.Items.Add(Now & vbTab & [Data])
            Me.ActivityLogListBox.TopIndex = ActivityLogListBox.Items.Count - 1
            Me.Refresh()
        End If

        Logger([Data])
    End Sub



    Private Sub Logger(ByVal Data As String)
        Dim fs As FileStream
        Dim logPath As String = "./SBScout_Log.txt"
        Dim byteLE As Byte() = New UTF8Encoding(True).GetBytes(Data)

        'If File.Exists(logPath) = False Then
        '    File.Create(logPath)
        'End If

        '        fs = File.OpenWrite(logPath)

        '       fs.Write(byteLE, 0, byteLE.Length)

        '      fs.Close()

    End Sub


    Private Sub Form1_Load(ByVal sender As System.Object, _
                   ByVal e As System.EventArgs) Handles MyBase.Load

        Me.Text = "SBScout v0.01"
        Me.StartServerButton.Enabled = True
        Me.StopServerButton.Enabled = False
        Me.Refresh()

    End Sub

End Class
Class Module:
VB.NET:
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text


Public Class StateObject
    Public workSocket As Socket = Nothing
    Public BufferSize As Integer = 1023
    Public buffer(1023) As Byte
    Public sb As New StringBuilder()
End Class

Public Class MySocket
    Public Event onGetConnect()
    Public Event onReceiveConnect()
    Public Event onError(ByVal Description As String)
    Public Event onDataArrival(ByVal Data As Byte(), ByVal TotalBytes As Integer)
    Public Event onDisconnect()
    Public Event onSendComplete(ByVal DataSize As Integer)

    Private Shared response As [String] = [String].Empty
    Private Shared port As Integer = 44
    Private Shared ipAddress As IPAddress = ipAddress.Parse("192.168.1.3")
    Private Shared client As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

    Public bIsListening As Boolean = False

    Public Sub Connect(ByVal RemoteIPAddy As String, ByVal RemotePort As Integer)

        Try
            client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            port = RemotePort
            ipAddress = Net.IPAddress.Parse(RemoteIPAddy)
            Dim remoteEP As New IPEndPoint(ipAddress, port)
            client.BeginConnect(remoteEP, AddressOf sockConnected, client)
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try
    End Sub

    Public Sub Listen(ByVal LocalAddy As String, ByVal LocalPort As Integer)
        Dim localAddr As IPAddress = Net.IPAddress.Parse(LocalAddy)
        Dim Listener As New TcpListener(localAddr, LocalPort)

        Try
            'bIsListening = True

            Listener.Start()

            'Do While bIsListening = True

            Debug.Print("Loop: Listener.AcceptSocket()")
            'pauses here and waits for connection.
            client = Listener.AcceptSocket()
            If client.Connected = False Then RaiseEvent onError("Connection refused.") : Exit Sub
            RaiseEvent onReceiveConnect()

            Dim state As New StateObject()
            state.workSocket = client
            client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)

            Listener.Stop()

            'Loop

        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try

    End Sub


    Public Sub Disconnect()
        Try
            client.Shutdown(SocketShutdown.Both)
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try

        client.Close()
    End Sub

    Public Function StringToBytes(ByVal Data As String) As Byte()
        StringToBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
    End Function

    Public Function BytestoString(ByVal Data As Byte()) As String
        BytestoString = System.Text.ASCIIEncoding.ASCII.GetString(Data)
    End Function

    Private Sub sockConnected(ByVal ar As IAsyncResult)
        Try
            If client.Connected = False Then RaiseEvent onError("Connection refused.") : Exit Sub
            Dim state As New StateObject()
            state.workSocket = client
            client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
            RaiseEvent onGetConnect()
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try
    End Sub

    Public Sub SendData(ByVal Data() As Byte)
        Try
            Dim byteData As Byte() = Data
            client.BeginSend(byteData, 0, byteData.Length, 0, AddressOf sockSendEnd, client)
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try
    End Sub


    Private Sub sockDataArrival(ByVal ar As IAsyncResult)
        Dim state As StateObject = CType(ar.AsyncState, StateObject)
        Dim client As Socket = state.workSocket
        Dim bytesRead As Integer

        Try
            bytesRead = client.EndReceive(ar)
        Catch
            Exit Sub
        End Try

        Try
            Dim Data() As Byte = state.buffer
            If bytesRead = 0 Then
                client.Shutdown(SocketShutdown.Both)
                client.Close()
                RaiseEvent onDisconnect()
                Exit Sub
            End If
            ReDim state.buffer(1023)

            client.BeginReceive(state.buffer, 0, state.BufferSize, 0, AddressOf sockDataArrival, state)
            RaiseEvent onDataArrival(Data, bytesRead)
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try
    End Sub

    Private Sub sockSendEnd(ByVal ar As IAsyncResult)
        Try
            Dim client As Socket = CType(ar.AsyncState, Socket)
            Dim bytesSent As Integer = client.EndSend(ar)
            RaiseEvent onSendComplete(bytesSent)
        Catch
            RaiseEvent onError(Err.Description)
            Exit Sub
        End Try
    End Sub

    Public Function Connected() As Boolean
        Try
            Return client.Connected
        Catch
            RaiseEvent onError(Err.Description)
            Exit Function
        End Try
    End Function
End Class
 
Back
Top