5

サードパーティアプリケーションのメモリをスキャンしようとしています。私はすでに住所を知っています。現在はにあり0x0643FB78ます。LPMODULEENTRY32->modBaseAddr問題は、であり0x00400000LPMODULEENTRY32->modBaseSize単にであるため、そこに到達することはできません0x006FF000。したがって、このモジュールでスキャンできる最大アドレスはです0x00AFF000

それは、私が探しているアドレスが別のプロセス/モジュール/スレッド/何かの中にあることを意味しますか?私が持っているプロセスにはアドレスが含まれていると確信しています。では、どのようにメモリにアクセスする必要がありますか?ありがとうございました。

4

2 に答える 2

12

少なくとも私の意見では、あなたがLPMODULEENTRY関与している場合、あなたはおそらく間違った方向から始めています。代わりに、ターゲットプロセスのメモリブロックをウォークスルーしますVirtualQueryEx。これによりMEMORY_BASIC_INFORMATION、そのプロセスの各ブロックについての情報が得られます。次に、ブロックを使用ReadProcessMemoryしてスキャンし、探しているものを見つけることができます。

これは、ほぼ同じことを行うために作成した古いコードですが、ポインターではなく文字列を探しています。

#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>

template <class InIter1, class InIter2, class OutIter>
void find_all(unsigned char *base, InIter1 buf_start, InIter1 buf_end, InIter2 pat_start, InIter2 pat_end, OutIter res) {
    for (InIter1 pos = buf_start;
        buf_end!=(pos=std::search(pos, buf_end, pat_start, pat_end));
        ++pos)
    {
        *res++ = base+(pos-buf_start);
    }
}

template <class outIter>
void find_locs(HANDLE process, std::string const &pattern, outIter output) {

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for ( p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        std::vector<char> buffer;

        if (info.State == MEM_COMMIT && 
            (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE)) 
        {
            SIZE_T bytes_read;
            buffer.resize(info.RegionSize);
            ReadProcessMemory(process, p, &buffer[0], info.RegionSize, &bytes_read);
            buffer.resize(bytes_read);
            find_all(p, buffer.begin(), buffer.end(), pattern.begin(), pattern.end(), output);
        }
    }
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <process ID> <pattern>", argv[0]);
        return 1;
    }

    int pid;
    sscanf(argv[1], "%i", &pid);

    std::string pattern(argv[2]);

    HANDLE process = OpenProcess( 
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 
        false,
        pid);

    find_locs(process, pattern, 
        std::ostream_iterator<void *>(std::cout, "\n"));

    return 0;
}
于 2012-04-29T15:05:48.420 に答える
4

プロセスは、特定の保護でマップされたメモリのページで構成されます。これらのページはモジュールにカプセル化されています。各モジュールにはベースとサイズがあります。ただし、ReadProcessMemoryはこれを完全に抽象化します。どのモジュールにあるかに関係なく、メモリを読み取ることができるはずです。

この場合、メモリはあなたが見ているモジュールにありません。それがどこに属するかを見つける必要がある場合は、CreateToolHelp32Snapshot、Module32First、およびModule32Nextを使用して、ベースとサイズをチェックするモジュールを反復処理できます。

いくつかのコードを投稿してください。どこが間違っているのかを見つけるお手伝いをします。なぜあなたはあなたが探しているものの住所があなたが述べている住所であると確信しているのですか?ASLRのため、アドレスはベースモジュール+オフセットで指定されることがよくあります。ターゲットプロセスのハンドルをどのように取得していますか?ReadProcessMemoryを使用するには、特定のアクセス権が必要です。

于 2012-04-29T14:32:21.483 に答える