• Welcome to Valhalla Legends Archive.
 

SC/BW UDP Struct

Started by Mesiah / haiseM, December 14, 2005, 06:26 AM

Previous topic - Next topic

Mesiah / haiseM

This may not be as progressive or useful of a topic as i foresee or would like to see it, but does anybody here have any input on the information i've gathered on starcraft's udp structure?


UDP Packet Struct:

Dword: 0 (Unknown/Not verified)
Word: CheckSum
Word: Packet Length
Word: Message Counter Sent
Word: Message Receive
Word: Command Type (0, 1, or 2)
Word: Player ID (0 to 7)
Void: Packet Data


I've seen little to no change on the first dword, and the message counter may be different depending on the command type...

I also realize this structure may be smaller or larger depending on the command type. I will be doing more research on this.

I'd like to progress on this in any way i can, does anybody have any useful info on what may be right or wrong.. or even missing?
]HighBrow Innovations
Coming soon...

AIM Online Status: 

Ringo

Good job, This should help out abit.

Mesiah / haiseM

#2
Excellent. Well i guess somebody can delete this thread now :-p Also, I think the bottom half of this struct may be a slight improvement on yours. I'm pretty sure those are words and not bytes... Either way, your still receiving the packet data in the same position, so yours will still work even if its wrong... If you have proof on these being bytes, please post. I've got no bnet buddies left so all my research is being done by myself.. maybe one or two random people join the game i create, but it's not the testing environment i'd like it to be.. Thanks.
]HighBrow Innovations
Coming soon...

AIM Online Status: 

iago

#3
By the way, here's the struct for udp packets that somebody reversed many years ago:


struct message { 
unsigned long udptype; 
unsigned short checksum; 
unsigned short len; 
unsigned short pos1;
unsigned short pos2;
unsigned char cls;
unsigned char cmd;
unsigned char sender;
unsigned char resend;
char data[];
};


Hope that helps.
MyndFyre edit: added code tags.  You should know better, iago!
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Ringo

#4
Quote from: Mesiah / haiseM on December 14, 2005, 07:21 AM
I think the bottom half of this struct may be a slight improvement on yours. I'm pretty sure those are words and not bytes... Either way, your still receiving the packet data in the same position, so yours will still work even if its wrong... If you have proof on these being bytes, please post. I've got no bnet buddies left so all my research is being done by myself.. maybe one or two random people join the game i create, but it's not the testing environment i'd like it to be.. Thanks.
They are bytes, im sure of that :)
Depending on the packet class/command depends on how the header is used, for example, command 0 will use the 14th byte for the packet ID, where as command 1 will use the 17th Byte as the packet ID, and command 2 is a header carrying a payload of queued packets.
The Resend (as iago put it) is used for abit more than just resending packets, it has multiple uses, and again that can depend on the packet command.
The status byte handles things like SEQ checks, SEQ Verifications and Resend requests.
Normaly* when the status is anything other than 0x00, the send and Recv will match, and Packet ID's and payloads shouldnt be used:
    Command 0: SEQ Check of there Recv VS your Sent, any missing messages should trigger messages to be resent. (Normaly done over multiple messages)
    Comamnd 1: SEQ Verifys the message was Recv (only true for the last message)
    Command 2: Depending on SEQ Sent Vs Your sent, SEQ checks, extra game beats and resend requests

These are the incoming and out going structure's i wrote for my bot awhile ago, which might be worth reading through:

Public Type UDPPacketHeader
    pIP As String
    pPort As Long
    pSum As Long
    pSize As Long
    pSent As Long
    pRecv As Long
    pCmd As Byte
    pEvent As Byte
    pSender As Byte
    pStatus As Byte
End Type

