TS2A

From Pandora Wiki
Jump to: navigation, search

Contents

Work in progress

This article is currently under construction! This might be moved to http://imfreedom.org/wiki/ once its done.

General

I (JayFoxRox) give up this project and open it for other developers so they can continue to work on it. I wrote multiple version of a teamspeak client. One was written in VB6 and is almost fully functional. Another one was written in C++ but it never got out of the testing phase. This article will feature some bits of the dirty source code of the VB6 version! The full VB6 version won't be released because it depends on C code which will be used in commercial Projects in the near future.

Rules

Some rules apply if you use this information:

  1. If you use this information I would like to be informed about it by! You can do this by contacting me through this wiki or at gp32x.
  2. You must include my name in the credits of your software (let it be the manual or readme or an about dialog in your program), more information about this when you contact me.
  3. You are not allowed to create flooders, virus or anything else malicious with the information provided in the article.
  4. You should, but you are not forced to, make the source of your project available.
  5. These rules are subject to change and you should check them again before releasing your project!
  6. This is a loose contract and you are not bound to it except for rule 1, 2 and 3 which can be found above.

Constants

There are some constants which you will come accross in the packets, I will define them here for easier reading.

Codec constants

  • CELP_5_1 = 0x0
  • CELP_6_3 = 0x1
  • SPEEX_12_3 = 0x9
  • SPEEX_19_5 = 0xB
  • SPEEX_25_9 = 0xC

Packet identifiers

  • PACKET_IN_UNKNOWN = 0x0
  • PACKET_OUT_UNKNOWN = 0x0

Packet format

More information coming soon

The checksum field

The checksum field in the packet header is a simple CRC32 checksum. The polynom is 0xEDB88320. To generate the checksum field you have to create the complete packet with 0x00000000 in the checksum field, generate the checksum and move it to the checksum field.

Splitting packets

Packet confirmations

Packets: Server to Client

Join Confirmation

Case &HF4BE0400:
 
Dim by_X() As Byte
ReDim by_X(&H1B4 - 17)
ReadData by_X
CopyMemory ln_Challenge, by_X(&HAC - 16), 4
CopyMemory ln_Player, by_X(&HB0 - 16), 4
 
fr_Main.Debug_Print "INFORMATION"

Pong

ID 0xF4BE0200
Description Response to an incoming Ping signal to keep the connection alive
Parameters


Size Field
16 Byte Default packet header

Packet arrival confirmation

ID 0xF1BE0000
Description This package is send when a Packet arrived successfully
Parameters


Size Field
16 Byte Default packet header

Text messages forbidden

Case &HF0BE0FFC:
 
ReDim by_Copy(&HE - 1)
ReadData by_Copy
fr_Main.Debug_Print "CHAT FORBIDDEN"
 
ProcessConfirmation Client, ln_Server

Unknown

Case &HF1BE0100:
 
fr_Main.Debug_Print "YYY?"

Unable to switch channel

Case &HF0BE91FF:
 
ReDim by_Copy(&H12 - 1)
ReadData by_Copy
 
Debug.Print "Couldn't switch channel!"
 
ProcessConfirmation Client, ln_Server

Channellist

Case &HF0BE0600:
 
ReDim by_Copy(4 - 1)
ReadData by_Copy
 
Dim ln_Count As Long
ln_Count = ReadInteger(1)
Debug.Print (ln_Count - 1) & " packets left"
 
ln_Count = ReadInteger(1)
 
Debug.Print "Channels: " & ln_Count
 
Dim in_X As Integer
 
For in_X = 0 To ln_Count - 1
 
 
Dim ln_ChannelID As Long
Dim ln_Order As Long
Dim ln_Parent As Long
ln_ChannelID = ReadInteger(1)
ln_Order = ReadInteger(1)
ln_Parent = ReadInteger(1)
 
ReDim by_Copy(4 - 1)
ReadData by_Copy
 
Dim st_Title As String
Dim st_Topic As String
Dim st_Description As String
 
'ls_Channel.AddItem ln_ChannelID & ") " & st_Channel
'Add channel to channellist - TODO!
 
st_Title = ReadText(0)
st_Topic = ReadText(0)
st_Description = ReadText(0)
 
AddChannel Client, ln_ChannelID, ln_Parent, st_Title, st_Topic, st_Description, ln_Order, by_Copy(2), 0, 0
 
