2009-05-06 2 views
2

私はリバースエンジニアリングを少しでもやってみようとしている文書化されていないAPIを扱っています。これは悪意のあるものではなく、創造的な方法でユースケースを実現しようとしていることを心配しないでください。名前を知らずにC構造体のメンバーにアクセスするにはどうすればよいですか?

私はC構造体へのポインタを持っています。この構造体のメンバ数を調べることで、私が決定する方法はありますか?彼らの価値?

実際のメンバー名は利用できないと思われますが、おそらくそれは可能でしょうか?

答えて

3

メモリレイアウトによっては、構造の終わりを特定し、構造が上位レベルで何をするかを知ることで、メンバーについて推測することができます(アライメントに注意してください)。しかし、コードにデバッグシンボルが付いていない限り、名前を知ることはできません。その場合は簡単です。構造体が使用されているどこかでブレークし、デバッガで検査します。

編集:
あなたは、構造体が含まれているものをメンバー知りましたと仮定し、また、あなたのコンパイラが同じアライメントを使用して、あなたがあなたのコード内の構造のファクシミリを定義し、あなたへのポインタを使用することができますことを知っています実構造のアドレスを指し示す構造体。その後、コード内のすべての要素に簡単にアクセスできます。

+0

私はそれを仮定することができます: struct Foo { int bar; }; Foo f; Foo * pf =&f; int * pFirstMember = &f[1]; // ?? – Marplesoft

+0

@Marplesoft、データ構造の整列を見て、SOまたはWPの情報をここで見つけることができます。基本的に、構造体の最初の要素は構造体自体と同じアドレスを持つことが保証されています。すなわち、pFirstMember =(int *)&fは、本当にintである場合にのみ動作します。 – quinmars

4

いいえ、単にメモリからstructメンバーの「構造」を判断する方法はありません。

1

残念ながら、CやC++では型情報がありません。 C++にはRTTIがいくつか用意されています。これにより、dynamic_castはダウンキャストの正当性をチェックできます。しかし、メンバー(名前またはタイプ)に関する情報は提供されません。

+0

そのようなRTTIが動作するには完全なソースが必要です。リンカーは、RTTI情報が参照できない場合は、すべてのRTTI情報を除去します。 – MSalters

0

Cでは、通常、すべてのメンバー名、オフセット、およびサイズを含むメタ構造を作成します。

#define MEMBER(name,str) { #name, offsetof(struct str, name), sizeof(*(&((struct str *)(0))->name) } 
struct A { char *name, int offset; int size; } = { 
MEMBER(name,A), 
MEMBER(offset,A), 
MEMBER(size,A) 
}; 

この場合、必要に応じてクリエイティブキャスティングを使用して、構造のすべてのメンバーを一覧表示することができます。

5

できません。あなたができることは、記憶を調べて、推測することだけです。

たとえば、ポインターの値は同じ「一般的な領域」にあることが多いため、簡単に見つけることができます。構造体へのアドレスがある場合は、数値的に「近い」値(プラットフォームのポインタサイズ、通常は32または64ビット)を探します。

プラットフォーム上のいくつかの「共通」浮動小数点数のビットパターンを調査して調べることも価値があります。ここでは、アプリケーションやドメインの知識はもちろん、おそらくそこにあるはずの値がありますが、それは検索する自然なものです。

関数に構造体を受け入れたり戻したりするAPIにアクセスできる場合は、構造体を呼び出して、何が起きているかの手がかりを得ることができます。

もちろん、最初の場所に構造体を割り当て/作成するコードをステップ実行して、どこで何が行われるのかを確認することもできます。

1

私は何をしようとしていると言いますが、より良い方法があります。

関連する問題