• Welcome to Valhalla Legends Archive.
 

[Python] Battle.net Login

Started by topaz, July 06, 2006, 08:01 PM

Previous topic - Next topic

topaz

I haven't been able to get the below to properly login. I am ipbanned immediately - I have compared packetlogs, and it should have worked. If you know or see what I did wrong, please post.

main.py
iimport socket
import struct
import bncs

#connect
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('europe.battle.net', 6112))
sock.send(chr(1))

#initialize parser and packetbuilder
pbuilder = bncs.builder(sock)
pbuilder.Send0x50()
parser = bncs.parser(sock)

#loop that checks for data
strBuffer = ''
buflen = 0

while 1:
    strTemp = sock.recv(1024)
    recvlen = len(strTemp)

    strBuffer += strTemp
    buflen += recvlen

    while  (buflen >= 4):
        lngLen, = struct.unpack('<b', strBuffer[2:3])
        if (buflen < lngLen): break
        parser.parsePacket(strBuffer[:lngLen])
        strBuffer = strBuffer[lngLen:]
        buflen -= lngLen


bncs.py
import struct
import socket

class packetbuffer:
   
    def __init__(self, sock):
        self.buffer = []
        self.sock = sock
       
    def insertData(self, data):
        self.buffer.append(data)

    def insertString(self, data):
        self.buffer.append(data)

    def insertNTString(self, data):
        self.buffer.append(data + chr(0))

    def insertDWORD(self, data):
        data = self.makeDWORD(data)
        self.buffer.append(data)

    def makeDWORD(self, data):
        return struct.pack('I', data)

    def makeWORD(self, data):
        return struct.pack('H', data)

    def getDWORD(self, data):
        return struct.unpack('<I', data)

    def getWORD(self, data):
        return struct.unpack('<H', data)
       
    def sendPacket(self, packetID):

        tmp = ''
        for i in self.buffer: tmp += i

        packetlen = self.makeWORD(len(tmp) + 4)

        header = chr(0xff) + chr(packetID) + packetlen

        self.sock.send(header + tmp)
       
        self.clear()
       
    def clear(self):
        self.buffer = list()

class builder:

    def __init__(self, sock):
        self.sock = sock
       
    def Send0x50(self):
        pbuffer = packetbuffer(self.sock)
       
        pbuffer.insertDWORD(0x00)
        pbuffer.insertString('68XIRATS')
        pbuffer.insertDWORD(0xCB)
        pbuffer.insertDWORD(0x00)
        pbuffer.insertDWORD(0x00)
        pbuffer.insertDWORD(0x00)
        pbuffer.insertDWORD(0x00)
        pbuffer.insertDWORD(0x00)
        pbuffer.insertNTString('USA')
        pbuffer.insertNTString('United States')
        pbuffer.sendPacket(0x50)

class parser:
    def __init__(self, sock):
        self.sock = sock

    def parsePacket(self, data):     
        packetID = ord(data[1:2])

        print 'data: ' + data
       
        print 'Packet received: %s' %hex(packetID)
RLY...?

UserLoser

Quote
self.buffer.append(data + '.')

I don't know python, but that looks like it's putting a period there instead of a null character?

topaz

#2
Quote from: UserLoser on July 07, 2006, 01:14 AM
Quote
self.buffer.append(data + '.')

I don't know python, but that looks like it's putting a period there instead of a null character?

They amount to the same thing.

EDIT:

You're right! Thanks a lot, UserLoser.

Note to self: never listen to Yegg when he gives Python advice.
RLY...?

Yegg

#3
Quote from: Topaz on July 07, 2006, 01:14 AM
Quote from: UserLoser on July 07, 2006, 01:14 AM
Quote
self.buffer.append(data + '.')

I don't know python, but that looks like it's putting a period there instead of a null character?

They amount to the same thing.

EDIT:

You're right! Thanks a lot, UserLoser.

Note to self: never listen to Yegg when he gives Python advice.

;D

That's not Python specific, the issue with the period. I figured it would work just fine. I decided to test it in Scheme by creating a binary file and reading it with a hex editor. I wrote "hello world" + "." to one file, and "hello world" + a null character (Python would display as '\x00'). The first file, using the period, shows a 0x2E representing the hex of the period. The second file shows the hex as 0x00 which is what we want.

I guess period and null character do have their differences  :).

Btw, did you do a faulty job comparing packet logs? I would have observed each byte in each packet.

K

Most hex editors use periods to display non-printable characters or characters that would screw up the formatting, since printing a tab, newline, or null in the middle of a string you are trying to align nicely will cause problems.    you can use isprint() in C/C++ to determine whether or not a character is printable, though it might not catch all of them.

topaz

Got another weird issue

After unpacking the packet length ('lngLen, = struct.unpack('H', strBuffer[2:4])') and comparing it to the length of the buffer, I get two wildly different numbers that make parsing data impossible:

lngLen = 25168
strBuffer.Length = 99

Does anyone know why it would do this?
RLY...?

Yegg

Well, what was the value of strBuffer[2:4]?

K

#7
Shouldn't it be 2:3, not 2:4?

Edit: perhaps that what you meant, as it is written as such in your first post.

topaz

#8
Quote from: K on July 07, 2006, 09:02 PM
Shouldn't it be 2:3, not 2:4?

Edit: perhaps that what you meant, as it is written as such in your first post.

Thanks, I was experimenting since I had a problem with ord().
RLY...?

Banana fanna fo fanna

Looks like you are using the default endian setting of the struct module, big. Try prefixing your unpack strings with '<'

topaz

Packet received:
Packet received: 5Š‡ÿPc
Packet received: ÙrD% ÅIX86ver6.mpq A=699062515 B=955808502 C=857775189 4 A=A-S B=B

Not sure why the parser passed a blank string, can anyone see why?
RLY...?

topaz

After mulling over it for a bit, I looked at how warz did it with his moderation client. The new way of handling socket data is more or less the same way he did it, but oh well. The alpha post has been updated with the revised code.
RLY...?

UserLoser

Quote from: Topaz on July 09, 2006, 12:13 AM
Packet received:
Packet received: 5Š‡ÿPc
Packet received: ÙrD% ÅIX86ver6.mpq A=699062515 B=955808502 C=857775189 4 A=A-S B=B

Not sure why the parser passed a blank string, can anyone see why?

Perhaps you received SID_NULL?

topaz

Quote from: Topaz on July 09, 2006, 12:13 AM
Packet received:
Packet received: 5Š‡ÿPc
Packet received: ÙrD% ÅIX86ver6.mpq A=699062515 B=955808502 C=857775189 4 A=A-S B=B

Not sure why the parser passed a blank string, can anyone see why?

QuotePerhaps you received SID_NULL?

It shouldn't be the first packet I receive, though.
RLY...?

warz