fr_Main.Debug_Print ""
Debug.Print "Channel: " & st_Title & " (" & Hex(by_Copy(3)) & " - " & Hex(ln_Parent) & ", " & Hex(ln_ChannelID) & ")"
 
Next in_X
 
fr_Main.Debug_Print "CHANNELS"
 
ProcessConfirmation Client, ln_Server

Client was moved or kicked (Local client)

Case &HF0BE6500:
 
 
ReDim by_Copy(&H30 - 1)
ReadData by_Copy
 
'
'Channel switch = 0x30 Bytes -> 00 00 00 00 93 F6 7E BF 0B 00 00 00 06 00 00 00 00 00 00 1F F1 B7 78 F1 1F A1 01 00 00 00 30 F1 1F A1 59 2D E5 B7 6C F1 1F A1 00 00 00 00 07 FF
'Bot got kicked = 0x30 Bytes -> 00 00 00 00 C3 CA 89 AC 17 00 00 00 02 00 02 00 00 00 00 00 00 00 00 00 F0 BE 08 00 00 00 00 00 00 00 00 00 00 00 00 00 07 FF FF 0F FE FF FE FF
'
 
'MsgBox "Kicked?"
fr_Main.Debug_Print "Kicked"
 
ProcessConfirmation Client, ln_Server

Kicked (Remote client)

Case &HF0BE6600:
 
ReDim by_Copy(&H34 - 1)
ReadData by_Copy
fr_Main.Debug_Print "KICKED FROM CHANNEL"
 
ProcessConfirmation Client, ln_Server

Unknown

Case &HF0BE6700:
 
ReDim by_Copy(&H16 - 1)
ReadData by_Copy
fr_Main.Debug_Print "ZOMFG?!"
 
ProcessConfirmation Client, ln_Server

Unknown

Case &HF0BE0700:
 
ReDim by_X(&H1D4 - 17)
ReadData by_X
 
fr_Main.Debug_Print "FUCKED! - Sub channel switch?"
 
ProcessConfirmation Client, ln_Server
ln_Client = 2
ln_Counter = 2
fr_Main.tm_Poll.Enabled = True
'Call tm_Poll_Timer

Server homepage address

Case &HF0BE0800:
 
ReDim by_X(&H12E - 17)
ReadData by_X
 
fr_Main.Debug_Print "WEB SERVER"
 
ProcessConfirmation Client, ln_Server

Client join

Case &HF0BE6400:
 
ReDim by_Copy(4 * 5 - 1)
ReadData by_Copy
ReDim by_Copy(2 - 1)
ReadData by_Copy
ReDim by_Copy(1 - 1)
ReadData by_Copy
fr_Main.Debug_Print "Name: " & ReadText(by_Copy(0))
ReDim by_Copy(27 - by_Copy(0))
ReadData by_Copy
 
fr_Main.Debug_Print "JOIN"
 
ProcessConfirmation Client, ln_Server

Client list (?)

Case &HF0BE6C00:
 
ReDim by_Copy(&H8 - 1)
ReadData by_Copy
Dim in_Count As Integer
in_Count = ReadInteger(1)
ReDim by_Copy(&HE - 1)
ReadData by_Copy
Dim in_Index As Integer
For in_Index = 0 To in_Count - 1
Dim in_Channel As Integer
Dim in_Sub As Integer
ReDim by_Copy(1 - 1)
ReadData by_Copy
st_String = ReadText(by_Copy(0))
Debug.Print "User in channel: " & st_String
ReDim by_Copy(28 - Len(st_String))
ReadData by_Copy
in_Channel = ReadInteger(0)
in_Sub = ReadInteger(0)
ReDim by_Copy(&H5 - 1)
ReadData by_Copy
Next in_Index
ReDim by_Copy(&H1C4 - &H2C * in_Count - &H1A - 1)
ReadData by_Copy
 
ProcessConfirmation Client, ln_Server

Channel order index changed

Case &HF0BE7500:
 
ReDim by_Copy(&H12 - 1)
ReadData by_Copy
 
Debug.Print "Channel order modified"
 
ProcessConfirmation Client, ln_Server

Channel name changed

Case &HF0BE6F00:
 
ReDim by_Copy(&H10 - 1)
ReadData by_Copy
st_String = ReadText(0)
 
Debug.Print "Channel name modified (" & st_String & ")"
 
ProcessConfirmation Client, ln_Server

