0

私はデバッグ情報を扱っています。「デバッグ情報パーサー」のようなものを書こうとしています。これを行うためにDWARFおよびELFライブラリを使用していますが、メモリ空間の情報以外には何も提供していません。そのメモリ空間でデータを取得しようとしています. 私はプログラムに夢中です。私は Pin というツールを使用しているので、実際には他のプログラム内でコードを実行しています。その変数にアクセスできるのはそのためです。

アドレスへのポインターがあると仮定すると、そのアドレスと次の 4 バイト (たとえば) に格納されているすべてのデータを取得したいと考えています。

例として、アドレス 0xDEADBEEF があり、そのアドレスから始まる次の 4 バイトを調べて、データを読み取りたいとします (各バイトのポインターを逆参照します)。

私はCに比較的慣れていません。私がやろうとしていることは次のとおりです。

char * address = "0xDEADBEEF";
unsigned int bytesize = 4;

ptr = (void *) address;
ptr_limit = ptr + bytesize;

for(ptr; ptr < ptr_limit; ptr++)
     cout << ptr;

これは完全に間違っている可能性があり、多くのコンパイルエラーが発生していることはわかっていますが、使用しようとしているロジックの一部を示すだけです...

4

4 に答える 4

7

OK、C と C++ は低レベルですが、ワイルド ウェストではありません。アドレスを作ってアクセスすることはできません。ほとんどの OS では、アセンブリでこれを行うことは許可されていません。これが SegFault の発生源です。

メモリを取得する方法は、メモリを割り当てることです。このプロセスには、あるサイズのメモリが必要であることを OS に伝えることが含まれます。その時点で、OS は特定の範囲の仮想メモリにアクセスできるように処理を行います。この範囲外 (または OS がアクセスを許可した任意の範囲) のメモリにアクセスしようとすると、OS がプログラムを終了させます。

C では、一般にmalloc/ calloc/を使用reallocしてメモリを割り当てfree、OS にメモリの使用が完了したことを伝えます。C++ はnew、オブジェクトの割り当てとdelete割り当て解除に使用します。

「デバッグ情報パーサー」のようなものを書こうとしています。これを行うためにDWARFおよびELFライブラリを使用していますが、メモリ空間の情報以外には何も提供していません。そのメモリ空間でデータを取得しようとしています

質問にそのようなものを入れていただければ幸いです。

いずれにせよ、あなたは他人のメモリにアクセスすることについて話しているのですが、それは行われていません。標準 C および C++ の規則では許可されていません。さまざまな OS には、別のプロセスのアドレス空間を自分のプロセスにマップできる呼び出しがあります。しかし、それははるかに複雑で、OS 固有です。

于 2012-09-24T23:38:20.170 に答える
1

メモリアドレスは整数型(読み取り番号)です。
あなたの例では、char *(read string ) があります。

次のコード:

char * address = "0xDEADBEEF";
void * ptr     = ( void * )address;

char *その変数のアドレスをとして、void *に入れるだけpです。
ポインタをメモリ address に設定しません0xDEADBEEF

その特定のメモリ位置にアクセスしたい場合 (自分が何をしているのかを知っていると仮定して)、次のようなものが必要になります:

void * ptr = ( void * )0xDEADBEEF;

「自分が何をしているのか知っていると仮定して」と言ったのは、そのような特定のアドレスにアクセスすると最終的にセグメンテーション違反が発生するためです.リング0で何かをしていない限り、そのようなアドレスがアドレス空間にあることを基本的に知らないからです. (カーネルを読み取る)、たとえば、DMAを使用します。
しかし、ポインタが文字列ではなく数値であることを知っていると思います...

于 2012-09-24T23:41:05.080 に答える
0

コードは非常に単純です。

char *address, *limit;

for(address = (char *)0xdeadbeef, limit = address+4; address < limit; address++)
     cout << *address;

ただし、任意の整数をアドレスに変換することは許可されていますが、結果のポインターを使用した結果は移植可能ではないことに注意してください。コメント(デバッグ情報を介してアドレスを取得している)に基づいて、取得しているアドレスが有効である必要があり、結果通常どおり機能するはずです(移植可能であるという保証はありません)。

于 2012-09-24T23:43:58.447 に答える
0

アドレスをDWORDとして保存=>DWORD address = 0xDEADBEEF 次に、このアドレスをポインターにキャストします=>void *ptr = (void *)address

以下に例を示します。

char *pointer = "FOO";
DWORD address = (DWORD)pointer;
printf("0x%u\n", address);
printf("%s\n", (char *)address); // prints FOO

address++; //move 1 byte
printf("%s\n", (char *)address); // prints OO
于 2012-09-24T23:46:45.993 に答える