第4回  「メモリを書き換えるとどうなる?」





プログラム実行の手順

メモリについてお話する前に、皆さんがプログラムを起動する時の事を、思い浮かべてみましょう。
例えば、ワープロソフトを起動するとします。この時使うソフトはハードディスクに保存されていますよね?
そして、実行(起動)すると、その内容がハードディスクからメモリへコピーされます。

基本的にプログラムを実行するためには、その内容をメモりにコピーするというのがお約束なのです。
そして、プログラムが終了するまで、メモリの中に居座り続けます。
(実際は、多少異なる部分があるのですが、ここでは気にしないで下さい)



ゲームだってプログラムだ!

さて、ゲームソフトの場合はどうでしょう?
ゲームソフトとはいっても、ワープロソフト等と変わる事のない、れっきとしたプログラムです。
ということは、実行されている間はメモリにそのプログラムがあるはずですよね?

では当然、キャラクターのHP・MP・お金といった情報もメモリの中に存在するはずです。
ゲーム中にこれらの値は増減しますが、実際の増減はメモリの中で行われています。
セーブされた時には、これらの情報をセーブデータファイルとして保存しているのです。

では、メモリの中身を直接書き換えるためにはどうすればよいのでしょう?


実行中のプログラムの名前

前回までは、セーブデータファイルを書き換えてきましたが、
このファイルには、ファイル名が付けられていますよね。(セーブデータに限りませんが)
同じように、メモリの中にあるプログラムにも名前が付いています。

「Ctrl」と「Alt」キーを押しながら「Delete」キーを押すと「プログラムの強制終了」というダイアログボックスが出てきます。
(2回続けて押すと、再起動してしまうので注意して下さい)
その中に、現在動作中のプログラムが表示されています。

この、プログラムの名前の事を「プロセス名」と呼びます。
この画面を見ながら実行した人は「Microsoft Internet Explorer」等が表示されていますよね。
ただし、ここで表示される名前と、プロセスメモリエディタで表示される名前が異なる場合もあります。
この場合は、プロセスメモリエディタで表示されている名前を使用します。



メモリを書き換えるメリットって?

実際にメモリの書き換える時は、どのプロセスの、どのアドレスを書き換えるかを指定します。
セーブデータの時は、どのファイルの、どのアドレス・・・という感じでしたね。
ですから、基本的な考え方は、ファイルの書き換えと同じものです。

ただし、メモリを書き換える場合は、ファイルの書き換えに比べて優れた点も劣る点もあります。
例えば、「HPを5秒ごとに最大値に書き換える」という改造を実行するとどうでしょう。
これは「無敵」とほぼ同じ意味になります。(実質的にHPが減少しないのと同じ事)
セーブデータを書き換えた場合、一時はHPを最大になっても、ゲーム中に減ってしまうのは止められません。
これは、実行中のゲームを直接改造している場合のメリットといえるでしょう。

また、セーブデータファイルには、簡単に改造されないための細工がしてある事があります。
「チェックサム」「暗号化」・・・等(詳しくは述べませんが)
ですが、メモリ上に存在するデータの場合「暗号化」されていたデータも、普通のデータに戻っていたりします。
これなら改造も容易ですね。

ですが、デメリットもあります。
HP等の情報が存在するアドレスなのですが、これはゲームのバージョンが変わると、ほとんどの場合変わってしまいます。
パソコンゲームは、バグ修正等の細かいバージョンアップが何度も行われたりするので、
同じゲームでも、バージョンが変わると、多くの場合同じコードが使えなくなってしまうのです。

・・・とまあ、メモリを書き換えるのもそれなりの理由があるということで納得して下さいな。
ちなみに、プログラムそのものを書き換えれば、メモリを書き換えなくても「無敵」等を実現する事もできるのですが、
この場合プログラムを解析する技術が必要になりますので、難易度は高くなります。



それでは実行してみましょう

前置きが長くなりましたが、メモリの書き換えを実践してみましょう。
まずは、プロセスメモリエディタを使用してみます。
(プロセスメモリエディタは各自で入手しておいて下さい)

書き換える対象のプロセスは「メモ帳」にします。
「メモ帳」のプロセス名は「NOTEPAD.EXE」です。
では、改造後の「sample1.txt」をメモ帳で開き、「NOTEPAD.EXE」をプロセスメモリエディタで開きます。

sample1.txt (改造後)(プロセスメモリエディタで開いた時)
[ADDRESS] +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789abcdef
00410000 00 10 10 00 00 00 00 00 20 00 00 00 01 00 00 A0 ******* ********
00410010 80 0C 51 00 98 E8 42 00 80 00 00 00 01 00 00 A0 *Q◎B**********


とまあ、こんな感じになったと思います。
どうでしょう?何処かで見たような気がしませんか??
そう、バイナリエディタの画面とよく似ているんですね。
違いといえば、アドレスが「00000000」から始まっていない事ぐらいです。

ところで「sample1.txt」の中身は覚えていますか?
その中に「a11111111」という文字列がありましたので、これを探し出してみましょう。
この文字列は16進数で「613131313131313131」と表現されるんでしたね。

では、プロセスメモリエディタの機能で、この文字列を検索してみて下さい。
私の環境では、アドレス「00510280 〜 00510290」にかけて見つかりましたが、人によってバラバラだと思います。
では、その場所を表示してみましょう。

sample1.txt (改造後)(プロセスメモリエディタで開いた時)
[ADDRESS] +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789abcdef
00510280 31 31 31 31 31 31 31 31 31 31 31 31 61 31 31 31 111111111111a111
00510290 31 31 31 31 31 31 31 31 31 0D 0A 31 31 31 31 31 11111**111111111


該当部分はこんな感じになっています。
ゲームを改造する場合は、このように目的の場所を検索して書き換えればOKなのですが、
今回は書き換えても意味がないので、実際の書き換えは行いません。

では、サンプルプログラムでメモリを書き換える方法も同様に実行してみましょう。
「s_mem.vbp」をVBで開いて実行します。
すると以下のような画面になります。


プロセス名   
コード   

「メモ帳」で「sample1.txt」を開いた状態で、アドレス「0051028B」を「31」で書き換える場合は、
以下のように入力して、「書き換え」を実行するわけです。
(今回は書き換えを実行しても無意味なので、実行しない方がいいでしょう)


プロセス名 NOTEPAD.EXE
コード 0051028B-31


ソースプログラムの確認

では、先ほどのサンプルプログラムのソース部分を読んでみましょう。


s_mem ソースプログラム
Private Sub cmdExecute_Click()
    ret = MemoryEdit(txtProcessname.Text, txtCode.Text)

    If ret = 0 Then
      MsgBox "書き換えに成功しました"
    Else
      MsgBox "エラーです" & vbCrLf & "エラー番号 " & ret
    End If
End Sub


おや、これも何処かで見たような気がしますね。
そう、「s_file」のソースとほとんど同じなんです。
違いといえば、1行目の「BinFileEdit(txtFilename.Text, txtCode.Text)」が
「MemoryEdit(txtProcessname.Text, txtCode.Text)」に変わったぐらいです。

「MemoryEdit」という関数は、「プロセス名」と「改造コード」を与えてやると、
対象のプロセスを書き換え、その実行結果を返してくれる自作の関数です。
コードの読み方は第2回の時と全く同じですので、詳しい解説はそちらを見て下さい。


駆け足でメモりの書き換え全般を解説してきましたが、いかがでしたでしょうか?
次回は、レジストリの書き換えについて解説したいと思います。



前に戻る     次に進む

講座の初めに戻る