Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

入門! チートの解剖学 ~セキュアプログラミングでゲームのチートは防げるのか? ~

  • LINEで送る
  • このエントリーをはてなブックマークに追加

 ゲームのチート対策について、技術的に見るとチートとはどういった行為であるのかを解説し、チート対策の原理や仕組みを解説します。Webアプリケーション開発におけるセキュアプログラミング等とは大きく異なるチート対策に特有のポイントを挙げ、同じく「セキュリティ」と呼ばれるものでも両者は大きく異なる技術分野であることを見ていきます。チートの多くは技術的にはそれほど難しいことをしているわけではなくチートの被害はいつでも発生しうるのだということ点を実感していただくために、Unityで作成したAndroidアプリに含まれる中間言語コードを改変する様子も紹介しています。

目次

はじめに

 情報システムが生活に欠かせないインフラとなった昨今、その開発と運用に携わるエンジニアの間にはセキュリティの意識が深く浸透しています。ソフトウェア開発の現在のメインストリームといえるWebアプリケーション開発の分野では、不特定多数のユーザーに公開されるサービスを開発することから、セキュリティへの意識が高くなっていると言えます。Webアプリケーション開発のセキュリティについては、規範となる対策方針が業界全体として整備され、入門者向けの解説資料も充実しているなど、ソフトウェア開発の他の分野に比べても一歩先を行っていると言えます。

 セキュリティに関しては他に組み込みソフトウェア開発でも強く意識されますが、これ以外の分野では「セキュアプログラミング」といえばWebアプリケーション開発におけるセキュアプログラミングのことが意識されるのも無理のないことといえるでしょう。

 しかしながら、Webアプリケーション開発だけがソフトウェア開発というわけではありません。セキュリティを考える際には何を・何から・なぜ守るのかをポリシーとして明確にすることが大前提となり、開発するソフトウェアが異なればセキュリティポリシーも異なります。Webアプリケーション開発におけるセキュアプログラミングは、Webアプリケーションに関するセキュリティポリシーに基づくものであり、これとは異なるセキュリティポリシーが適用されるソフトウェア開発にそのまま持ってこられるものではありません。“セキュアプログラミング”の対象がWebアプリケーション開発であることが一般的な今日、これ以外のソフトウェア開発に携わるエンジニアは、自分たちの業界におけるセキュアプログラミングとは何であるのかを明確に意識する必要があるといえるでしょう。

 当稿では、Webアプリケーションとは大きく異なる視点でセキュリティを考えなければならない分野としてゲームを取り上げます。スマートフォン向けのゲームが爆発的ともいえる普及を遂げた現在、1兆円に迫るともいわれるその市場に参入しようと考えているエンジニアの方も多くいらっしゃるのではないでしょうか。スマートフォン向けのゲームはその多くがオンラインゲームであり特にサーバーサイドの開発ではWebアプリケーションの場合と同じようなセキュリティが意識されますが、クライアントサイドで実行されるゲームアプリの開発ではチートと呼ばれる不正行為の防止も重要なセキュリティ要件となります。両者のセキュリティにどういった違いがあるのかを対比し、技術的な観点で見るとチートとは何であるのかを当稿では解説していきます。

対象読者

  • チート対策に興味や関心のあるエンジニア

 Android向けにビルドしたUnityアプリを改変する例のみ、UnityとC#およびAndroidのアプリ開発に関する基本的な知識を前提とした解説になっています。

必要な環境

 アプリ改変の例を試してみる場合は、UnityでAndroidアプリを開発・実行できる環境が必要になります。UnityやAndroidのバージョンについては特に制限はありません。

チートとは何か(1)

 ユーザーが、ゲームを有利に進めるために、製作者の意図しない状態でゲームのプログラムを動作させることをチートと呼びます。有料アイテムを料金の支払いをせずに使用してしまう、敵に攻撃されてもダメージを負わないようにする、実際にはクリアできていないステージをクリアしたことにする、といった行為が行われてしまうため、アイテム課金の売り上げに直接の損害を受けるほか、ゲームバランスを崩されてしまいゲームタイトル自体の魅力が失われてしまうといった深刻な事態を招くこともあります。

 製作者が意図しない状態とは、以下に挙げるような、プログラムの挙動に関する何らかの要素が改変された状態です。

