[第2章]→

1 DSプロテクトについて


1.1 概要


1.1.1 プロテクトの概要

DSプロテクトは、ニンテンドーDS対応のソフトウェアの不正利用を制限することを目的に開発されています。ニンテンドーDS対応のソフトウェアは、海外のウェブサイトやP2Pネットワークを経由して、1タイトルあたり数万〜十数万本も不正にコピーされています。また、マジコン本体も正確な実売数は不明ですが、大手ネットオークションサイトだけでも月1万本以上が落札されているとも言われています。

DSプロテクトは、その不正な利用方法であるマジコンやエミュレータ上での利用を検出する手段を提供します。

※マジコン
海外のウェブサイトやP2Pネットワーク上で配布されているROMイメージを実機で遊ぶことのできる、DSゲームカード型のハードウェアです。


1.1.2 検出と反映

DSプロテクトは、不正な利用方法であるマジコンやエミュレータの存在を検出します。その検出結果を元に、プログラムとして反映させることができます。

本マニュアルでは「検出」「反映」の用語を頻繁に用いますが、両者の用語の定義を以下に示します。

・検出とは
プログラムの実行環境を調査し、不正な実行環境であるかを判定することを指します。DSプロテクトでは、「正規ゲームカードからの実行」のみを本来の実行環境とみなし、「マジコン」「エミュレータ」「デバッガ」は不正な実行環境であるとみなします。

本マニュアルでは、不正な実行環境であることが検出された場合を「検出に成功」「マジコンを検出した」「不正利用時」、正規の実行環境の場合は「非検出」「検出に失敗」「正規の場合」などと表現しています。

DSプロテクトは、この不正な実行環境の検出手段を提供します。

・反映とは
「不正な実行環境でのみプログラムの継続動作を阻止する」ような、条件分岐を伴う処理を指します。「不正利用時のみプログラムが暴走する」「不正利用時のみセーブが動作しない」といった挙動を行うものが当てはまります。

反映方法については、対象となるプログラムに応じたものでなければなりません。本マニュアルでは反映方法のサンプルとガイドラインを記載していますので、そちらを参考にして実装してください。

一般的に、攻撃者は反映処理を迂回するようプログラムを書き換えることでプロテクトの回避を試みます。そのため、反映処理が最も脆弱になることを常に留意して下さい。


1.1.3 検出方法

検出関数は以下の通りです。

1 : マジコン全般・一部エミュレータ検出関数
2 : エミュレータ検出関数
3 : 実際には検出を行わないダミー関数

※注意
今後起こりうるマジコン側によるプロテクト対策により、検出タイプは増加・変更する予定です。常に最新情報を確認し、最新版を用いるようにしてください。


1.1.4 検出時間

検出に要する時間は、DSフラッシュカード使用時で、約 30 ミリ秒です。これは6種類の検出関数を一度に呼び出した時の結果です(この実測値はバージョンアップにより変更されることがあります)。


1.1.5 使用メモリ・ROMサイズ

ライブラリサイズで 13.0 KByte となりますが、実際に組み込まれた際はそれより小さなサイズとなります。検出で利用するメモリ領域はスタック上に確保され、検出終了後に解放されます(この実測値はバージョンアップにより変更されることがあります)。


1.1.6 耐タンパー性

耐タンパー性とは、ライブラリ関数の解析の難しさを示します。検出ライブラリは暗号化されていますが、反映部分の実装方法でその強度は大きく影響されます。


1.1.7 暗号方法に関して

疑似乱数列と平文との排他的論理和が暗号文となることを利用したブロック暗号と、ARM命令の置換を行った暗号アルゴリズムを利用しています。ブロック単位はARM命令長と同じ4バイトとなっています。このアルゴリズムにより暗号化されたARMアセンブラ命令は、ARMアセンブラ命令(オペコード)の特徴をある程度残しながらオペランドを暗号化します。


1.1.8 暗号の鍵長に関して

暗号鍵の長さは16文字(128bit)に固定されています。


1.2 対応状況


1.2.1 検出確認済みマジコン

DSプロテクトでの検出を確認したマジコン一覧を以下に示します。これらのマジコンは、次章で解説する検出関数 AM_Is(Not)MagiconA1 で検出可能です。

