Dim cmd As MyWoW.LoginServer.Packet.LogonOpcode ' // OP code = CMD_AUTH_LOGON_CHALLENGE
Dim [error] As MyWoW.LoginServer.Packet.LogonErrorCode ' // 0x02
Dim size As UInt16 ' // size of the rest of packet, without this part
Dim gamename() As Char ' // "WoW"
Dim version() As Byte ' // 0x01 08 00 -> (1.8.0)
Dim build As UInt16 ' // 0x7F12 -> 4735
Dim platform() As Char ' // 68x\0 -> "x86"
Dim os() As Char ' // niW\0 -> "Win"
Dim localization() As Char '// BGne -> 'enGB'
Dim timezone_bias As UInt32 ' // 0x78 00 00 00
Dim ip() As Byte ' // client ip: 0x7F 00 00 01
Dim acclen As Byte ' // length of account name (without zero-char)
Dim acc() As Char ' // upcased account name (without zero-char)
End Structure
其中cmd是登陆过程使用的Opcode(即命令代码),登陆过程的Opcode列表如下:
Public Enum LogonOpcode As Byte
CMD_AUTH_LOGON_CHALLENGE = &H0 ' // client
CMD_AUTH_LOGON_PROOF = &H1 ' // client
CMD_AUTH_RECONNECT_CHALLENGE = &H2 ' // client
CMD_AUTH_RECONNECT_PROOF = &H3 ' // client
CMD_REALM_LIST = &H10 ' // client
CMD_XFER_INITIATE = &H30 ' // client? from server
CMD_XFER_DATA = &H31 ' // client? from server
CMD_XFER_ACCEPT = &H32 ' // not official name, from client
CMD_XFER_RESUME = &H33 ' // not official name, from client
CMD_XFER_CANCEL = &H34 ' // not official name, from client
'// unknown:
CMD_GRUNT_AUTH_CHALLENGE = &H0 ' // server
CMD_GRUNT_AUTH_VERIFY = &H2 ' // server
CMD_GRUNT_CONN_PING = &H10 ' // server
CMD_GRUNT_CONN_PONG = &H11 ' // server
CMD_GRUNT_HELLO = &H20 ' // server
CMD_GRUNT_PROVESESSION = &H21 ' // server
CMD_GRUNT_KICK = &H24 ' // server
End Enum
error为错误代码,列表如下:
Public Enum LogonErrorCode As Byte
'// LOGIN_STATE_FAILED:
LOGIN_FAILED = 1 ' // 2, B, C, D // "Unable to connect"
LOGIN_BANNED = 3 ' // "This World of Warcraft account has been closed and is no longer in service -- Please check the registered email address of this account for further information."; -- This is the error message players get when trying to log in with a banned account.
LOGIN_UNKNOWN_ACCOUNT = 4 ' // 5 // "The information you have entered is not valid. Please check the spelling of the account name and password. If you need help in retrieving a lost or stolen password and account, see www.worldofwarcraft.com for more information.";
LOGIN_ALREADYONLINE = 6 ' // "This account is already logged into World of Warcraft. Please check the spelling and try again.";
LOGIN_NOTIME = 7 ' // "You have used up your prepaid time for this account. Please purchase more to continue playing";
LOGIN_DBBUSY = 8 ' // "Could not log in to World of Warcraft at this time. Please try again later.";
LOGIN_BADVERSION = 9 ' // "Unable to validate game version. This may be caused by file corruption or the interference of another program. Please visitwww.blizzard.com/support/wow/ for more information and possible solutions to this issue.";
LOGIN_PARENTALCONTROL = &HF ' // "17"="LOGIN_PARENTALCONTROL" // "Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at http://www.worldofwarcraft.com.";
'// LOGIN_STATE_AUTHENTICATED:
LOGIN_OK = 0 ' // E
'// LOGIN_STATE_DOWNLOADFILE, LOGIN_OK
LOGIN_DOWNLOADFILE = &HA ' // not official name
End Enum
size为无符号16位整数型,表示除了封包头部(命令码,错误码,和封包大小)之外的剩余封包大小
gamename一直都为WoW,不过4个字节长度,第一个字节为0
version表示客户端版本号,3字节,一个字节表示一个小节,比如1.8.0则为01 08 00
build是客户端的build号,16位无符号整数,如:7F12就是4735。
platform是系统信息,一般为“68x”即x86,4字节
os是操作系统,如niW则为Win,4字节
localization是客户端语言和区域信息,英语英国则为BGne,即enGB,4字节
timezone就是时区,没什么好解释,4字节
ip是客户端ip地址,4字节,如7F 00 00 1为127.0.0.001
acclen为帐号名长度,8位无符号整数,1字节
acc为用户输入的用户名,全部大写
其实这么多信息,真正重要的是版本号和用户名,其他处不处理看个人喜好。
服务器的响应封包结构如下:
Public Structure SServerLogonChallenge_Ok
Dim cmd As Packet.LogonOpcode '; // 0x00 -> OPcode = CMD_AUTH_LOGON_CHALLENGE ? CMD_GRUNT_AUTH_CHALLENGE
Dim [error] As Packet.LogonErrorCode ' ; // 0 -> ok = LOGIN_OK
Dim unk1 As Byte ' // 0x00
Dim B() As Byte ' // calculated by server
Dim g_len As Byte ' // 0x01
Dim g As Byte ' // 0x07 (const)
Dim N_len As Byte ' // 0x20
Dim N As BigInteger ' // const
Dim salt() As Byte ' // random
Dim unk2() As Byte ' //1: BA 79 D4 8D - BF FC BF AD - 8C B4 EC B3 - 75 C5 96 05
首先,我们需要一个临时字符串,用来保存从帐号数据库里取得的正确的用户名和密码(例如,用户名abc,密码def,那么这个字符串为:”ABC:DEF”)。此外我们还需要另外一个Byte()类变量,比如Dim TempHash() As Byte,TempHash等于刚才那个临时字符串的sha1值。现在将tempHash反转(reserve)然后用他创建一个新的临时BigInteger变量x。
现在我们需要另外一些临时变量:tmp As BigInteger, v As BigInteger, k As New BigInteger,其中tmp等于N反转后生成的biginteger,k等于3,v=(x^g) mod tmp
(运算符都为vb运算符,^是指数,mod是求余数,c#或者c++请自行修改)
现在需要随机生成另外一个20字节长度的大整数:Dim b As BigInteger。注意,这里的b是个临时变量,并不是最后计算结果B。
现在从新给tmp赋值:tmp=(k * v + (b ^ g) mod tmp) mod tmp
计算结果B等于tmp的16进制表达方式然后反转。
封包最后一个变量,unk2,随机生成一个16字节长度大整数转换成16进制即可
下面是我写的处理第一个封包的代码,没优化,所以有些地方有点不合理,不过不影响使用:
Private Shared Function ProcessClientLogonChallenge(ByVal sock As MyWoW.LoginServer.Client, ByVal data As ClientLogonChallenge) As Boolean
Dim senddata As Packet.PacketSendManager.Packet
Dim sendpacket As SServerLogonChallenge_Ok
Dim tick As Integer = GetTickCount
Dim x As BigInteger, tmp As New BigInteger, temphashb() As Byte