0

VirtualQueryEx を使用して、次のコードでモジュールのメモリ ページを列挙しています。

unsigned char *p = (unsigned char *)module;
    MEMORY_BASIC_INFORMATION info;
    unsigned long usage = 0;
    for ( ;VirtualQueryEx(hProcess, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        printf("%#10.10x (%6uK)\t", info.BaseAddress, info.RegionSize/1024);

        switch (info.State) {
        case MEM_COMMIT:
            printf("Committed");
            break;
        case MEM_RESERVE:
            printf("Reserved");
            break;
        case MEM_FREE:
            printf("Free");
            break;
        }
        printf("\t");
        switch (info.Type) {
        case MEM_IMAGE:
            printf("Code Module");
            break;
        case MEM_MAPPED:
            printf("Mapped     ");
            break;
        case MEM_PRIVATE:
            printf("Private    ");
        }
        printf("\t");

        if ((info.State == MEM_COMMIT) && (info.Type == MEM_PRIVATE))
            usage +=info.RegionSize;

        int guard = 0, nocache = 0;

        if ( info.AllocationProtect & PAGE_NOCACHE)
            nocache = 1;
        if ( info.AllocationProtect & PAGE_GUARD )
            guard = 1;

        info.AllocationProtect &= ~(PAGE_GUARD | PAGE_NOCACHE);

        switch (info.AllocationProtect) {
        case PAGE_READONLY:
            printf("Read Only");
            break;
        case PAGE_READWRITE:
            printf("Read/Write");
            break;
        case PAGE_WRITECOPY:
            printf("Copy on Write");
            break;
        case PAGE_EXECUTE:
            printf("Execute only");
            break;
        case PAGE_EXECUTE_READ:
            printf("Execute/Read");
            break;
        case PAGE_EXECUTE_READWRITE:
            printf("Execute/Read/Write");
            break;
        case PAGE_EXECUTE_WRITECOPY:
            printf("COW Executable");
            break;
        }

        if (guard)
            printf("\tguard page");
        if (nocache)
            printf("\tnon-cachable");
        printf("\n");
    }

コードはこちらの別の投稿から取得しました。

問題は、VirtualQueryEx が現在のモジュールでページの列挙を停止せず (メモリがプロセス外になったときに停止するだけ)、結果が間違っていることです。

ここに私の出力とVMMapの出力があります

ここに画像の説明を入力

強調表示されたアドレスから始まることがわかるように、ページはすべて間違っており、VirtualQueryEx はそれらの列挙を停止しません。

どこが間違っていますか?

4

1 に答える 1

3

VMMap はファイル形式 (セクション .data、.text、ext) を認識しますが、VirtualQueryEx は認識しません。MEMORY_BASIC_INFORMATION.RegionSize - すべてのページが同一の保護属性を持つ領域のサイズ (スクリーンショットの RW)。そのため、領域の VMMap と VirtualQueryEx の計算が一致しません。

ここに画像の説明を入力

VirtualQueryEx はそれらの列挙を停止しません。

p += info.RegionSize

ユーザー モードの仮想メモリ アドレス空間全体をスキャンします。スキャンを停止する場合は、AllocationBase フィールドを確認してください。

于 2013-01-05T15:57:00.783 に答える