ラベル 解析 の投稿を表示しています。 すべての投稿を表示
ラベル 解析 の投稿を表示しています。 すべての投稿を表示

2009年5月26日

Mafia Wars: 解析 その3 (訂正、そして...)


解析シリーズ(?)の第三回目です。
今回は、初回の解析記事と前回の解析記事の訂正と、改造に関して紹介したいと思います。

初回の記事で、ゲーム上表示されないパラメータの attack, defense と attack_strength, defense_strength の説明に関して、逆に書いてしまいました。

あと、前回の記事で、V1.11 では、V1.0 にはなかったデータのやりとりがある。と書きましたが、これは間違いでした。
あの時取得したパケットは、V1.11 をインストールした直後に行われたやりとりでした。
つまり、通常やり取りしている起動時の通信は、V1.11 でも V1.0 でもほとんど変わりありません。ただニュースティッカー(動作が重い原因と疑われている、トップ画面の下の不要なニュース)だけは V1.11 から追加されたものになります。

さて、既に私を仲間に加えてくれた方はお気づきかと思いますが、一気にとんでもなくレベルが上がってしまいました...
技術的な興味からと、だんだんやることがなくなってきたので、そろそろいいかな? という気持ちから、悪魔の囁きに乗っかって、ちょっといたずらしてみた結果です。

まずは、右上のキャプチャ画面をご覧下さい。なんか普通と違いませんか?
そう、名前の後ろに数字が二つつくようになっています。これは戦闘時に重要になる、(上記で訂正した) attack, defense などのパラメータを、データを操作して名前の後ろにくっつけてみた結果です。
一つ目の数値が attack_strength と defense_strength の合算、二つ目は attack, defense の合算です。
これでパトロンがひと目でわかるようになりました。

操作できるデータは、サーバから送られてくる全てのデータになりますので、前回の解析記事の最初に列挙したデータの全てを好みの値に変更することが可能になります。

通常、この手のネットワークゲームは、データの改竄ができないようにガードをかけてあるものです。確かに Mafia Wars でも、touch からサーバに送出するデータに関してはチェックサムが付加されていて、改竄がかなり困難でした。
しかし、サーバから受信するデータに関しては何のガードもかかってないんですねぇ... これはネットワーク対応ゲームとしては致命的な気がします。
# 片側は出来てるんだから、もう片側もガードするのは大した話じゃないはずなのに...

というわけで、私が改造した仕組みを簡単に触れます。
まずは、構成ですが、

touch - proxy サーバ - 変換サーバ - オリジナルサーバ

という形で、間に二つのサーバを挟んで本物のサーバとの間に割り込みます。touch 側には proxy の設定をして、自前の proxy サーバを向くようにします。
# 実際には、二つのサーバは同じマシンで問題ありません

私の場合は、proxy サーバに delegate、変換サーバに apache を使用しました。
delegate は既に稼働中でしたし、apache も、既に動かしているサーバに virtual host 設定を追加しただけなので、一番面倒なサーバ立ち上げが省けたのはラッキーでした。
変換サーバのコンテンツは CGI だけになります。Mafia Wars では PHP をサーバに使用していましたが、個人的にあまり PHP が得意じゃなかったので、中身は Perl で書いちゃいました。
# 名前が「見習い Rubyist」なのに Perl かよ。と言われそうですが...

CGI での処理は大きく二つ。
前述の通り、touch からのデータは改竄できないので、そのままオリジナルサーバに転送する部分と、返ってきた値を(必要に応じて変換して) touch に転送する部分、になります。
サーバから送られてくるデータは JSON 形式になっていますが、JSON パッケージを使えば簡単に Perl で扱えるようになります。
# ヘッダにちゃんと text/json と書いてあったのに、データの形式が JSON であることに気づくのにだいぶかかりました。(JSON 自身も ajax にちょっと興味を示した時に見た以来で完全に忘れてました...)

例えば前述の、名前にパラメータを付加する変換は、
$res = $ua->request($req);
$dat = JSON->new->decode($res->content);
foreach $user (@{$dat->{data}->{friends}}){
$gidref = $user->{game_data}->{"gid_$gid"};
$fp = $gidref->{attack_strength}+$gidref->{defense_strength};
$ss = $gidref->{attack}+$gidref->{defense};
$gidref->{name} .= "+$fp+$ss";
$gidref->{pic_url} = "" if $gidref->{pic_url};
}
てな感じでやりました。