Channel description changed

Case &HF0BE7200:
 
ReDim by_Copy(&H10 - 1)
ReadData by_Copy
st_String = ReadText(0)
 
Debug.Print "Channel description modified (" & st_String & ")"
 
ProcessConfirmation Client, ln_Server

Channel topic changed

Case &HF0BE7000:
 
ReDim by_Copy(&H10 - 1)
ReadData by_Copy
st_String = ReadText(0)
 
Debug.Print "Channel topic modified (" & st_String & ")"
 
ProcessConfirmation Client, ln_Server

Player attributes changed

Case &HF0BE6800:
 
ReDim by_Copy(8 - 1)
ReadData by_Copy
Dim by_Attributes As Byte
Dim ln_Index As Long
ln_Index = ReadInteger(1)
ReDim by_Copy(2 - 1)
ReadData by_Copy
Dim in_Attributes As Integer
CopyMemory in_Attributes, by_Copy(0), 2
 
fr_Main.Debug_Print "PLAYER ATTRIBUTES"
 
ProcessConfirmation Client, ln_Server

Speech data (CELP 5.1)

Case &HF3BE0000
 
ReDim by_Copy(&HA6 - 1)
ReadData by_Copy
 
fr_Main.Debug_Print "PLAYER SPEECH (CELP 5.1)"

Speech data (CELP 6.3)

Case &HF3BE0001
 
ReDim by_Copy(&H40 - 1)
ReadData by_Copy
 
fr_Main.Debug_Print "PLAYER SPEECH (CELP 6.3)"

Speech data (Speex 12.3)

Case &HF3BE0009
 
ReDim by_Copy(&H91 - 1)
ReadData by_Copy
 
fr_Main.Debug_Print "PLAYER SPEECH (Speex 12.3)"

Speech data (Speex 19.5)

Case &HF3BE000B
 
ReDim by_Copy(&H7 - 1)
ReadData by_Copy
ReDim by_Copy(&HE4 - 1)
ReadData by_Copy
fr_Main.Debug_Print "PLAYER SPEECH (Speex 19.5)"

Speech data (Speex 25.9)

Case &HF3BE000C
 
ReDim by_Copy(&H7 - 1)
ReadData by_Copy
ReDim by_Copy(&H134 - 1)
ReadData by_Copy
'Put #5, , by_Copy
fr_Main.Debug_Print "PLAYER SPEECH (Speex 25.9)"

Channel removed

Case &HF0BE7300:
 
ln_ChannelID = ReadInteger(1)
ln_ChannelID = ReadInteger(1)
ReDim by_Copy(&H2 - 1)
ReadData by_Copy
ln_ChannelID = ReadInteger(1)
 
 
 
fr_Main.Debug_Print "Remove Channel"
 
ProcessConfirmation Client, ln_Server
 
Client.Channel(FindChannel(Client, ln_ChannelID)).Used = False
Client.ChannelCount = Client.ChannelCount - 1
 
'00 00 00 00 1F 1B AB 12 1F 00 02 00 00 00

New channel created

Case &HF0BE6E00:
 
ReDim by_Copy(&H8 - 1)
ReadData by_Copy
ReDim by_Copy(4 - 1)
ReadData by_Copy
 
ln_ChannelID = ReadInteger(1)
ln_Order = ReadInteger(1)
ln_Parent = ReadInteger(1)
 
ReDim by_Copy(4 - 1)
ReadData by_Copy
 
st_Title = ReadText(0)
fr_Main.Debug_Print "CHANNEL CREATED (" & st_Title & ")"
st_Topic = ReadText(0)
st_Description = ReadText(0)
 
AddChannel Client, ln_ChannelID, ln_Parent, st_Title, st_Topic, st_Description, ln_Order, by_Copy(2), 0, 0
 
ProcessConfirmation Client, ln_Server

Channel flags changed

Case &HF0BE7100:
 
ReDim by_Copy(&H14 - 1)
ReadData by_Copy
 
Debug.Print "Channel flags modified"
 
'Channel Created -> 00 00 00 00 50 27 21 CB 02 00 00 00 1E 00 00 00 00 00 0A 00 FF FF FF FF 80 0C 19 00 4F 4D 47 00 00 00
'Channel Changed -> 00 00 00 00 25 D3 01 AA 1F 00 00 00 01 00 0B 00 02 00 00 00
 
ProcessConfirmation Client, ln_Server

