...寫YAHOO機器人的時候,很想抱怨,
怎麼都沒半篇"中文"的文章介紹YMSG呢?
我這裡簡單介紹一下好了(雖然說我很不會介紹東西)。
<正文開始>
I.幾乎即時通每個封包(不管是送出去還是丟進來)都有以下格式:
※備註:以下標示的陣列全都是byte陣列
YMSG封包的內容依序是:
- 開頭都是YMSG, 以陣列表示是 {'Y','M','S','G'},
轉成十六進制就是 0x59 0x4D 0x53 0x47 [共佔4個位元組] - 接下來是版本號{0,16} [共佔2個位元組]
- 然後是兩個0 {0,0} [共佔2個位元組]
- 接著是以Short表示的"Yahoo Data"(後面會提)的長度 [共佔2個位元組]
- 以Short表示的Service常數 [共佔2個位元組]
- 以Int 32表示的Status常數 [共佔4個位元組]
- 以Int 32表示的SessionID [共佔4個位元組]
- 最後就是"Yahoo Data" [不定]
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能拿來幹嘛?當然是拿來模擬即時通啦!要模擬即時通,當然要先學會登入。
登入的動作分為:
- Client->Server
[封包內容]YMSG參數:Service=SERVICE_AUTH , Status=99 , SessionID=0
Yahoo Data(請參考第二部份轉換):[1]你的帳號
你或許會有疑問,封包要傳到哪去?我個人是連線到76.13.15.41:5050 - Server->Client
- 下載1網頁"https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=" + 你的帳號 + "&passwd=" + 你的密碼 + "&chal=" + 神秘驗證碼
- 第3步取得的網頁內容,如果密碼正確的話,網頁內容會像是"0\r\nymsgr=XXXXXXXXXXXXX",取出ymsgr
- 下載第2個網頁"https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=" + ymsgr
- 同第3步,但這次不是從內容中取出ymsgr而是crumb
- 對「crumb+""+神秘驗證碼」進行MD5加密取得byte陣列
- 然後用Base64加密byte陣列,並用分別用".", "_", "-"取代"+", "/", "=",加密後的字串我稱之為AUTHCODE
- 第5步的網頁中還有兩個資料,分別是Y跟T,也請取出
- Client->Server
[封包內容]YMSG參數:Service=SERVICE_AUTHRESP , Status=99 , SessionID
Yahoo Data:[0]你的帳號[1]你的帳號[277]Y的資料[278]T的資料 [307]AUTHCODE的資料[244]2097087[2]你的帳號 - 如果以上無誤,應該已經正確登入了
- (顯示上線)這裡應該在登入後暫停個一秒左右才進行動作。
- 恭喜你,如果你看懂的話你現在應該是登入的了
[封包內容]Yahoo Data:[94]神秘驗證碼
Client->Server
[封包內容]YMSG參數:Service=198 , Status=0 , SessionID
Yahoo Data:[10]99[19]狀態訊息[97]1
IV.發送訊息和接收訊息
- 發送部分:
Client->Server
[封包內容]YMSG參數:Service=SERVICE_MESSAGE , Status=0 , SessionID
Yahoo Data:[0]你的帳號[1]你的帳號[5]對方帳號[14]訊息 - 接收部分:
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的原始檔也不錯。
