2

私が作ったこのDLLがあります。別のプロセスに注入されます。他のプロセス内で、次の関数を使用してそのメモリ空間から検索を行います。


void MyDump(const void *m, unsigned int n)
{
        const char *p = reinterpret_cast(m);

        for (unsigned int i = 0; i < n; ++i) {
                // Do something with p[i]...
        }
}

今私の質問。ターゲットプロセスがデータ構造を使用する場合、たとえば

struct S
{
        unsigned char a;
        unsigned char b;
        unsigned char c;
};

プロセスのメモリ内で常に同じように表示されますか? つまり、Sa = 2 (常に b = 3、c = 4 に続く) は、プロセスのメモリ空間の連続した行に表示される構造です。

Offset
---------------------
0x0000 | 0x02 0x03 0x04

または、これらの変数は、次のように別の場所にある可能性があります

Offset
---------------------
0x0000 | 0x00 0x02 0x00
0x03fc | 0x00 0x03 0x04

後者の場合、メモリからさまざまなポイントからデータ構造を再構築する方法は?

よろしくお願いします、
nhaa123

4

4 に答える 4

1

被害者が C または C++ で記述されていて、使用されているデータ型が非常に単純な場合、それらは常にメモリ内の単一のバイト ブロックとして検出されます。

しかし、C++ 型のようなものがあるとすぐに、std::stringその観察は成り立たなくなります。まず、正確なレイアウトは C++ コンパイラ間で異なり、同じコンパイラのバージョンが異なる場合でも異なります。std::string のバイトは、連続した配列にない可能性がありますが、連続した配列になる場合があります。それらが 2 つに分かれている場合、後半を見つけても前半を見つけるのにはおそらく役に立ちません。

Java アプリを実行する JIT 実行中の JVM のような、より複雑な環境には投入しないでください。メモリ内で遭遇する型は非常に複雑です。それらを解読することについて本を書くことができます。

于 2009-09-09T08:41:38.437 に答える
0

メンバーの順序は常に同じになり、構造体は連続したメモリ ブロックを占有します。

コンパイラによっては、メンバー間にパディングが追加される場合がありますが、プログラムが同じコンパイラと同じ設定で再コンパイルされた場合でも同じです。パディングが追加されていて、それを認識していない場合、実行時に確実に検出することはできません.コンパイラが持っていたすべての情報はその瞬間に失われ、パターンを分析して推測するだけです.

于 2009-09-09T08:26:22.633 に答える
0

それは構造の配置に依存します。

このようなものがある場合:

struct A
{
  int16_t a;
  char    b;
  int32_t c;
  char    d;
}

次に、デフォルトで32ビットプラットフォーム(64ビットに当てはまるかどうかはわかりません)、bの後に1バイトがパディングされ、dの後に最後にさらに3バイトがパディングされるため、cのオフセットは4です(正しく覚えていれば) )。

構造体に指定されたアライメントがある場合は異なります。

于 2009-09-09T11:01:05.353 に答える