アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語で、自己改変コードの作成を行っています。
実行時にmain関数の中で、そのコードが含む(main関数ではない)別の関数がロードされているメモリ領域に対して処理を行い、自己改変を実現しようと考えています。
変更を加えたい関数がロードされたメモリ領域を特定し、そのメモリ領域への書き込みをmprotectシステムコールを用いて書き込み可能にするところまではできました。
しかし、その先、そのメモリ領域の内容を読み出し、変更を加えるところがどうもうまくできません。
例えば、あるメモリアドレス0x804845cに格納されている値を読み出したい場合、どのようにしたら良いのでしょうか?
さらに、そこに格納されている値を変更したい場合、memsetシステムコールを用いて書き込みを行おうと考えているのですが、正しいでしょうか?
(例:メモリアドレス0x804845cに値0x23を格納したい場合
memset((0x804845cへのポインタ), 0x23, 1);
のようにする)
アドバイスをお願いいたします。

A 回答 (1件)

この種のポインタ操作はC言語仕様上は保障されませんので可搬性は乏しいですが、あらかじめ該当アドレスへの書き込み権限が設定されているなら、例えば


char *p;
p=0x804845c;
*p=0x23;
で書き込みできるでしょう。
読み出しは、*pを参照すれば可能です。
複数バイトに渡ってアクセスする場合は配列へのポインタとして扱いましょう。書き込みはmemset(これはライブラリ関数で通常システムコールではないですけど)を使っても良いでしょう。

ただし、書き換えたコードを実行する場合はコードがキャッシュされていると書き換え前のコードを実行する可能性もあるので注意が必要です。
コード書き換えを通知する手段(システムコール等)があればそれを使い、またない場合はキャッシュをフラッシュして整合性を取ってください。キャッシュのフラッシュはシステムコールがあるか、なければCPU命令(特権命令)を使うことになります。
Linuxなど保護されたOSではアプリケーションで特権命令を使うことは普通はできません。必要ならデバイスドライバなど特権命令を実行できるカーネルモードで実行されるプログラムを用意してください。
    • good
    • 0
この回答へのお礼

確かに、このようにポインタを利用すれば読み書きできますね。
memsetを使う必要はありませんでした。
コードのキャッシュについては考慮しなくても大丈夫でした。

おかげさまで無事、目的のプログラムが完成いたしました。
ありがとうございました。

お礼日時:2008/01/15 09:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています