取出Gamania P2P 遊戲下載器種子檔?

玩楓之谷的人都知道,官方下載遊戲有兩種方式,一是直接下載,另一種就是用P2P下載器。
偶爾會用BT的我好奇,能不能夠把P2P下載器中的種子檔(.torrent)取出來,用習慣的Client來下載?

在開始之前,我已閱讀並同意「遊戲橘子點對點檔案下載服務合約書」,並在此聲明,本文僅作為學術研究一用,僅以探討點對點通訊的運作方式為基礎,在無任何對「遊戲橘子點對點檔案下載」軟體進行破解、破壞、修改或逆向工程,無任何干擾其他使用者正常使
用該服務之行為的規範下作學術研究之分享。「遊戲橘子點對點檔案下載軟體」及「遊戲橘子」商標為「遊戲橘子數位科技股份有限公司」所有。

當我們在下載BT時,Client會定時向tracker發出請求,以取得使用者列表、peer數量、seed數量等重要資訊,有這些資訊才得以與他人進行P2P點對點通訊。而發出請求最常見就是HTTP Get方式,因此我們可以先分析request header中的各項參數。


由這張圖上可發現,這是很常見的BitTorrent request,其中Get parameter中有幾項是我們感興趣的:

NAME DESC
info_hash .torrent檔案中info部分的SHA-1校驗值,共20 Bytes。Tracker就是藉由它來辨識種子。
peer_id 由Client產生的辨識ID,透過它可以得知使用的Client。
port 監聽的埠。
uploaded 已上傳的大小。
downloaded 已下載的大小。
left 剩餘的大小。

而只要有info_hash就能夠產生一個magnet連結,讓支援magnet的client直接從DHT中抓取種子檔案。
一個簡單的磁力連結格式是:

magnet:?xt=urn:btih:INFO_HASH&tr=TRACKER_URL

要填入正確格式的INFO_HASH必須先將info_hash解碼,其是在這裡只是很簡單的轉換成HEX而已。

J%07%d4%a1%a8%0d%15N%d80%d2%8e%10p%02%93%1fY%dah

先在%??左右插入空格。

J %07 %d4 %a1 %a8 %0d %15 N %d8 0 %d2 %8e %10 p %02 %93 %1f Y %da h

然後將非%??用以ASCII轉換成HEX。

`4A` %07 %d4 %a1 %a8 %0d %15 `4E` %d8 `30` %d2 %8e %10 `70` %02 %93 %1f `59` %da `68`

再把所有的非HEX字元移除。

4A07d4a1a80d154Ed830d28e107002931f59da68

大小寫一致化。

4a07d4a1a80d154ed830d28e107002931f59da68

如此一來,INFO_HASH就完成了。

我們來試試產生的magnet能不能正常使用:

magnet:?xt=urn:btih:4a07d4a1a80d154ed830d28e107002931f59da68&tr=http%3A%2F%2F210.208.86.28%2Fkawa2%2Fannounce


Tracker傳回有效,而且看得其他seed,說明了這個hash是有效的。
不過,client卻無法抓取torrent的其他資訊,連檔案清單也是空白的,因為這個種子不在DHT上。

這下子就必須分析下載器,看看能不能從memory中找到一些蛛絲馬跡。
不過在這之前,還得先做好功課,認識一下torrent檔案的格式。
Torrent檔案的內容用的是Bencode邊碼,同時也是 BitTorrent 用在傳輸資料結構的編碼方式
由四種型態就足以構成一個正確且有效的torrent檔案,分別為integer(I)、byte string(S)、list of values(L)、dictionary(D)。
詳細的資料結構、組成方式,請大家自行Google,很多文章都講解得很詳細,因此在這裡就不再重覆說明。

有了對torrent檔案格式的基本概念後,我們就能找找是否有一個torrent檔藏在memory中。
我們必須選用一個較少重覆且必須存在的一個關鍵字來搜尋,piece length十分勝任。
在CE中搜尋字串piece length,並瀏覽該處記憶體區域。


結果十分令人滿意,這是Bencode的邊碼格式。稍微往上瀏覽就能發現一個torrent檔的info。


找到6:pieces615640:,可以得知從最後的:往後615640 Bytes共有615640/20 = 30782個分塊的SHA-1校驗值。
計算一下pieces結束的位址在哪:

02A601D6 + 964D8(615640的16進制表示) = 02AF66AE


確實在這位址之後一項資料就結束了。
我們把02A60020 ~ 02AF66BB這段memory保存起來,檢查一下它的SHA-1校驗值。

SHA-1: 4A07D4A1A80D154ED830D28E107002931F59DA68

發現了這段memory的HASH和info_hash是一樣的!

然而我們把它的附檔名直接改成.torrent並開啟卻出現Invalid torrent file!的錯誤訊息。

怎麼辦?
記得我們剛剛發現memory的HASH和info_hash是一樣的,但如果你隨便下載一個種子檔,然後用Client去取得它的magnet連結,你會發現,種子的HASH和magnet的INFO_HASH是不同的!
也就是說,magnet的INFO_HASH並不是整個種子的SHA-1值,而是只有info段的HASH,而目前的資料也都是屬於info段內的資料,缺少了info標記才是造成種子檔案錯誤的原因‧

而種子除了要有info外,缺少了tracker的announce資料也會無法進行點對點傳輸,所以我們用HEX編輯器來完善torrent檔。
我們在檔案開頭插入一個dictionary,包含tracker資訊和整個info

d8:announce36:http://210.208.86.28/kawa2/announce/4:info

並在檔案結尾插入e來把dictionary關閉

e

保存檔案,載入到Client,成功!


可以正常下載,看得到peer清單、Client以及對方速率。

本文僅作為學術研究之用,讀者因自身行為而違反「遊戲橘子點對點檔案下載服務合約書」者,一切責任皆請自行負責。