Channel client limit changed

Case &HF0BE7400:
 
ReDim by_Copy(&H12 - 1)
ReadData by_Copy
 
Debug.Print "Channel limit modified"
 
ProcessConfirmation Client, ln_Server

Text message received

Case &HF0BE8200:
 
ReDim by_X(8 - 1)
ReadData by_X
Dim ln_Color As Long
ln_Color = ReadInteger(1)
fr_Main.Label1.ForeColor = IIf(ln_Color = (ln_Color And &HFFFFFF), ln_Color And &HFFFFFF, GetSysColor(ln_Color And &HFFFFFF))
ReDim by_X(1 - 1)
ReadData by_X 'Message type?
fr_Main.Label1.Caption = by_X(0) & " "
ReadData by_X
fr_Main.Label1.Caption = fr_Main.Label1.Caption & ReadText(by_X(0)) & ": "
ReDim by_X(27 - by_X(0))
ReadData by_X
fr_Main.Label1.Caption = fr_Main.Label1.Caption & ReadText(0)
 
ProcessConfirmation Client, ln_Server

Packets: Client to Server

Join details

WriteInteger &HF0BE0500, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger &H1000000, 0
WriteInteger &H0, 0
ln_Address = WriteInteger(0, 0)
Dim st_String As String
ReDim by_Copy(2 - 1)
WriteData by_Copy
 
st_String = "Cosy Corner" '"Default" '"Dungeon"
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(29 - Len(st_String) - 1)
WriteData by_Copy
 
st_String = ""
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(29 - Len(st_String) - 1)
WriteData by_Copy
 
st_String = ""
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(29 - Len(st_String) - 1)
WriteData by_Copy
 
WriteInteger &H0, 0
 
Dim ln_Key As Long
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
SendData

Ping

WriteInteger &HF4BE0100, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger ln_Client, 1 'client[0x0C],4 = read[0x0C]
ln_Address = WriteInteger(0, 0)
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
ln_Client = ln_Client + 1
SendData

Speech data (Speex 25.9)

WriteInteger &HF2BE000C, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
ln_pcount = ln_pcount + 1
WriteInteger ln_pcount, 1
 
ReDim by_Copy(&H1 - 1)
by_Copy(0) = 5
WriteData by_Copy
 
ReDim by_Copy(&H134 - 1)
Get #4, , by_Copy
WriteData by_Copy
 
SendData

Packet arrival confirmation

Public Function ProcessConfirmation(Client As TeamspeakClient, Packet As Long)
WriteInteger &HF1BE0000, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger Packet, 1
SendData
End Function

Player attributes

Public Function ProcessAttribute(Client As TeamspeakClient, Away As Boolean, Microphone As Boolean, Speakers As Boolean, Commander As Boolean, Whisper As Boolean, Record As Boolean)
WriteInteger &HF0BE3001, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger ln_Counter, 1
ln_Counter = ln_Counter + 1
WriteInteger 0, 0
ln_Address = WriteInteger(0, 0)
Dim by_Attribute(2 - 1) As Byte
 
If Whisper = False Then by_Attribute(0) = by_Attribute(0) + &H4
If Microphone = False Then by_Attribute(0) = by_Attribute(0) + &H10
If Speakers = False Then by_Attribute(0) = by_Attribute(0) + &H20
If Commander = True Then by_Attribute(0) = by_Attribute(0) + &H1
If Away = True Then by_Attribute(0) = by_Attribute(0) + &H8
If Record = True Then by_Attribute(0) = by_Attribute(0) + &H40
 
by_Attribute(1) = 0
WriteData by_Attribute
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
SendData
End Function

Login / Connect packet

Public Function ProcessLogin(Host As String, Display As String, Login As String, Password As String, Assign As Boolean) As TeamspeakClient
fr_Main.Debug_Print "LOGIN"
 
Dim st_Split() As String
st_Split() = Split(Host, ":")
fr_Main.ws_Client.RemoteHost = st_Split(0)
fr_Main.ws_Client.RemotePort = IIf(UBound(st_Split) = 0, 8767, st_Split(1))
fr_Main.ws_Client.Bind
 
WriteInteger &HF4BE0300, 0
Dim st_String As String
ReDim by_Copy(8 - 1)
WriteData by_Copy
WriteInteger &H1000000, 0
ln_Address = WriteInteger(0, 0)
st_String = "TeamSpeak"
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
st_String = "Shitface Express"
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
 