ファイルが改変される

 ゲームが中断される際、そこからプレイを再開できるようにするためにはその時点でのプレイ状況をファイルに保存しておく必要があります。ここで、このファイルの内容が改変されると何が起きてしまうでしょうか。改変されたファイル内容を読み取ったプログラムは、それを自分が保存したものと誤認し、そこに書かれているとおりの状態でプレイを再開させてしまいます。これにより、ダメージを受けて減っていたHPの値を回復させるといったことができるようになり、回復アイテムの購入を不要にするといったチートが行われます。

 この種のチートに対しては、ファイルに保存する内容を暗号化することが有効な対策となります。また、オンラインゲームならではの方法として、ローカルファイルではなくゲームサーバーを保存先とするという対策も考えられます。

プログラムが改変される

 ファイル内容を暗号化すれば改変されることを防げますが、では、ファイル内容を暗号化するようにすればファイル内容は暗号化されるのでしょうか。この意味不明な問いに「え!? 当たり前でしょう?」と思われたかもしれません。しかし、チート対策を考える場合、書いたプログラムが書いたとおりに実行されると無条件には期待できないのです。攻撃者は、プログラムを本来の内容のままで実行するとは限りません。自分に都合が良いように内容を改変してプログラムを実行し、ファイル内容が暗号化されないようにできてしまうのです。あるいはより直接的に、攻撃を受けてもHPが減らないようにする、パズルが最初から解けているようにする、ランダムに変化する内容を固定化する、といったようにプログラムが改変されてしまうこともあります。

 プログラムが改変されないようにするにはどうすればよいでしょうか。改変を防止する技術といえば電子署名が思い浮かびます。実際、プログラムに電子署名を施す仕組みは多くのOSが標準機能としてサポートしており、AndroidやiOSではアプリへの電子署名は必須となっています。しかしながら、こういった電子署名の仕組みはチート対策にはなりません。攻撃者は、もともとの電子署名を除去し、電子署名が必須である場合は自分の秘密鍵で新たな電子署名を施します。これによってOSはプログラムが信頼できる開発元によるものでないことをユーザーに警告するようになりますが、その警告を受ける“ユーザー”とは攻撃者自身であり警告は無視されるだけです。

 電子署名で改変を防止するのであれば、署名の検証をプログラム自身が自身のために行うようにしなければなりません。実行される際には、最初にプログラム自身に施されている電子署名を検証するようにし、検証に使用する公開鍵もプログラム開発者のものをプログラム内に埋め込んでおけば、改変したプログラムは実行できなくなります。ただし、攻撃者がプログラムを改変してくるということの意味を忘れてはなりません。改変がないか検証するという仕組み自体が改変されて無力化されてしまえば対策を突破されてしまいます。この攻撃を防ぐためには、改変がないかの検証処理がプログラム中のどこでどのように行われているのかが分かりづらいようなプログラム内容にするしかありません。プログラムはCPUへの命令を形式どおりに並べたものであるため絶対に解析できないようにするのは原理的に不可能ですが、さまざまな技法・工夫によって解析が非常に困難となるようにはできます。こういったプログラムの処理内容を解析・改変することが困難であるという性質は「耐タンパー性」と呼ばれ、チート対策を行う上での重要な要件となります。

 ファイル内容を暗号化する処理が解析されて暗号鍵を看破されてしまうと、暗号化して保存したファイル内容であっても読み書きされてしまうため、プログラムの改変を検知する処理だけでなく、ファイル内容の暗号化処理にも耐タンパー性が要求されます。プログラムに耐タンパー性を持たせる1つの方法として、プログラムの実行ファイル全体を暗号化しておき、プログラムが実行される際の最初の段階で暗号化を解除するという方法があります。この場合、暗号化を解除する処理自体は暗号化しておけないため、この部分の耐タンパー性をどうするか、メモリ上にロードした後は暗号化を解除してCPUが実行できる状態にしなければならないがそれをダンプされないようにするにはどうするか、といった点で工夫が必要になります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5