まぁ、簡単に書きましたが、いろいろ設定をいじったりスクリプトを書いたり、動かしてパケット見て変更してを繰り返したりして、と悪戦苦闘したので、このブログの更新も滞ってしまいました。

というわけで、全世界 2000万以上のユーザがいる人気ネットゲームの割には、見習いエンジニアが改造できてしまうくらい脆いということが露呈してしまった Mafia Wars の改造結果のご紹介でした。

2009年5月18日

Mafia Wars: 解析 その2 (V1.11)

タグに「マフィア」を追加してみたら、ゲームのタグと同数、つまり全部マフィア系ゲームの紹介だったことに今さらながら気づきました。
それ以外にもゲームはいくつか試してますが、これ程までにマフィアに傾いていたとは...

さて、今回は Mafia Wars 解析の第二弾。V1.11 での解析です。 V1.11 ってなんだ? とお思いでしょうが、これは例の 20RP 無料のアプリです。恐らく V1.1 と中身は変わらないと思います。

まず起動時のデータのやりとりですが、以下のようになっています。
  • サーバ確認
  • ユーザ情報取得*
  • チェック
  • ユーザ情報取得*
  • 仲間リスト
  • ニュースティッカー*
  • ファイトリスト
  • 戦闘結果*
  • ジョブ*
  • ニュース
  • GODFATHER*
  • アイテム*
  • 物件*
*がついているのが、V1.0 では存在しなかったデータです。
これらのデータから言える特徴は、以下の通りです。
(2009/5/22 追記)
この辺の理解が間違ってました。次回の解析あたりで訂正を含めて追加情報をお届けします。
  • 自分自身の情報を含む、大半のデータをサーバから取得
  • 隠しアイテムがある
v1.0 までは、サーバ確認の後、すぐにバージョンチェックを行っていましたが、そのまえに自分自身のユーザ情報をサーバから取得するようになっています。ここで、サーバに保持されている情報と touch に保持されている情報のマッチングを取っているのかもしれません。(cheat 防止?)

それから、アイテムや物件などの情報も、今までは(恐らく)更新があったときだけサーバから取得していましたが、毎回取るようになっています。
(2009/5/22 追記)
この辺まで理解が間違ってました。次回の解析あたりで訂正を含めて追加情報をお届けします。


アイテムや物件のデータを見ていて気づいたのが、表示されない隠しアイテムがかなりある。ということです。
物件に関しては Mafia Mike's というものが存在しています。これは、価格が 8000 で収入が 12000 という、超ウマーな物件ですが、表示されないので実際に買うことはできません。
アイテムに関しては、武器、防具、車に続く 4 番目、5 番目のカテゴリが用意されていて(データでは type=4,5)、そこに Cards, Shiv, Wiretap Device, Health Kit, Getaway Driver, Tokens, Stun Gun, Liquor といったものが用意されています。今後のバージョンアップで JOB に必要になったりするのかもしれないので楽しみに待ちましょう。

