2009年7月20日 星期一

Yahoo即時通的通訊協定 YMSG Protocol

YAHOO即時通的通訊協定叫做YMSG,會用Wireshark的人可以找找看。
...寫YAHOO機器人的時候,很想抱怨,
怎麼都沒半篇"中文"的文章介紹YMSG呢?
我這裡簡單介紹一下好了(雖然說我很不會介紹東西)。
<正文開始>
I.幾乎即時通每個封包(不管是送出去還是丟進來)都有以下格式:
※備註:以下標示的陣列全都是byte陣列
YMSG封包的內容依序是:
  1. 開頭都是YMSG, 以陣列表示是 {'Y','M','S','G'},
    轉成十六進制就是 0x59 0x4D 0x53 0x47 [共佔4個位元組]
  2. 接下來是版本號{0,16} [共佔2個位元組]
  3. 然後是兩個0 {0,0} [共佔2個位元組]
  4. 接著是以Short表示的"Yahoo Data"(後面會提)的長度 [共佔2個位元組]
  5. 以Short表示的Service常數 [共佔2個位元組]
  6. 以Int 32表示的Status常數 [共佔4個位元組]
  7. 以Int 32表示的SessionID [共佔4個位元組]
  8. 最後就是"Yahoo Data" [不定]
II.YahooData的組成
 Yahoo Data基本上是用字串表示的,而資料則是用Key跟Value的方法表示,並用{0xc0 , 0x80}兩個連續位元分隔。
 舉個例比較明白(以".."暫時表示0xc0跟0x80),例如傳送聊天訊息的封包裡面的DATA就像這樣:"0..twlupus..1..twlupus..5..nickwinwin..14..Hello world.."。這個DATA可以看成是:
  • [0]twlupus
  • [1]twlupus
  • [5]nickwinwin
  • [14]Hello world
 組合而成的。
 然而有時候key會重複,這點需要注意=ˇ=,結尾時也要放0xC0,0x80喔
III.登入與驗證
 YMSG能拿來幹嘛?當然是拿來模擬即時通啦!要模擬即時通,當然要先學會登入。
 登入的動作分為:
  1. Client->Server
    [封包內容]YMSG參數:Service=SERVICE_AUTH , Status=99 , SessionID=0
    Yahoo Data(請參考第二部份轉換):[1]你的帳號
    你或許會有疑問,封包要傳到哪去?我個人是連線到76.13.15.41:5050
  2. Server->Client
  3. 這裡"讀到"的SessionID要在後面用到,請記得取出。
    [封包內容]Yahoo Data:[94]神秘驗證碼
  4. 下載1網頁"https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=" + 你的帳號 + "&passwd=" + 你的密碼 + "&chal=" + 神秘驗證碼

  5. 第3步取得的網頁內容,如果密碼正確的話,網頁內容會像是"0\r\nymsgr=XXXXXXXXXXXXX",取出ymsgr

  6. 下載第2個網頁"https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=" + ymsgr

  7. 同第3步,但這次不是從內容中取出ymsgr而是crumb

  8. 對「crumb+""+神秘驗證碼」進行MD5加密取得byte陣列

  9. 然後用Base64加密byte陣列,並用分別用".", "_", "-"取代"+", "/", "=",加密後的字串我稱之為AUTHCODE

  10. 第5步的網頁中還有兩個資料,分別是Y跟T,也請取出

  11. Client->Server
    [封包內容]YMSG參數:Service=SERVICE_AUTHRESP , Status=99 , SessionID
    Yahoo Data:[0]你的帳號[1]你的帳號[277]Y的資料[278]T的資料 [307]AUTHCODE的資料[244]2097087[2]你的帳號

  12. 如果以上無誤,應該已經正確登入了

  13. (顯示上線)這裡應該在登入後暫停個一秒左右才進行動作。

  14. Client->Server
    [封包內容]YMSG參數:Service=198 , Status=0 , SessionID
    Yahoo Data:[10]99[19]狀態訊息[97]1
  15. 恭喜你,如果你看懂的話你現在應該是登入的了

IV.發送訊息和接收訊息

     
  1. 發送部分:
    Client->Server
    [封包內容]YMSG參數:Service=SERVICE_MESSAGE , Status=0 , SessionID
    Yahoo Data:[0]你的帳號[1]你的帳號[5]對方帳號[14]訊息

  2.  
  3. 接收部分:
    Server->Client
    [封包內容]YMSG參數:Service=SERVICE_MESSAGE , Status=0 , SessionID
    Yahoo Data:[4]對方帳號[14]訊息


V.附錄

    C#在登錄與驗證那邊,實作7、8步的方法:
    //要記得using System.Security.Cryptography;
    private string GetAuthCode(string Crumb, string Challenge) {//Challenge就是神祕驗證碼
    string Crypt = string.Join(string.Empty, new string[] { Crumb, Challenge });
    byte[] Hash = HashAlgorithm.Create("MD5").ComputeHash(Encoding.Default.GetBytes(Crypt));
    string Auth =
    Convert.ToBase64String(Hash).Replace("+", ".").Replace("/", "_").Replace("=", "-");
    return Auth;
    }
    好啦,剩下是商業機密XDD,可以自己爬英文文章或者爬點PIDGIN的原始檔也不錯。

2009年7月6日 星期一

C# 腳本直譯器

腦袋沒動會生鏽,
以前就曾想自己寫一個腳本執行器看看,昨天就用C#寫了個非常陽春的版本。

程式碼在gitHub

範例程式下載

陽春是沒辦法的ˊˇˋ 畢竟只用了數小時=口=++
一般來講C#可以直接用內建的CodeDom庫去編譯腳本(如果沒特殊需要真的就用CodeDom就好),但這裡我用的是自己寫的直譯器。


這個直譯器可以用的邏輯式有:
for(i=0;i<5;i=i+1){
}
while(i<5){
}
if(i>=6){
}
之類的(sorry沒有else),全部都要按照格式一步一步來(沒時間寫偽編譯啊)
變數不用宣告,宣告陣列只需要 "陣列名稱=[];"
嗯,差不多就是這樣了

如果糟糕的程式碼很榮幸的被用到您的程式上,希望但不強制您放上本站的網址xDD