Public Sub UDP_PARSER(ByVal Data As String, ByVal IP As String, ByVal Port As Long)
    Dim packetID As Long
    packetID = Buf.GetDWORD(Mid(Data, 1, 4))
    Select Case packetID
        Case &H0 'Game packets
            If Len(Data) < 16 Then: MakeLog Data, vbRed, "Under Sized UDP Game Packet": Exit Sub
            Dim P As UDPPacketHeader
            With P
                .pIP = IP
                .pPort = Port
                .pSum = Buf.GetWORD(Mid(Data, 5, 2))
                .pSize = Buf.GetWORD(Mid(Data, 7, 2))
                If Not .pSize = (Len(Data) - 4) Then
                    MakeLog Data, vbRed, "UDP Packet Lengh Doesnt Match Data Lengh!!!"
                    Exit Sub
                End If
                .pSent = Buf.GetWORD(Mid(Data, 9, 2))
                .pRecv = Buf.GetWORD(Mid(Data, 11, 2))
                .pCmd = Asc(Mid(Data, 13, 1))
                If P.pCmd = 0 Then .pEvent = Asc(Mid(Data, 14, 1))
                .pSender = Asc(Mid(Data, 15, 1))
                .pStatus = Asc(Mid(Data, 16, 1))
                If P.pCmd = 1 And .pStatus = 0 Then .pEvent = Asc(Mid(Data, 17, 1))
            End With
            Call CheckSEQ(Data, P) 'Parse it
            Exit Sub
        Case &H3: Call BNCS_UDP_H_0x03(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
        Case &H5: Call BNCS_UDP_H_0x05(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
        Case &H6: Call BNCS_UDP_H_0x06(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
        Case Else: MakeLog Data, vbRed, "Unknown UDP Data"
    End Select
End Sub


Out going:

Public Enum PacketHeaders
    BNCS_HEADER = 0
    BNFTP_HEADER = 1
    BNRS_HEADER = 2
    BNLS_HEADER = 3
    D2GS_HEADER = 4
    W3DMGS_HEADER = 5
    BNCS_UDPHEADER = 6
    UDPG_HEADER = 7
End Enum

Public Sub InsertHEADER(ByVal packetID As Byte, _
                        Optional Header As PacketHeaders = BNCS_HEADER, _
                        Optional Sent As Long, _
                        Optional ByVal Recv As Long, _
                        Optional ByVal PacketType As Byte = 0, _
                        Optional ByVal Status As Byte = 0, _
                        Optional ByVal AddSEQ As Boolean = False)
    Buffer = MakeHEADER(packetID, Header, Sent, Recv, PacketType, Status, AddSEQ) & Buffer
End Sub

Public Function MakeHEADER(ByVal packetID As Byte, _
                           Header As PacketHeaders, _
                           UDPSent As Long, _
                           ByVal UDPRecv As Long, _
                           ByVal UDPPacketCmd As Byte, _
                           ByVal UDPStatus As Byte, _
                           ByVal AddSEQ As Boolean) As String
    Dim tmpDat As String
    Select Case Header
        Case BNCS_HEADER:    tmpDat = Chr$(&HFF) & Chr$(packetID) & MakeWORD(Len(Buffer) + 4)
        Case BNFTP_HEADER:   tmpDat = MakeWORD(Len(Buffer) + 2)
        Case BNCS_UDPHEADER: tmpDat = MakeDWORD(CLng(packetID))
        Case BNRS_HEADER:    tmpDat = MakeWORD(Len(Buffer) + 3) & Chr$(packetID)
        Case BNLS_HEADER:    tmpDat = MakeWORD(Len(Buffer) + 3) & Chr$(packetID)
        Case D2GS_HEADER:    tmpDat = Chr$(packetID)
        Case W3DMGS_HEADER:  tmpDat = Chr$(&HF7) & Chr$(packetID) & MakeWORD(Len(Buffer) + 4)
        Case UDPG_HEADER
            If AddSEQ = True Then UDPSent = UDPSent + 1
            tmpDat = tmpDat & MakeWORD(UDPSent)
            tmpDat = tmpDat & MakeWORD(UDPRecv)
            tmpDat = tmpDat & Chr$(UDPPacketCmd)
            'type 0 packet ID
            If UDPPacketCmd = 0 Then
                tmpDat = tmpDat & Chr$(packetID)
            Else
                tmpDat = tmpDat & Chr$(0)
            End If
            tmpDat = tmpDat & Chr$(MyPID)
            tmpDat = tmpDat & Chr$(UDPStatus)
            'type 1 packet ID
            If UDPPacketCmd = 1 And UDPStatus = &H0 Then tmpDat = tmpDat & Chr$(packetID)
            'queue the Null DWORD, UDP check sum and packet Len
            tmpDat = MakeWORD(Len(tmpDat) + Len(Buffer) + 4) & tmpDat
            tmpDat = MakeWORD(UDPCheckSum(MakeWORD(0) & tmpDat & Buffer)) & tmpDat
            tmpDat = MakeDWORD(0) & tmpDat
    End Select
    MakeHEADER = tmpDat
    tmpDat = ""
End Function


And you can kinda see how im useing it here

Mesiah / haiseM

Hrm... Thanks, i think i pretty much got it down now. Man, that was fast :)

Almost makes me wonder why I never tried this before.. Well... I did once, but i was just sending a buttload of hex characters :-P Thanks again.
]HighBrow Innovations
Coming soon...

AIM Online Status: