Seite 1 von 3

ICQ Protokoll "OSCAR"

Verfasst: 30.01.2006 22:31
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?

Verfasst: 30.01.2006 23:36
von MVXA
Ich habe irgendwann mal irgendwo im Forum diese Url hier aufgeschnappt:
http://iserverd.khstu.ru/oscar/

Vielleicht hilft es dir...

Verfasst: 30.01.2006 23:47
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...

Verfasst: 30.01.2006 23:50
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.

Verfasst: 30.01.2006 23:52
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.

Verfasst: 31.01.2006 00:01
von MVXA
> Oder verstehe ich da etwas falsch?
[c]SendNetworkData()[/c] ;)?

Verfasst: 31.01.2006 00:03
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...

Verfasst: 31.01.2006 02:35
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).

Verfasst: 31.01.2006 07:02
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

Verfasst: 31.01.2006 09:12
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.