見出し画像

unityroomのランキングは改竄できる話

みなさーん、unityroomで楽しんでいるかな??
unityroomもランキングシステムができてずいぶん経ちました。

ところでたまにランキングで目にしないでしょうか。
到底普通に取れるとは思えない異常なスコア。 

せっかくなので解説を書こう。

■というわけで

拙作のゲームです。おもしろいからやってね。(ダイマ
このゲーム、とある週でピックアップに選ばれたんですが、明らかに1位のスコアが飛びぬけているんですよね。ということは何かしらのアレが行える可能性がある。これは試すしかない!!

というわけで友達のスーパーハッカーに検証してもらったぜ!!

■そして

できました。

これは不正です。不正!

■どういうからくり?

詳しいやり方を説明してしまうと余計にやろうとする人が増えそうなのでかいつまんで説明すると、クラシックなメモリの改竄です。具体的には、「そのときに値が明確なもの」で検索し、候補のアドレスを抽出、その値を別の値に変化させ再検索、を繰り返し最終的にその値が割り当てられているアドレスを特定し、その値を変更するという手順になります。このゲームでは収穫した作物の数(↑のSSではじゃがいも)の数が常にわかるので、そのアドレスを特定して書き換えたわけですね。

ま、結論から言えばwebGLのゲームもメモリ改竄は可能という事です。

■で、どうすんのよ

対応を考える。

◆気にしない。

ぶっちゃけこれでいいとおもいます。unityroomのスコアランキングごときにマジになってもしょうがない。気になるなら作者ページから該当のスコアを消せばいい話。あとそもそも誰がやったかが明確にわかるので、まあunityroomの管理者からすれば大体当事者が追跡可能な訳でして……。

◆それでも防ぎたい人は

つまり、どのアドレスがそれなのか特定できなくしてしまえばいいわけです。また、ユーザが任意のタイミングで変化させられる値、かつ整数型でないと難しいので、タイムアタックの時間の改竄とかはそもそも困難ですね。

どうしても画面に数字を出したく、かつそれを改竄されたくない場合は簡単な暗号化を用いるしかないでしょう。そこまでするかという気もする。


public readonly struct Score {

    private readonly int key;
    private readonly int cipher;

    private Score(int key, int cipher) {
        this.key = key;
        this.cipher = cipher;
    }

    public static implicit operator Score(int value) {
        int key = Random.Range(int.MinValue, int.MaxValue);
        return new Score(key, key ^ value);
    }

    public static implicit operator int(Score value) {
        return value.key ^ value.cipher;
    }
}

XORを用いたシンプルな暗号化の例。書いたのは某Photonのファンさん。

■まとめ

さあみんなでどんどん改竄しよう!!

嘘です。冗談です。まあunityroomの変なスコアはそういうからくりだからあまりきにせんでええよって話でした。

◆参考文献

割と具体的なやり方書いてあるなこれ 

◆定型句

当記事がいい!とおもったら
スキ!やシェアとかフォローなど、お願いいたします!!

◆謝辞

当記事はUGDGの皆さんの協力によって執筆されました。
この場を借りて感謝申し上げます。

↑UGDGについての記事はこちら。
UGDGよいとこいちどはおいで。

この記事が気に入ったらサポートをしてみませんか?