So-net無料ブログ作成

ちょっとしたプログラムプロテクトの話 #2 [プログラム]

ちょっとしたプログラムプロテクトの話 #1」のつづきです。




コード内のメッセージを見たい VS メッセージを覗かれたくない

この戦いに決着をつけるためのアプローチとしては、大きく分けて2つの方法が採られました。

ひとつは、リストを見られないように BASIC プログラム自体に細工をすること。
もうひとつは、コード内にあるメッセージを「暗号化」することでした。




ひとつめのアプローチは BASIC プログラム自体に細工をすることです。

あるゲームではリストの各所に REM 文が挿入してあり、コメントの先頭文字が「CLR(画面消去)」になっていました。 リストを取ると頻繁に画面消去が繰り返され、内容を確認する事がとても困難になります。

また、あるゲームでは 'P' オプション付きでセーブされているのですが、ワークエリアを操作して 'P' オプションを解除しても、リストを取ると特定の場所の表示時に「暴走」するような仕掛けがしてありました。
リスト中に「…:PC=98」という記述があり、この部分に細工がしてありました【PC-9801版 大○○2】

どちらの場合も、「MON」命令が無効化されていたのですが、無効化を解除した後でモニタから直接 BASIC のテキストを操作する事で破られてしまいました。




様々な方法で BASIC のテキストを「不可視化」する試みが行われましたが、ことごとく破られてしまうためか、この後テキスト自体を不可視化することはあまり行われなくなります。

これは BASIC の不可視化よりもディスク自体のプロテクトにウェイトが置かれるようになったのと、C コンパイラでの開発が主流になってきたのが原因と思われますが、真相は定かではありません。




ふたつめのアプローチは、コード内にあるメッセージを暗号化することでした。

これは現在でも使用されている方法です。 もちろん当時よりは高度な暗号化技術が使われているので「暗号強度」は比べるまでもありませんが…。


最初に用いられた暗号化は、「シーザー暗号」と呼ばれる、単純に
'IBM' → 'HAL'
'シンブンシ' → 'スアベアス'
という具合にキャラクタコードをずらしただけのものでした。 しかしこれだと、表示されたメッセージと比較する事で簡単に見破られてしまいます。

また、メッセージ全体を暗号化すると、
'ココ ニハ ナニ モ ナイ' → 'スス#ノヘ#ネノ#ヨ#ネオ'
と、単語の区切りに使用する「スペース」が、特定の文字(この場合は '#' )に変換されることから、元のメッセージとの対応が容易に推測されてしまいます。
(この場合は ' '(0x20) '#'(0x23) が ASCII コードでは +3 の違いなので、
<暗号化された文字> - 3 = <元の文字>
という推測が簡単に導けます。)




雑誌投稿や同人系のゲームでは、単純な「シーザー暗号」でも問題はないでしょうが、パッケージで発売されるゲームとなると、もう少し複雑な仕組みでないと「技術力が低い」と馬鹿にされてしまいます。
そこで「シーザー暗号」よりも、もう少し高度な「ビット反転」が使われます。
ビット反転だけだと見破られてしまう可能性があるのですが、暗号化/復号化の両方で同じルーチンが使える利点があります。


Encrypt_sample
メッセージ暗号化ルーチン サンプル(MSX)

これは、友人に頼まれて作った「簡易暗号化ルーチン」の復刻版(!)です。
このままだとリストが見難いので、テキストに直したものを掲載しておきます。
list
10 DEFINT A-Z
20 A$="ここには Shield が おいてあります"
30 FOR I=1 TO LEN(A$)
40  C=ASC(MID$(A$,I,1))
50  IF C>&H85 THEN E=C XOR &H5C ELSE IF C>&H40 THEN E=C XOR &H1F 
    ELSE E=C
