HttpClient を使って建造送信を偽装する

このエントリーをはてなブックマークに追加

HttpClient を使って、艦これの「建造」を偽装してみます。画面的には「工廠」のところから、ぽちぽちと燃料や弾薬を設定するのですが、これを一発で設定して建造まで行かせます。マクロを作る気はないので、送信の偽装部分の試してみましょう、ということで。

■送信にトークンが必要

建造の通信は、POST通信を使って行われています。Cookieを使わず、単純なトークンのやり取りでログインチェックをしているようなので、なんらかの形でトークンが取れれば、別のツールから送信することが可能です。現在のトークン自体は、FeddlerCore でトラップすれば OK です。
送信データは、以下のようにフォーム型です。

api%5Fitem4=30&api%5Fitem3=500&api%5Fitem2=251&api%5Fitem1=200&api%5Fkdock%5Fid=1&api%5Fhighspeed=0&api%5Fverno=1&api%5Ftoken=e41e63da9c8985ec5a319c065fdb0d3be30f34f7

これを適当に分解してクラスを作っておきます。

public class Kenso 
{
    public int nenryo { get; set; }
    public int danyaku { get; set; }
    public int kouzai { get; set; }
    public int baux { get; set; }
    public int dock { get; set; }
    public bool speed { get; set; }
    public string token { get; set; }
    public string ToContent()
    {
        /*
            * api%5Fitem4=30&      // ボーキサイト
            * api%5Fitem3=500&     // 鋼材
            * api%5Fitem2=251&     // 弾薬
            * api%5Fitem1=200&     // 燃料
            * api%5Fkdock%5Fid=1&  // 建造ドック
            * api%5Fhighspeed=0&   // 高速化 0:なし 
            * api%5Fverno=1&       // バージョン
            * api%5Ftoken=e41e63da9c8985ec5a319c065fdb0d3be30f34f7
            */
        string body = "";
        body += string.Format("api%5Fitem1={0}&", nenryo);
        body += string.Format("api%5Fitem2={0}&", danyaku);
        body += string.Format("api%5Fitem3={0}&", kouzai);
        body += string.Format("api%5Fitem4={0}&", baux);
        body += string.Format("api%5Fkdock%5Fid={0}&", dock);
        body += string.Format("api%5Fhighspeed={0}&", speed? "1":"0");
        body += string.Format("api%5Fverno={0}&", 1);
        body += string.Format("api%5Ftoken={0}", token);
        return body;
    }
}

艦これに接続している間はトークンは一定なので、なんらかの形でトークンが取得できれば、それを使いまわせます。

■PostAsyncの内容を偽装する

private async void button1_Click(object sender, EventArgs e)
{
    var kn = new Kenso()
    {
        nenryo = int.Parse(textBox2.Text),
        danyaku = int.Parse(textBox3.Text),
        kouzai = int.Parse(textBox4.Text),
        baux = int.Parse(textBox5.Text),
        dock = 1,
        speed = false,
        token = _token
    };

    var cl = new HttpClient();
    var url = "http://" + _HOST + "/kcsapi/api_req_kousyou/createship";
    var s = kn.ToContent();
    var cont = new StringContent(s);
    cl.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0");
    cl.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    cl.DefaultRequestHeaders.Add("Accept-Language", "ja,en-us;q=0.7,en;q=0.3");
    cl.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
    cl.DefaultRequestHeaders.Add("Referer", "http://" + _HOST + "/kcs/port.swf?version=1.4.0");
    cont.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
    cont.Headers.ContentLength = s.Length;
    var res = await cl.PostAsync(url, cont);
    MessageBox.Show("建造を開始しました");
}

POST するデータを作った後は、HttpClient を使って送信します。コンテンツ部分は、StringContentを使って HttpContent オブジェクトを作ります。ヘッダ部の偽装はできるだけ行っていますが、こんなにやる必要はないかもしれまん。これはターゲットにするサーバーによりけりですね。
あと、Content-Type を変更しないといけないのですが、これが曲者でした。どうやら、ContentType プロパティに MediaTypeHeaderValue オブジェクトで設定しないといけないようです。DefaultRequestHeaders や、Headers に Add すると実行時にエラーがでます。また、User-Agent の場合は、Headers に対して設定すると実行エラーになります。このあたり、stack overflow でも間違った回答がついているので注意が必要です。

■これで建造はできます

無事、建造はできているようなのですが、いくつか問題点あります。

  • 建造の設定後、成功のレスポンスを受け取ってやる必要がある。
  • 建造の後に、通常はクライアントからいくつかのリクエストを送っているが、これのは場合はしていない。
  • 艦娘が収容量いっぱいでも、建造できてしまう。

あらかじめ、わかっている建造レシピをプリセットして、投入するのは可能なのですが...まあ、そのあたりは少しずつ。ちなみに、これはデスクトップアプリから試していますが、トークンさえわかってしまえば、他のアプリでも可能なので、ストアアプリとか iPhone からも建造が可能ですね。今度、ストアアプリで試してみましょう。

カテゴリー: 雑談   パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">