Code: Alles auswählen
Structure S_TLV
Type.w
Len.w
StructureUnion
TLV_Word.w
*TLV_Data
EndStructureUnion
EndStructure
;- Misc functions
Procedure XOrByte(sText.l, TextLen.l, Key.b)
MOV ecx, TextLen
MOV esi, sText
MOV edi, sText
CLD
Cipher:
!lodsb
XOR al, Key
!stosb
LOOP l_cipher
;MOV straddr, edx
EndProcedure
Procedure RoastPassword(*Pass, Length, *RoastArray)
Length-1
For k=0 To Length
char.l = PeekB(*Pass+k)
mod.l = (k%16)
key.b = PeekB(*RoastArray+mod)
XOrByte(*Pass+k, 1, key)
Next
EndProcedure
Procedure.w InvertWord(Word.w)
ProcedureReturn ((Word & $FF)<<8) | ((Word & $FF00)>>8)
EndProcedure
Procedure.l InvertLong(Long.l)
ProcedureReturn ((Long & $FF)<<24) | ((Long & $FF000000)>>24)
EndProcedure
Procedure SetTLVData(*TLV.S_TLV, Type.w, Len.w, *Buffer)
*TLV\Type = InvertWord(Type)
*TLV\Len = InvertWord(Len)
CopyMemory(*Buffer, *TLV+4, Len)
EndProcedure
Procedure SetTLVWord(*TLV.S_TLV, Type.w, Word.w)
*TLV\Type = InvertWord(Type)
*TLV\Len = InvertWord(2)
*TLV\TLV_Word = Word.w
EndProcedure
Procedure ReceiveFlapHeader(Connection, *channel.BYTE, *seq.WORD, *len.WORD)
t = ElapsedMilliseconds()
While byte.b <> $2A
If ElapsedMilliseconds()-t >= 3000
ProcedureReturn 0
EndIf
ReceiveNetworkData(Connection, @byte, 1)
Delay(10)
Wend
*Buffer = AllocateMemory(5)
ReceiveNetworkData(Connection, *Buffer, 5)
If *channel
*channel\b = PeekB(*Buffer)
EndIf
If *seq
*seq\w = InvertWord(PeekW(*Buffer+1))
EndIf
If *len
*len\w = InvertWord(PeekW(*Buffer+3))
EndIf
FreeMemory(*Buffer)
ProcedureReturn 1
EndProcedure
Procedure RecTLVHeader(Connection, *TLV.S_TLV)
ReceiveNetworkData(Connection, *TLV, 4)
*TLV\Type = InvertWord(*TLV\Type)
*TLV\Len = InvertWord(*TLV\Len )
ProcedureReturn *TLV
EndProcedure
;- Global functions
InitNetwork()
Procedure ICQ_Connect(Server.s, Port.l)
ConnectionID = OpenNetworkConnection(Server.s, Port)
ProcedureReturn ConnectionID
EndProcedure
Procedure ICQ_Disconnect(ConnectionID)
ProcedureReturn CloseNetworkConnection(ConnectionID)
EndProcedure
Procedure ICQ_Login(ConnectionID, UIN.s, Pass.s)
If ConnectionID
ReceiveFlapHeader(ConnectionID, @channel.b, 0, 0)
If channel = 1
*Buffer = AllocateMemory(6)
If *Buffer
Info.s = "ICQ Inc. - Product of ICQ (TM).2000b.4.65.1.3281.85"
Size = 6
Distribution_Nr.l = $55000000
PokeB(*Buffer+0, $2A)
PokeB(*Buffer+1, $01)
;Version
*Buffer = ReAllocateMemory(*Buffer, Size+4)
CopyMemory(?version, *Buffer+Size, 4) : Size + 4
;UIN
*Buffer = ReAllocateMemory(*Buffer, Size+4+Len(UIN))
SetTLVData(*Buffer+Size, $0001, Len(UIN), @UIN) : Size + 4 + Len(UIN)
;Roasted Password
RoastPassword(@Pass, Len(Pass), ?roast_array)
*Buffer = ReAllocateMemory(*Buffer, Size+4+Len(Pass))
SetTLVData(*Buffer+Size, $0002, Len(Pass), @Pass) : Size + 4 + Len(Pass)
;Client ID string
*Buffer = ReAllocateMemory(*Buffer, Size+4+Len(Info))
SetTLVData(*Buffer+Size, $0003, Len(Info), @Info) : Size+4+Len(Info)
;Client ID number
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVWord(*Buffer+Size, $0016, $010A) : Size + 6
;Client major version
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVWord(*Buffer+Size, $0017, $0004) : Size + 6
;Client minor version
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVWord(*Buffer+Size, $0018, $0041) : Size + 6
;Client lesser version
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVWord(*Buffer+Size, $0019, $0001) : Size + 6
;Client build number
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVWord(*Buffer+Size, $001A, $0CD1) : Size + 6
;Distribution number
*Buffer = ReAllocateMemory(*Buffer, Size+8)
SetTLVData(*Buffer+Size, $0014, 4, @Distribution_Nr) : Size + 8
;Client language
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVData(*Buffer+Size, $000F, $0002, @"en") : Size + 6
;Client country
*Buffer = ReAllocateMemory(*Buffer, Size+6)
SetTLVData(*Buffer+Size, $000E, $0002, @"us") : Size + 6
;Flap Header(Size)
PokeW(*Buffer+2, InvertWord($135A ))
PokeW(*Buffer+4, InvertWord(Size-6))
;Send the data
SendNetworkData(ConnectionID, *Buffer, Size)
FreeMemory(*Buffer)
Delay(10)
ReceiveFlapHeader(ConnectionID, @channel.b, 0, @len.w)
If channel = 4
RecTLVHeader(ConnectionID, @TLV.S_TLV)
If TLV\Type = $0001
ICQUin.s = Space(TLV\Len)
ReceiveNetworkData(ConnectionID, @ICQUin, TLV\Len)
If ICQUin = UIN
RecTLVHeader(ConnectionID, @TLV.S_TLV)
If TLV\Type = $0005
BOS.s = Space(TLV\Len)
ReceiveNetworkData(ConnectionID, @BOS, TLV\Len)
Host.s = StringField(BOS, 1, ":")
Port.l = Val(StringField(BOS, 2, ":"))
RecTLVHeader(ConnectionID, @TLV.S_TLV)
If TLV\Type = $0006
*Cookie = AllocateMemory(TLV\Len)
CookieSize = TLV\Len
ReceiveNetworkData(ConnectionID, *Cookie, TLV\Len)
Connection = OpenNetworkConnection(Host, Port)
If Connection
ReceiveFlapHeader(Connection, @channel.b, 0, 0)
*Buffer = AllocateMemory(6)
If *Buffer
Size = 6
PokeB(*Buffer+0, $2A)
PokeB(*Buffer+1, $01)
;Version
*Buffer = ReAllocateMemory(*Buffer, Size+4)
CopyMemory(?version, *Buffer+Size, 4) : Size + 4
;Cookie
*Buffer = ReAllocateMemory(*Buffer, Size+4+CookieSize)
SetTLVData(*Buffer+Size, $0006, CookieSize, @UIN) : Size + 4 + CookieSize
;Flap Header(Size)
PokeW(*Buffer+2, InvertWord($101F))
PokeW(*Buffer+4, InvertWord(Size-6))
;Send the data
SendNetworkData(Connection, *Buffer, Size)
ReceiveFlapHeader(Connection, @channel.b, 0, 0)
FreeMemory(*Buffer)
EndIf
EndIf
FreeMemory(*Cookie)
ProcedureReturn Connection
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
ProcedureReturn 0
EndProcedure
DataSection
version:
Data.b $00, $00, $00, $01
roast_array:
Data.b $F3, $26, $81, $C4, $39, $86, $DB, $92, $71, $A3, $B9, $E6, $53, $7A, $95, $7C
EndDataSection
;- Example
ConnectionID = ICQ_Connect("login.icq.com", 5190)
BOS_ConnectionID = ICQ_Login(ConnectionID, "77777", "test")
If BOS_ConnectionID
CloseNetworkConnection(BOS_ConnectionID)
EndIf
Delay(100)
ICQ_Disconnect(ConnectionID)
End