注意!

このページに含まれる情報は直ちに悪用されうるものではありませんが
使い方によっては所謂チート行為等迷惑行為に繋がる恐れがあります。
そういった使い方をして発生した問題に対して当方では責任を負いかねます。

このページで目指すのは通常個別に探すしかないデータのアドレスを
効率よく発見するためのものに過ぎません。


手っ取り早くボイスが聞きたい方はコチラ

経緯

2016年2月11日以降

艦これのボイスデータの配置は従来のような単純に推測されるようなものではなく
6桁の一見ランダムな数値を使ってアクセスするようになりました。
これによってWEB上で艦これのボイスを聞くことができるようなサービスが
相次いで対応を中止したようです。

艦これのゲーム中の通信を見ればわかるように一見ランダムに見えるアドレスは
ゲーム起動時にロードされる
apt_start2
に含まれている情報からゲーム内で何らかの処理を行って生成していることは明らかです。
さらに、その"何らかの処理"は Core.swf で行っていることもほぼ明らかです。

というのはゲームサービス開始後しばらくは、艦これのゲームデータは全く暗号化や
難読化といった手段を講じておらず、古いデータを使えば Core.swf 内で
旧来の単純なアドレスを生成している getVoiceURL()関数を確認することができました。

よって

apt_star2に含まれる艦娘のデータ

Core.swfで処理

アドレス生成

という手順を踏んでいるわけです。
この内 apt_star2 のデータは以前から解析が進んでいますので
現行の暗号化されたCore.swfをなんとかして展開して内容をみることができれば
自ずとボイスのアドレスも求めることができることになります。

Core.swfの解読

というわけで、早速 Core.swfの展開にかかったわけですが、
これが結構骨の折れる作業です。

艦これを起動するとまず MainD2.swf というデータが読み込まれます。
表示的には"ぷかぷか丸"が表示されている段階です。

このMainD2はCore.swf をサーバーからダウンロードし、暗号化を解除、
ゲーム本体である Core.swf を読み込む仕組みになっています。

よって、Core.swf を展開するための作戦は大きく2つです。

  • 先にMainD2を調べてCore.swfの復号の仕方を解明する
  • MainD2にCore.swfを読み込ませ復号された段階でメモリをダンプし、復号済みCore.swfを発見する

まず、MainD2を解読する方法ですが、これはかなり困難です。
MainD2自体ははじめに読み込まれるデータなので暗号化などはされておらず
簡単にコードを見ることはできます。ただし、コードが難読化されています。

Flashゲームのロジックを記述するために
使われている ActionScriptは名前の通りスクリプト言語なので、
無理やり難読化することが簡単にできてしまいます。
また、ActionScriptの逆コンパイラは万能ではないので結構間違ったコードが
出力されてしまいます。
これらを考えるとこの難読化を解除することは不可能ではないのですが
かなりの時間がかかるという結論になります。
(のちに解読に成功します -> 別記事で解説)

というわけで、一度切りの解析であれば2つめのメモリから復号済みCore.swfを
抜き出す方法が現実的には簡単です。

メモリ抽出の手順

Windowsでは、それらしいデバッガやメモリエディタを用意
Linux等では gdb が使用できます。

まず Chromeならchrome://memory LinuxでFirefoxなら

 $ps -al | grep plugin_container

などを実行して動作中の艦これのプロセスIDを確認します。

確認したプロセスのメモリをダンプします。
Windowsでは使用しているメモリエディタ等のメモリダンプ機能を使用します。
Linuxのgdbでは

$sudo gdb
gdb> attach (プロセスID)
gdb> gcore out.bin
gdb> detach

こんな感じでメモリのダンプデータ(out.bin) が取得できます。

ダンプできたらこれを任意のバイナリエディタで開き
暗号化されていないswfデータのヘッダである
"FWS." を意味する "4657531D" から始まる部分を見つけます。

そこから約 200KB のデータがメモリ上に展開されたCore.swf です
該当部分を別のデータとして保存すれば摘出完了です。

摘出後

Core.swfの摘出を乗り越えればほぼ難しい部分は完了です。
JPEXSなどのFlashデコンパイラか
Windows環境ではhugflashのモードをHugDimentionにして
読みこませれば Core.swfを動かしているActionScriptを
読むことができます。

コードが出力されたら getVoiceURL という関数を探してください。
これが目指していた処理です。

getVoiceURL

以上の工程で判明した getVoiceURL() の処理が以下の通りです。

 public static function getVoiceURL(charaID:int, voiceID:int):String
{   
    var var3:String = null;
    var var8:int = 0;
    var var6:String = null;
    var var4:String = SettingFacade.URLROOT_SOUND;
    var var7:String = DataFacade.getServerConstData().voice_server;

    if(var7 != "") var4 = ("http://" + var7 + "/kcs/sound/");
    var var5:int = createFileName(charaID, voiceID);

    if((SettingFacade.IGNORE_SHIP_FILENAME == true) || (charaID == 9998) || (charaID == 9999)) return (var4 + "kc" + charaID + "/" + var5 + ".mp3");

    var3 = DataFacade.getStartData().getShipFileName(charaID);
    var8 = DataFacade.getStartData().getShipVersion(charaID);
    var6 = "";

    if(var8 > 1) var6 = ("?version=" + var8);

    return (var4 + "kc" + var3 + "/" + var5 + ".mp3" + var6);
}

ほとんどの処理が従来の処理と変わりません。
getVoiceURLは 2つの値 charaID と voiceID を受け取り
その値からボイスデータのある アドレスを作るようになっています。
charaIDは艦娘のIDで例えば 睦月なら1 長門なら80 といったように
api_start2へのレスポンスに記述されています。
VoiceIDは 挨拶なら1 のように発言の種類ごとに決められた値です。

SettingFacadeやDataFacadeはゲームスタート時にサーバーのアドレスや艦娘のデータなど
各種設定やデータを一纏めにしたものです。

重要なのは

 var var5:int = createFileName(charaID, voiceID);

この部分です。ここで例の6桁の数値を生成しています。

createFileName() は

 public static function createFileName(sid:int, vid:int):int
{
    if(SettingFacade.IGNORE_SHIP_FILENAME == true) return vid;
    var var3:int = vid;

    if((vid <= 53) && (sid <= 500)) hug3 = (((((sid + 7) * 17) * (vcKey[vid] - vcKey[vid - 1])) % 0x00018365) + 0x000186A0);

    return var3;
}

このようになっています。
vcKey というボイスURL用のキーを用いて6桁の数値を算出します。
vcKeyもCore.swf内に記述してあり、ここを変化させるとアドレスの値も変わる仕組みです。
(ここには掲載しません)

以上で艦これのボイス算出が仕組みが判明しました。

結果

ボイスのアドレスは

kc[艦娘path]/[計算値D].mp3
D =(((((sid + 7) 17) (vcKey[vid] - vcKey[vid - 1])) % 0x18365) + 0x186A0);
path = 艦娘のpathname(参照)

ex) Zara(sid=448)の自己紹介(vid=1)なら

D=(((((448 + 7) 17) (vcKey[1] - vcKey[0])) % 0x18365) + 0x186A0);
= (((((448 + 7) 17) (0x****1 - 0x****6)) % 0x18365) + 0x186A0);
= 103736

/kcs/sound/kcspmuptretooz/103736.mp3

と行った風にボイスアドレスが簡単に算出できるようになります。

こちらで実際にボイスURLを生成する実験ができます。

コメントを追加する