名称 カーネルの
バージョン
URL
(リンク先要注意)
AceKard2 / AceKard2i 4.16 http://www.acekard.com/
SuperCard (DSOne) 3.0SP5 http://eng.supercard.cn/
CycloDS Evolution 1.54 http://www.cyclopsds.com/
M3DS Real 4.3c http://m3flash.jp/
G6DS Real 4.3c http://m3flash.jp/
iTouch 2.5a http://www.simplepluseasy.com/
R4DS 1.18 http://www.r4ds.com/index-en.htm
R4i 1.53 http://www.r4ultra.com/download.htm
DSTT / DSTTi 1.17 http://dstt.jp/index.htm
Ezflash V / Ezflash Vi 1.90beta11 http://www.ezflash.cn/
AceKard R.P.G 4.11 http://www.acekard.com/
MK5 1.45 http://www.neoflash.com/
DSLinker 1.45 http://www.dslinker.cn/
Ninjapass X9TF 1.2beta http://www.ninjapass.com/
F-CARD 1.45 http://www.dsfirelink.com/
K6 SUPER CARD 2.52 http://k6.cngba.com/k6.htm
n5 1.29 http://www.dsn5.com/
EDGE 1.44 http://www.edge-ds.cn/
KINOSAKI N-CARD 2.53 http://www.kinosaki.eu/
E7 2.01 http://www.dse7.net/
ND1 3.09 http://www.dsnd1.com/EN-ND1/
U2 1.7 http://www.u2ds.com/download.html

※ DSTTiなど「i」のついているマジコンは、DSiのNitroモードのみ対応しています。

マジコンのカーネルの中にはDSプロテクトの検出を、自動でプログラムにパッチを当てる等して回避している場合(以後、回避)があります。
以下はDSプロテクトのバージョンと、マジコンカーネルの回避状況との対比表になります。(ovlはオーバーレイ、○は検出可能、×は回避されている)

名称 1.06 常駐 1.06 ovl 1.08 常駐 1.08 ovl 1.10 常駐 1.10 ovl 1.20 常駐 1.20 ovl
AceKard2 / AceKard2i ×
SuperCard (DSOne) ×
CycloDS Evolution ※1×
M3DS Real × × ×
G6DS Real × × ×
iTouch × × ×

※1 特定の条件で検出される場合と回避される場合があります。

※ この表以外のマジコンやカーネルバージョンにおいても、特定のタイトルに対してのみ回避が行われる場合があります。

※ バージョンおよびURLは2009年4月現在のものです。


1.2.2 検出確認済みエミュレータ

DSプロテクトでの検出を確認したエミュレータ一覧を以下に示します。これらのエミュレータは、次章で解説する検出関数 AM_Is(Not)MagiconA1 または AM_Is(Not)MagiconA2 で検出可能です。エミュレータによって検出可能な関数が異なるため、併せて記載しています。

名称 バージョン AM_Is(Not)
MagiconA1
AM_Is(Not)
MagiconA2
URL
(リンク先要注意)
NO$GBA 2.6 × http://nocash.emubase.de/gba.htm
iDeaS 1.0.2.1 http://www.ideasemu.org/
NeonDS 0.1.1 × http://www.neonds.com/
ensata 1.4h 公式エミュレータ(※1)
FINALROM版のみ対応
IS-NITRO-DEBUGGER 1.87.0807.1700 × 公式デバッガ(※1)
FINALROM版のみ対応
IS-TWL-DEBUGGER 1.04.0903.1800 × 公式デバッガ(※1)
TWLSDK、及びTWLSDK付属のNITROSDKを使用しビルドしたFINALROM版のみ対応

※1 ensataは公式エミュレータですが、クラック版が流出していることを考慮して検出対象に含めています。同様に、IS-NITRO-DEBUGGERとIS-TWL-DEBUGGERも実機ではないため、検出対象に含めています。
デバッガや開発ツール上での詳しい検出結果は1.2.3節を参照してください。

※ バージョン、URL、プロテクト回避情報は2009年4月現在のものです。


1.2.3 開発ツール上での動作について

開発ツール上での検出関数の判定はROMのビルドの種類によって異なります。
以下にDSプロテクトを含み、DEBUG版、RELEASE版、FINALROM版でそれぞれビルドしたROMの動作を示します。