60  PRINT CHR$(E);
70 NEXT
Ok
run
ニニコカ Lwvzs{ ハ♣ ノホソヘ、ウチ
Ok


この暗号化の利点は、単純なので CPU パワーを食わないことと、アルファベット/記号部分(0x21 - 0x7f)とひらがな/カタカナ部分(0x86 - 0xfd)の反転させるビットを違うパターンにする事で、解読され難くなっている事です。

欠点としては、
'`' 0x60 → 0x7f 「削除」
'「' 0xa2 → 0xfe 「未定義文字」
'」' 0xa3 → 0xff 「カーソル表示」
' ' 0x90 → 0xcc 'フ'
' ' 0xa0 → 0xfc 'わ'
と変換されるため、BASIC でプログラミングする場合、ルーチンをこのまま使用すると
「バッククォート(0x60)
「山括弧(0xa2 - 0xa3)
'フ'
'わ'
をメッセージ中に使用できなります。
そのため BASIC で上記の文字を表示させるには例外処理を追加する必要があります。

また、例外処理を追加する事で暗号化されたメッセージに「迷彩」が施され、単純なビット反転だけではなくなるので、逆に破られにくくなる利点もあります。




BASIC でゲームを作る時代は瞬く間に過ぎ去り、C やマシン語での開発も汎用ツール(ゲームエンジン/スクリプトエンジン)を使う方式へと代わりました。
今では「暗号化」はエンジンの一機能として存在していますが、ほとんど誰も気に留めることはありません。

コード内のメッセージを見たい VS メッセージを覗かれたくない

たぶん永遠に続くであろう戦いの「始まりの時代」のお話でした。


(参考)
Wikipedia: 単一換字式暗号
Wikipedia: シーザー暗号
Wikipedia: ゲームエンジン
Wikipedia: スクリプトエンジン (ゲーム)

nice!(2)  コメント(5)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 2

コメント 5

しおんパパ

ども(^o^)/
先日はご訪問ありがとうございました。


暗号化の話、面白いですね。雑誌から手入力の時代にはADVはあまり見かけませんでしたが、そのままだと打ち込み時に判ってしまいつまらないですし、暗号化されてると、入力が大変だったりと作者の方も苦労されたでしょうね(⌒~⌒)
by しおんパパ (2010-02-23 07:55) 

Thunderbolt

しおんパパさん、nice! & コメントありがとうございます。

実は技術さえあればBASICのテキスト暗号化は難しくありません。 テキスト中のメッセージだけを探して暗号化するルーチンを作成し、暗号化が終われば削除してしまえば簡単に暗号化できます。

by Thunderbolt (2010-02-23 21:55) 

本名荒井

打ち込みプログラムの暗号化技術は、入力者=プレイヤーに対する礼儀という側面が強かったと思います。

 しおんパパさんが仰るとおり、複雑に暗号化しすぎるとデータが入力しづらくなるという側面もありましたね。MSX2+以降では、漢字モードのテキストデータをテキストモードで表示させると文字化けを起こすことを利用して、メッセージを暗号化することがありましたが、この方法で暗号化すると、似たようなキャラクターが入り乱れて出現するので、非常に入力しづらそうだったのを覚えてます。
by 本名荒井 (2010-02-25 09:58) 

Thunderbolt

牛鳥庵。さん、nice! ありがとうございます。

体調不良のためレスが遅くなりました。すみませんでしたm(_ _)m

by Thunderbolt (2010-03-01 20:56) 

Thunderbolt

本名荒井さん、コメントありがとうございます。

しおんパパさんや本名荒井さんの仰るとおり、打ち込みプログラムの場合はプレイヤーに対する礼儀の側面が強かったと思います。

市販ソフトでは「礼儀」としては勿論ですが「技術力の誇示」としての側面も持っていたように感じます。
ユーザー登録葉書などに「暗号化は簡単に解読できました」なんて書いてあると「次こそは破られない暗号化を…」と考えたものです。

体調不良のためレスが遅くなりました。すみませんでしたm(_ _)m
by Thunderbolt (2010-03-02 02:09) 

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。