WriteText (Chr(2) & Chr(&H0)) 'Major.Major
WriteText (Chr(0) & Chr(&H0)) 'Major.Minor
WriteText (Chr(32) & Chr(&H0)) 'Minor.Major
WriteText (Chr(60) & Chr(&H0)) 'Minor.Minor
 
WriteText (Chr(IIf(Assign, 1, 0)) & Chr(IIf(Login = "", 1, 2))) 'Allow assigned nick / [1 = Anonymous; 2 = Registered]
 
st_String = Login 'Loginname
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
 
st_String = Password 'Server Password
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText st_String
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
 
 
st_String = Display
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText (st_String)
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
SendData
 
ReDim ProcessLogin.Channel(1 - 1)
ReDim ProcessLogin.Remote(1 - 1)
ReDim ProcessLogin.Packet(1 - 1)
ProcessLogin.Used = True
End Function

Channel switch

Public Function ProcessSwitch(Client As TeamspeakClient, ByVal Index As Long, Password As String)
WriteInteger &HF0BE2F01, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger ln_Counter, 1
ln_Counter = ln_Counter + 1
WriteInteger &H0, 0
ln_Address = WriteInteger(0, 0)
WriteInteger Client.Channel(FindChannel(Client, Index)).Index, 1
Dim st_String As String
st_String = Password
ReDim by_Copy(1 - 1)
by_Copy(0) = Len(st_String)
WriteData by_Copy
WriteText (st_String)
ReDim by_Copy(28 - Len(st_String))
WriteData by_Copy
 
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
 
SendData
End Function

Text message

Public Function ProcessMessage(Client As TeamspeakClient, Receiver As Byte, Color As Long, Text As String)
If Receiver = 0 Then
End If
 
WriteInteger &HF0BEAE01, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger ln_Counter, 1
ln_Counter = ln_Counter + 1
WriteInteger &H0, 0
ln_Address = WriteInteger(0, 0)
WriteInteger Color, 1
WriteInteger &H0, 0
ReDim by_Copy(1 - 1)
WriteData by_Copy
Dim st_String As String
st_String = Text
WriteText st_String
ReDim by_Copy(1 - 1)
WriteData by_Copy
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
 
SendData
End Function

Leave packet

Public Function ProcessExit(Client As TeamspeakClient)
WriteInteger &HF0BE6500, 0
WriteInteger ln_Challenge, 1
WriteInteger ln_Player, 1
WriteInteger ln_Counter, 1
ln_Counter = ln_Counter + 1
WriteInteger &H0, 0
ln_Address = WriteInteger(0, 0)
WriteInteger &H20, 1
WriteInteger 1, 1
WriteInteger 0, 0
 
ReDim by_Copy(&H1C - 1)
 
by_Copy(0) = &H90
by_Copy(1) = &HFB
by_Copy(2) = &H1F
by_Copy(3) = &HA1
by_Copy(4) = &H0
by_Copy(5) = &H0
by_Copy(6) = &H0
by_Copy(7) = &H0
by_Copy(8) = &H40
by_Copy(9) = &HAA
by_Copy(10) = &H16
by_Copy(11) = &H6C
by_Copy(12) = &HC5
by_Copy(13) = &HEB
by_Copy(14) = &HD3
by_Copy(15) = &H3F
by_Copy(16) = &H25
by_Copy(17) = &H2D
by_Copy(18) = &HE1
by_Copy(19) = &H3F
by_Copy(20) = &HD8
by_Copy(21) = &HF2
by_Copy(22) = &H1F
by_Copy(23) = &HA1
by_Copy(24) = &H25
by_Copy(25) = &H6F
by_Copy(26) = &H5
by_Copy(27) = &H8
 
WriteData by_Copy
by_Copy = GetKey(by_Send, 0, UBound(by_Send) - 1)
CopyMemory by_Send(ln_Address), by_Copy(0), 4
 
SendData
End Function

More information coming soon

Sample traffic

Limitiations and Trivia

  • The channels codec is not forced, it should be taken as an recommendation
  • You can even speak while you are muted
  • The version field of a login packet is checked, the OS field is not

More information coming soon

Further reading

A similar project is called TeamBlibbityBlabbity but the documentation is not too good. It might be good as a reference anyway: It can be found at SourceForge

Personal tools
community