ICQ Protokoll "OSCAR"

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

ICQ Protokoll "OSCAR"

Beitrag von AND51 »

Hallo!
Ich möchte mich etwas mit dem ICQ Protokoll "OSCAR" beschäftigen.
Aber ich habe keine Ahnung, wie ich die Daten senen muss.
Ich weiß bisher nur, wass ich eine Verbindung zu login.icq.com:5190 öffnen muss und dann den Login durchführen muss.
Das war's aber auch schon.

Ich verstehe dieses Zahlenwirrwar nicht, warum soll ich
2A 01 13 5A 00 83 00 00 00 01 00 01 00 06 37 37 *..Z..........77
37 37 37 37 00 02 00 08 83 47 F2 B7 4E E9 A9 F6 7777.....G..N...
00 03 00 33 49 43 51 20 49 6E 63 2E 20 2D 20 50 ...3ICQ Inc. - P
72 6F 64 75 63 74 20 6F 66 20 49 43 51 20 28 54 roduct of ICQ (T
4D 29 2E 32 30 30 30 62 2E 34 2E 36 35 2E 31 2E M).2000b.4.65.1.
33 32 38 31 2E 38 35 00 16 00 02 01 0A 00 17 00 3281.85.........
02 00 04 00 18 00 02 00 41 00 19 00 02 00 01 00 ........A.......
1A 00 02 0C D1 00 14 00 04 00 00 00 55 00 0F 00 ............U...
02 65 6E 00 0E 00 02 75 73 .en....us
senden (Beispiel mit ICQNr. 777777 und passwort "password").

Kann mir das jemand genauer erklären? Wozu die ganzen zahlen da sind und wie ich Daten senden muss?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Ich habe irgendwann mal irgendwo im Forum diese Url hier aufgeschnappt:
http://iserverd.khstu.ru/oscar/

Vielleicht hilft es dir...
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Ja, genau von der URL habe ich diesen Quatsch ja.
Ich bin zwar in der 11. Klasse, also an meinem Englisch kann es nicht liegen, aber ich verstehe nicht, wie die Daten zu senden sind, beispielsweise für ein simples Login.
Wenn ich eine Verbindung zu login.icq.com:5190 öffne, und/oder etwas sende, dann erhalte ich immer nur hyroglyphische Buchstaben.

Kann mir jemand helfen? Ich erwarte an dieser Stelle kein Tutorial, sondern eher einige kleine Tipps oder kleine Codeschnipsel.

Beispiel:
DWORD.B 00 00 00 01 HELLO Always sent as the first parameter of a Channel 1 packet.
steht auf http://micq.alpha345.com/ICQ-OSCAR-Prot ... Flap1.html aber ich weiß nicht, was ich machen soll. ich habe einfach mla per Networstring die Zeichenkette (String) "00 00 00 01" an den Server gesendet, aber das bringt's nicht...
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Du darfst hier auch nicht mit Strings arbeiten. Das ICQ Protokoll ist ein
Byte Protokoll. D.h. dass dort die Befehle nicht in Form von Text stehen
sondern in Bytes.
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Sowas habe ich mir schon gedacht. Aber wie mache ich das?
Es gibt ja nur Funktionen, um Strings zu senden. Oder verstehe ich da etwas falsch?
Mag sein, dass ich den Wald vor lauter Bäumne nicht sehe, aber vielleicht bin ich zu ungeduldig. Jedenfalls wär ich dir dankbar, wenn du insofern ein paar Infos für mich auf Lager hast. Mit dem Byte-senden.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

> Oder verstehe ich da etwas falsch?
[c]SendNetworkData()[/c] ;)?
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

OK, du wirst dich vielleicht jetzt an den Kopf packen, aber trotzdem:
Soll ich dann einfach "00 00 00 01" mit SendNetworkData() verschicken?
Während ich poste, probier ich das mal aus...
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Wenn de was hast, sag mal bitte bescheid. So ein Client, der Hoax
verschickt, lässt sich sicher gut an Firmen verkaufen, die Werbung
machen wollen 8).
Bild
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

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
Vorsicht: ist noch nicht die ganze Verbindung
Zuletzt geändert von DarkDragon am 31.01.2006 17:50, insgesamt 1-mal geändert.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hallo Dark Dragon,
danke für deine Aneilnahme.

Aber dein Code funktioniert bei leider nicht:

Code: Alles auswählen

Procedure RecSNAC(Connection, FLAPSize, *Family.WORD, *Subtype.WORD, *flags.WORD, *id.LONG) 
  If Connection 
    ReceiveNetworkData() 
  EndIf 
EndProcedure 
Hier mecker der DeBagger.
und bei der funktion XOrByte(), wobei er bei jeder Zeile hinschreibt, dies sei kein gültiger Operator.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten