2

DWARF および ELF 情報を使用するプログラムで作業しています。Pin というツールを使用して別のプログラムにハマっています。「Y」プログラムで宣言されたグローバル変数からのアドレスを取得し、それを「X」と呼ぶ Pin モジュールにフックします。

これらのグローバル変数のアドレスを取得しています。残念ながら、それらを逆参照しようとすると問題が発生します。例(現在、私は手動で行っていることを行っているかどうかを確認しています):

char * limit, * address1;

for(address1 = (char *) 0x804A040, limit = address1 + bytesize; address1 < limit; address1++)
      cout <<  *(address1) << "\n";

そのアドレスに格納されている変数をchar *単語に取得する必要があります。この場合、2 つのポインターを逆参照する必要がありますか? アドレス、そしてそのアドレスにchar *保存されている?

これは、変数を逆参照する場合は完全に機能しintますが、char ポインターまたは変数を逆参照しようとすると、non-ASCII値が取得されます...

4

2 に答える 2

7

次のように考えてください: を逆参照する場合はint、次を使用しますint *

int *addr = (int *)0x12345678;
printf("%d\n", *addr);

ただし、文字列は既にポインターであるため、次のようにすると:

char *addr = (char *)0x12345678;

印刷するために逆参照する必要はないため、次のように取得します。

printf("%s\n", addr);

さらに、次の記憶があるとします。

00000001:  0x12345678
...
12345678:  'A'
12345679:  'B'
1234567A:  '\0'
...

0x00000001アドレスにアクセスして、何ができるか見てみましょう。

unsigned int *addr = (unsigned int *)0x00000001;

*addr文字列の最初の文字のアドレスである整数を保持します。文字列引数を取る関数は、通常、文字列アドレス、つまりそれへのポインタを要求します。これは、たとえば*addr出力する文字列でもあります。coutprintf

// This should print "AB"
printf("%s\n", (char *)(*addr));

ここで、値 ( 0x12345678) を逆参照すると、文字列の最初の文字だけが として取得されますchar。したがって、それを誤用して a に逆参照すると、char *printfメモリ 'A' を検索しようとし、これは0x00000041であり、おそらくセグメンテーション フォールトが発生します。

したがって、その値を参照解除して最初の文字を取得する正しい方法は次のようになります。

// This should print "A"
printf("%c\n", (char)(**addr));

したがって、結論として、まだ非 ASCII 値を取得している場合は、おそらくこの種のアドレス間の階層の問題であり、メモリを厳密にデバッグして、ポインターへのポインターを作成することが正しいかどうかを確認することをお勧めします。あなたの文字列へのパス。

于 2012-09-25T20:14:24.933 に答える
2

はい、2 つのポインターを逆参照する必要があります。最初に char* を保持する変数のアドレスを取得し、次に char* を逆参照します。

于 2012-09-25T20:13:36.353 に答える