それから変わったところでは、戦闘結果というリストがサーバから渡ってきています。その内容は、戦闘後に表示される結果のメッセージと、
"fight_odds":[{
"max":5,
"odds":0.95,
"win":0.02,
"lose":0.03},
というデータで構成されるオッズ表です。恐らく戦闘結果を計算するときに倍率表として使用されるんだと思われますが、どう読み取るのかは分かりません。


さてさて、ここまで解析すると、ちょっと改造ができそうな匂いがしてきます。
私の中で、悪魔君が「へへへ、改造してお前が GOD FATHER になっちまえよ」と囁き、一方で天使が「そんなことして何になるんだい? 戦略を練る材料程度に使えばいいじゃないか」と囁いています。果たしてどちらに傾くことになるか... 乞うご期待

2009年5月13日

Mafia Wars: 解析 (全体、戦闘)

右側のタグ一覧で、仕事よりゲームが上(14vs15)に来てしまいましたが、またもや Mafia Wars ネタです。
といっても、今回はいつもの攻略とはちょっと違う視点から見てみます。

ご存知の通り、Mafia Wars はオンラインで他のユーザと仲間になったり戦ったりできます。ということはネットワーク通信して情報をやりとりしているので、それを解析することで何らかの戦略の足しにしようと思います。

解析に使う環境は、以前の RSS リーダの解析記事と同じです。ちなみに、今回解析したのは v1.0 です。

まず、通信の全体像ですが、以下に分けて説明します。
  • 起動時
  • 戦闘時
  • 仲間追加時
まず起動時ですが、6 回のデータがやりとりされます。その内容は
  • サーバ確認
  • チェック
  • ファイトリスト
  • ニュース
  • 仲間リスト
  • チェック
になります。

最初のサーバ確認は普通の GET リクエストで行われるので、普通のブラウザでもできます。
http://mafia.iphone.zynga.com/net/ping.php にアクセスすると OK と表示されると思いますが、これと同じことが行われます。(別に user-agent とかはチェックしてないようです)

ここから後は POST コマンドで実行されるので、ブラウザでは確認できません。
また、データの改竄防止用にチェックサムが付加されているので、そのアルゴリズムを解析しない限り通信をハックしての改造は難しいと思います。あしからず。

次と、最後の「チェック」は同じ内容で、gid, ipid, zid というものを送っています。
gid は恐らく mafia のグループの ID と思われます。
ipid は touch のIDそのまま( iTunes でシリアル番号だかをクリックした時に表示される 32 文字のID)。
zid は Mafia Wars での ID と思われるものです。
これを送るとサーバから以下のものが返ってきます。

{
"status":200,
"message":"OK",
"data":{
"last_purchase_level":"0",
"activity_post_freq":5,
"refresh_freq":5,
"server":{
"time":1242039257},
"versions":{
"user":1,
"jobs":5,
"items":2,
"favors":4,
"properties":4,
"fight_results":3},
"aaron_factor":1,
"setters":{
"favor_points":"120"}}}

見やすいようにインデントをつけて改行してますが、実際には1行で送られてきます。
恐らく time の値がかけ離れていると、時刻が変更されていると判断して、パラメータの回復を止める動き(オフライン時と一緒)をしてるんだと思います。
versions には、各メニューのバージョンが渡ってきているようです。例えば先日 JOB が増えましたが、これはこの項目の jobs を見て、touch 側のが古かったらサーバに取りに行って更新する、という動きをするんだと思います。
面白いのは、aaron_factor とか favor_points とかですね。何に使っているのか分かりませんが、aaron は公式フォーラムにも出てくる、作者の一人と思われる名前なので、何か秘密の機能があるのかもしれません。 favor_points は熱中度みたいな感じでしょうか? どれくらい頻繁にやってるか、とかを見ているようです。ちなみに max=120 のようです。(つまり、やりすぎ? > 俺)

この後は、ファイトリスト、ニュース、仲間リスト、を取得していますが、今回はパトロン探しにも有効な仲間リストに焦点を絞って後ほど説明します。

起動時に取得する情報は以上です。
次に戦闘時の情報ですが、実は戦闘時は通信が行われません。つまり、起動時に取得したファイトリストや仲間リストを元に全ての戦闘が行われる。ということになります。
そして、仲間追加時の通信ですが、これはいたって簡単で、入力した player id をサーバに送り、その結果が返ってくるだけです。


さて、起動時に交わされる情報の仲間リストについて解析しましょう。

仲間リストは 200 人分の my mafia の情報がリストになって(データとしては1行で)送られてきます。
一人一人について以下のパラメータが入っています。
character_id
zphone_user_id
name
cash
level
experience
energy
energy_max
stamina
stamina_max
health_max
group_size
attack
defense
favor_points
character_type
created_at
updated_at
health
fights_won
fights_lost
favor_increment
upgrade_points
upgrade_increment
group_adjust
attack_strength
defense_strength
item
200人分を受信すると書きましたが、含まれている項目の量で3種類に分けられます。
  • 項目がほとんどないメンバー
  • item がないメンバー
  • 全部あるメンバー
項目がほとんどないメンバーは、私が闇雲に登録したメンバーっぽいです。これらのメンバーは名前くらいしか項目がない状態で、my mafia のリストにも現れません。(ですので、私の my mafia のリストは 100 人ちょいです^^;)
item には、所有している武器や物件が全て記載されています。
で、200人のリストの前半の方のメンバーには item が記載されているんですが、途中からは記載されなくなっています。
この差は my mafia のリストでも分かります。よくある fight points の attack, defense ともに 0 のメンバー(このブログでパトロンと呼んでいる人)ですが、この人たちは item パラメータが送られてきていません。
つまり、このパラメータではパトロンかどうかは判断できない、ということになります。^^;

ここから分かることは、よく戦闘時の判断で、仲間の人数以上に武器を持っていても意味がない。とよく言われますが、どうも仲間の人数(group_size)は考慮してないっぽいです。
というのは、上述の通り、戦闘時に通信は行われないので、全てはこの仲間リストの情報だけで決まることになります。で、仲間リストに仲間の人数は含まれていますが、どの武器をいくつ持っているかの情報(item)が全てのメンバーに含まれているわけではないので、考慮しようがないということになります。

v1.1 から fight points が、仲間の人数で算出されるように変更になったことから考えても、恐らく仲間の人数は考慮されてないと断言しても良さそうですね。

それから気になるパラメータとしては、attack_strength, defense_strength です。これらが、あの HIDDEN と表示される secret skills になります。つまり、パケットをキャプチャすれば HIDDEN じゃなくなるってわけです。
実際の戦闘は、fight points (パラメータでは attack, defense)と、これらの attack_strength, defense_strength で判定していると思われます。
(2009/5/26 訂正)
上記の記載で、fight points と secret skills を逆に書いてしまっています。
secret skills が、自分でポイントを割り振っている attack, defense で、fight points が、レベルや所有武器等から計算され、実際の戦闘時の評価に使用される値で attack_strength, defense_strength です。

ちなみに、私のパトロンは、

"level":320,
"attack":1,
"defense":1,
"attack_strength":900,
"defense_strength":900,

となっていました。

以上、だらだらと書いてしまいましたが、とりあえず現状で分かったところをお伝えしました。
また何か分かったら書きたいと思います。

2009年1月26日

ITmedia の RSS を他のリーダで読む

ITmedia のアプリでは、iPod 向けだけに feed されている 4 つのニュースを読めるんですが、その4つ「しか」読めないという欠点があります。その基となっている RSS Probe というアプリでは、任意の RSS を登録できるので、ITmedia でも機能を制限しなければ登録ができるはずですが、あくまで ITmedia 専用なんですね。

それじゃぁ逆に、その4つのニュースを他の RSS リーダで読めるようにできれば、アプリを一本化できるだろう。ということでトライしてみました。

まずはどんなURLで feed されているかを調べます。ITmedia アプリ上では URL は確認できないので、パケットをキャプチャして調べる必要があります。無線LANルータと直接通信しちゃってる環境では、パケットをキャプチャできないので、ここで紹介したように、PC経由での環境を使用します。

パケットキャプチャに使用するPCのソフトは ethereal か wireshark ですね。今は開発が後者に移っているので、そちらの方がいいでしょう。この辺のソフトの環境設定や使い方については適当にググって頂くとして、さっそくキャプチャします。

そうすると、以下の URL にアクセスしていることが分かります。
名前から察するに、それぞれ、Apple、デジタルライフ、IT、MacWIRE に相当してるかと思います。
  • http://ipn.itmedia.co.jp/iV1/apple.xml
  • http://ipn.itmedia.co.jp/iV1/digitallife.xml
  • http://ipn.itmedia.co.jp/iV1/it.xml
  • http://ipn.itmedia.co.jp/iV1/column.xml
URL が分かってしまえば後はこっちのもんなんで、とりあえずブラウザでアクセスしてみます。すると...
なんと、http://www.itmedia.co.jp/ に転送されちゃうんです。
おっとっと、これはこれは ITmedia さん、何やらガードかけてますね。確かに他の RSS リーダで読まれちゃったら、このアプリの存在意義がなくなっちゃいますからね。

でも、ここで引き下がっちゃいけません。同じ URL を ITmedia でアクセスした場合と、RSS Probe でアクセスした場合で、比べてみます。

こちらが ITmedia (Cookie の行だけ一応内容を削除しました)

GET http://ipn.itmedia.co.jp/iV1/apple.xml HTTP/1.1
User-Agent: ITmedia/1.0.1 CFNetwork/342.1 Darwin/9.4.1
Accept: */*
Accept-Language: ja-jp
Accept-Encoding: gzip, deflate
Cookie:
Pragma: no-cache
Connection: keep-alive
Proxy-Connection: keep-alive
Host: ipn.itmedia.co.jp

こちらが RSS Probe

GET http://ipn.itmedia.co.jp/iV1/apple.xml HTTP/1.1
User-Agent: RSS%20Probe/1.0.6 CFNetwork/342.1 Darwin/9.4.1
Accept: */*
Accept-Language: ja-jp
Accept-Encoding: gzip, deflate
Pragma: no-cache
Connection: keep-alive
Proxy-Connection: keep-alive
Host: ipn.itmedia.co.jp

比べると、違いは User-Agent と Cookie の有無だけですね。試しに User-Agent を変更できるブラウザで ITmedia の User-Agent でアクセスしてみると、見事アクセス成功しました。

というわけで、一応からくりは分かりました。
でも、対策方法は難しいですね。User-Agent を変更できる RSS リーダが登場するのを待つしかなさそうです。