開発ツール名 DEBUG版 RELEASE版 FINALROM版
IS-NITRO-CAPTURE 正規品 正規品 正規品
IS-NITRO-VIDEO 正規品 正規品 正規品
IS-TWL-CAPTURE(開発カード対応) 正規品 正規品 正規品
IS-TWL-CAPTURE(市販カード対応) 正規品 正規品 正規品
TWL 開発用実機 正規品 正規品 正規品
ensata 正規品 正規品 不正利用
IS-NITRO-DEBUGGER 正規品 正規品 不正利用
IS-TWL-DEBUGGER
(TWLSDK内のtwl.h、nitro.hを使用)
正規品 正規品 不正利用
IS-TWL-DEBUGGER
(単体のNITROSDKのnitro.hを使用)
不正利用 不正利用 不正利用
IS-TWL-DEBUGGER (※1)
(デバッガとしてではなく開発用カードから単体起動)
正規品 正規品 正規品

※1 IS-TWL-DEBUGGERで動作保証されているフラッシュカードからカード起動した場合にのみ正規品と判定します。

1.3 注意事項


1.3.1 TWL 対応/専用ソフトへの組み込み

現在のDSプロテクトはすべてのROMタイプへの組み込み・検出には対応していません。
以下にDSの動作モードとDSプロテクトの組み込み・検出対応状況を示します。

組み込み方法 Nitroモード時の動作 TWLモード時の動作
DS ソフト(NitroROM)に組み込み マジコン検出可能
TWL 対応ソフト(HybridROM)の「ARM9 実行バイナリ」に組み込み マジコン検出可能 マジコン検出対象無し(※1)
TWL 対応ソフト(HybridROM)の「ARM9 TWL専用実行バイナリ」に組み込み 組み込み不可
TWL 専用ソフト(LimitedROM)に組み込み 組み込み不可
DSiウェアに組み込み 組み込み不可

※1 2009年4月現在、TWLモードに対応したマジコンが存在しないため検出可能なマジコンはありません。


1.3.2 ダウンロードプレイ、体験版への組み込み

DS実機から配信されない店頭什器体験版やDSダウンロードプレイによる配信版などについてはDSプロテクトを組み込まないようお願いします。

DS実機同士のDSダウンロードプレイ(マルチブートとクローンブート)についてはDSプロテクトを組み込まないようにするか、親機と子機の判定を行って子機の場合にDSプロテクトの関数を呼び出さないようお願いします。

親機と子機の判定をを行って関数を呼び出さないようにする場合には、プロテクトを簡単に回避されてしまわないように注意する必要があります。相応しい実装を以下に示します。詳しい検出反映方法は3章を参照してください。

if ( ! MB_IsMultiBootChild() )
{
    // オーバーレイでライブラリを含むモジュールを呼び出す
    FS_LoadOverlay(MI_PROCESSOR_ARM9, FS_OVERLAY_ID(OVERLAY_PROTECT));

    // ここでプログラムに対してMB_IsMultiBootChild()の判定を迂回させるパッチを当てられた場合に
    // 正常な動作を行わなくなるような親機で必須の処理を行う
    
    // ここで親機のみにマジコン検出と反映を行う
    
    // ここでプログラムに対してMB_IsMultiBootChild()の判定を迂回させるパッチを当てられた場合に
    // 正常な動作を行わなくなるような親機で必須の処理を行う

    // オーバーレイとして読み出したライブラリをアンロード
    FS_UnloadOverlay(MI_PROCESSOR_ARM9, FS_OVERLAY_ID(OVERLAY_PROTECT));
}


1.3.3 マルチスレッドでの動作

DSプロテクトは、基本的にスレッドセーフ(マルチスレッドに対応した形)に設計されていません。 このため、DSプロテクトの各ライブラリのAPIを割り込みハンドラや異なるスレッドから呼び出した場合、 正常に動作しない可能性があります。


1.3.4 NitroSDKのバージョン依存

DSプロテクトはNitroSDKのバージョンに依存しません。


1.3.5 TWLSDKのバージョン依存

DSプロテクトはTWLSDKのバージョンに依存しません。


1.4 動作確認環境


各種サンプルは、以下の環境で動作確認しております。

 

[第2章]→