C言語で、自己改変コードの作成を行っています。
実行時にmain関数の中で、そのコードが含む(main関数ではない)別の関数がロードされているメモリ領域に対して処理を行い、自己改変を実現しようと考えています。
変更を加えたい関数がロードされたメモリ領域を特定し、そのメモリ領域への書き込みをmprotectシステムコールを用いて書き込み可能にするところまではできました。
しかし、その先、そのメモリ領域の内容を読み出し、変更を加えるところがどうもうまくできません。
例えば、あるメモリアドレス0x804845cに格納されている値を読み出したい場合、どのようにしたら良いのでしょうか?
さらに、そこに格納されている値を変更したい場合、memsetシステムコールを用いて書き込みを行おうと考えているのですが、正しいでしょうか?
(例:メモリアドレス0x804845cに値0x23を格納したい場合
memset((0x804845cへのポインタ), 0x23, 1);
のようにする)
アドバイスをお願いいたします。
No.1ベストアンサー
- 回答日時:
この種のポインタ操作はC言語仕様上は保障されませんので可搬性は乏しいですが、あらかじめ該当アドレスへの書き込み権限が設定されているなら、例えば
char *p;
p=0x804845c;
*p=0x23;
で書き込みできるでしょう。
読み出しは、*pを参照すれば可能です。
複数バイトに渡ってアクセスする場合は配列へのポインタとして扱いましょう。書き込みはmemset(これはライブラリ関数で通常システムコールではないですけど)を使っても良いでしょう。
ただし、書き換えたコードを実行する場合はコードがキャッシュされていると書き換え前のコードを実行する可能性もあるので注意が必要です。
コード書き換えを通知する手段(システムコール等)があればそれを使い、またない場合はキャッシュをフラッシュして整合性を取ってください。キャッシュのフラッシュはシステムコールがあるか、なければCPU命令(特権命令)を使うことになります。
Linuxなど保護されたOSではアプリケーションで特権命令を使うことは普通はできません。必要ならデバイスドライバなど特権命令を実行できるカーネルモードで実行されるプログラムを用意してください。
確かに、このようにポインタを利用すれば読み書きできますね。
memsetを使う必要はありませんでした。
コードのキャッシュについては考慮しなくても大丈夫でした。
おかげさまで無事、目的のプログラムが完成いたしました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# このプログラミング誰か教えてくれませんか 3 2022/05/13 17:27
- Visual Basic(VBA) 【Excel VBA】書き込み先のシートが存在しなかった場合、新規でシート作成する方法 3 2021/11/04 21:45
- C言語・C++・C# このプログラミング誰か教えてくれませんか 2 2022/05/14 09:45
- Excel(エクセル) IF文の管理を簡単にしたい 4 2021/11/07 11:23
- その他(データベース) Access Nz関数の合計値の小数点桁数について 1 2021/12/14 14:51
- Excel(エクセル) VBA 特定の単語以外が含まれる行全体を削除したい 2 2021/11/03 18:55
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- JavaScript javascriptとPHPで入力フォームのコードを書いているのですが、 流れとしては、①入力フォー 2 2021/12/02 09:18
- 高校 合成関数の定義域につきまして 1 2022/05/18 17:26
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ヒープメモリの解放について
-
メモリ不足になってしまう。
-
win32APIのHeapAlloc()の使い方...
-
new、memset()、エラー
-
allocってなんですか?
-
C言語に関する質問
-
GDI+におけるメモリの開放について
-
64ビットと32ビットの違い
-
C++のnewで確保したメモリーの...
-
HEAP に関すること
-
newしないオブジェクトについて
-
c言語のポインタへの文字列入力...
-
指定したメモリアドレスの値の...
-
C++ Vectorのデストラクタ
-
スタック破壊の上手な見つけ方...
-
LPWSTRのコピー
-
malloc()関数内でセングメント...
-
グローバル変数のサイズ
-
newでrealloc?
-
入れ子になった構造体について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語のポインタへの文字列入力...
-
allocってなんですか?
-
newしないオブジェクトについて
-
mallocについて
-
配列の添え字の最大数とは?
-
ヒープメモリの解放について
-
ビットをローテートするプログ...
-
C++で、メンバもヒープに確保さ...
-
malloc呼び出し時のセグメンテ...
-
プログラムが途中で強制終了し...
-
指定したメモリアドレスの値の...
-
スタック破壊の上手な見つけ方...
-
void*型のデータサイズ
-
ポインタのポインタの初期化法
-
free関数で動作が止まる
-
callocの処理速度
-
MSDNがgethostbynameではなくge...
-
C++のnewで確保したメモリーの...
-
sprintf()の使い方について
-
Accessで、メモリを開放するタ...
おすすめ情報