質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.50%

[Unity]メモリ上に置かれる変数について、改竄の対処方法が知りたい

解決済

回答 1

投稿

  • 評価
  • クリップ 14
  • VIEW 11K+

score 104

前提・実現したいこと

Unityでオンラインゲームを作っています。
こちらを参考にさせていただき、「チートでメモリのデータ書き換え」に対処する処理を実装したいと思っています。ですがチートする側についてあまりわからないので、対処方法もわからない状態です。

そこで疑問に思ったのですが、例えば下記スクリプト(Character_Status)の変数HPがチート対象にされる場合、

  1. このスクリプトをアタッチしたゲームオブジェクトがScene上にInstantiate()で生成されたと同時に、メモリ上に変数HPが割り当てられて、そのメモリの内容を見れるようになる と考えてもいいでしょうか?(内部ではnew演算子でオブジェクト用のメモリ領域をゲーム中に割り当てている?)
  2. チートへの対処に、変数HPをXOR(排他的論理和)で暗号化するクラスを実装して、暗号化してメモリ上に置いたとしても、例えばダメージ計算処理過程で瞬間的に復号した変数HPから簡単に改竄できてしまう のでしょうか?

また、メモリのデータ書き換え対処方法について他に知っておくことがあれば教えて頂けるとありがたいです
質問が纏まっていませんがよろしくお願いします

該当のソースコード

using UnityEngine;
using System.Collections;
using System;
//ステータスクラス
    public class Character_Status
    {
    public int HP;
    }

//変数をXOR(排他的論理和)で暗号・復号化するクラス
public class Encrypt {
    const int Key = 0x111;
    int value;    //実際にメモリに置かれる値

    //暗号化
    public void setvalue(int HP)
    {
        value = HP ^ Key;
    }

    //復号化
    public int get_value()
    {
        return value ^ Key;
    }
}

補足情報(言語/FW/ツール等のバージョンなど)

Unity5.3.5f(64bit)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+8

 TL;DR

チート対策にリソースをつぎ込むとイタチゴッコなので青天井となります。
餅は餅屋ということでマネーパワーを使い、専門の業者に依頼しましょう。

 質問への回答

①その通りです。見ることが可能です。

②結論からすると改ざん可能です。
「瞬間的な複合」といったタイミングを狙う必要はありません。
HPに関するメモリ上の値がどのように変化しているか、ブレークポイントを設置してトレースすることが可能です。
簡単な手順としては以下のとおりです。

  1. チート対象のアプリにアタッチする
  2. 対象アプリが利用しているメモリのすべてのメモリに対してサーチをかけて絞り込む。
  3. HPと思われるメモリにブレークポイントを設置する。
    (指定したメモリ番地がReadされたとき、Writeされた時など色々ブレークポイントの設定の仕方があります。)
  4. ゲーム内でHPが変化したときにブレークするので、おのずと暗号化部分の処理が丸見えとなります。
    (アセンブリが丸見えになります。)

 対策するには、ある程度「やり方」を知る必要があります…

 Unityについて

Unityは残念なことにデフォルトの状態では非常に脆いです。
試しに何かAPKを作成し、自分で見るのが分かりやすいです。

  1. Androidであればjp.co.game_title.apkといったアプリのパッケージの拡張子をzipに変更します。
  2. assets/bin/Data/Managed/Assembly/Assembly-CSharp.dllILSpy等で開いてください。
  3. すべてのプログラムをほぼ元のコードに近い形で見ることが可能です。
    もちろんILそのものを書き換えるという改ざん方法もあります。
    今回の場合であればHPのsetterでの処理をコメントアウトしてしまえば、HPは一切変化しなくなります。

また、AESなどで暗号化していてもこのような手法でkeyivが丸見えといったケースも少なくありません。

この件についてはIL2CPPを利用し、生成するものをILからネイティブにすることで少しマシになります。
(高級言語としては見えず、アセンブリを見る形になります。
チートするまでにかかる労力が大きくなり諦める人も出てくるはずです。)

 Pokemon GOの事例

有名タイトルであるPokemon GOもご存知かもしれませんがUnity製アプリです。
リリース当初はハックされ、RPCのAPIをそのまま実装したBOTやマップサイトによりサーバーが何度も不安定になるなど、荒れていました。BOTにより量産されたアカウントのRMTも非常に目立っていました。

ですが、(名前を忘れましたが)専門の業者のプロテクト(packer)の導入に加え、
ハッシュチェックを厳密にしたり、SafetyNetを導入したところ、
全世界で全てのBOTやマップサービスが停止しました。
理由はデバッガでの静的解析が困難になった為です。
(かなり高度な知識を持つ海外の人によって最近破られてしまいましたが…)
高級なプロテクトはメモリ上に自身のコードを全て展開しない為、
メモリダンプ等による元のアセンブリの復元が不可能です。

 おすすめのスライド

現在売り上げランキング1位の有名なゲームである「モンスターストライク」の中の人が書いたスライドがあるので、
こちらもぜひ読んでみてください。
(モンスターストライクのゲームエンジンがcocos2dなので今回の質問のUnityとは違いますが…)
http://www.slideshare.net/ssuser8200d3/ss-59926328

こちらはパズドラだと思います
http://www.slideshare.net/kumin1030/cocos2dx-40930112

 おすすめの資料

セキュリティエンジニアからみたUnityのこと
https://engineering.linecorp.com/ja/blog/detail/110

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/03 21:55

    詳細な回答ありがとうございます!
    IL2CPPの利用が対処になるとは知りませんでした。この方法と事例のSafetyNetを検討してみます。
    メモリデータのxor暗号・復号化についてですが、結果的に解析されるとなるとこの暗号化は気休め程度の対処であり、何もしないよりマシ というものなのでしょうか?

    キャンセル

  • 2016/11/04 00:39 編集

    無いよりもマシです。
    知識がない人にとってはXORだけでもサーチが簡単にできなくなるので、
    チートが不可能だと思い込みます。

    チートを防ぎたい場合は、
    何か特別な問題がない限り実装しておいたほうがいいと思います。

    XORをしておけば、
    メモリエディタで簡単にサーチできてしまうレベルから、
    「少し工夫をしないといけなくなる」というレベルに変化します。

    「どういう工夫が必要か」というのに気付ける人もいれば、気づけない人も居ます。
    気づけない人はそこで脱落です。その時点でXORの意味があります。

    また、その工夫に気づける人でもチートをするまでに必要な工程などを考えると、
    「労力」と「チートによって得られる効果」が見合ってない場合は大抵諦めます。

    ※keyが何でXORされているのかを探るのは、
    デバッガをアタッチしてブレークポイントを設置して処理を見れば簡単にわかりますが、
    デバッガ対策や静的解析などを対策している場合は相当な労力が必要になってきます。

    ただし、最終的に高度な知識を持つ人間にターゲットにされてしまうとどうしようもないです。

    ちなみに、XORですとパフォーマンスに大きく影響しないので実装しておいて問題ありません。

    キャンセル

  • 2016/11/04 10:38

    マシと聞いて少し安心しました。XORの処理も入れてみたいと思います!
    ご丁寧に回答していただき有難うございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る