0

Windows API について学び始めたばかりで、特定のプロセスで値を読み取る簡単なプログラムを作成したいと考えています。

これが私のコードです

#include <stdio.h>
#include <Windows.h> 

void printError();

int main()
{
    int *buffer;

    // process input
    unsigned int pid = 0;
    printf("process ID : ");
    scanf("%d", &pid);
    getchar();
    HANDLE authorisation = OpenProcess(PROCESS_VM_READ, FALSE, pid);
    if(authorisation == NULL)
    {
        printf("OpenProcess Failed. GetLastError = %d", GetLastError());
        getchar();
        return EXIT_FAILURE;
    }   

    // adress memory input
    int *memoryAddress = 0x0;
    printf("memory address to read (in hexadecimal) : ");
    scanf("%p", &memoryAddress);
    getchar();
    printf("Reading from address : %p", memoryAddress);
    if(ReadProcessMemory(authorisation, (LPCVOID)memoryAddress, &buffer, 8, 
    NULL))
    {
        printf("\nptr2int = %p\n", buffer);
    }
    else
    {
        printError();    
    }

    int varInt = 0;
    // HERE IS THE PROBLEM
    // GetLastError return 6 : Invalid Handle 
    if(ReadProcessMemory(authorisation, (LPCVOID)buffer, &varInt, 
    sizeof(int), NULL))
    {
        printf("varInt = %d\n", varInt);
    }
    else
    {
        printError();
    }

    printf("Press ENTER to quit");
    getchar();

    return 0; 
}

void printError()
{
    printf("ReadProcessMemory Failed. GetLastError = %d", GetLastError());
    getchar();
    return EXIT_FAILURE;
}

ただし、RPM の 2 回目の呼び出し用に新しいハンドルを作成すると、完全に機能します。

MSDNでこれを読みました:

OpenProcess 関数によって返されるハンドルは、プロセスへのハンドルを必要とするすべての関数で使用できます。」

私は何を間違っていますか?

4

1 に答える 1

1

あなたの問題はこれです:

int *buffer;
unsigned int pid = 0;

ReadProcessMemory(authorisation, (LPCVOID)memoryAddress, &buffer, 8, NULL);

32 ビット アプリケーションをコンパイルしていて、ポインタが 4 バイトであるため、バッファのアドレスは 0x0 で、pid のアドレスは 0x4 であるとします。RPM を呼び出すと、8 バイトのサイズがハードコーディングされているため、pid が上書きされて無効になります。あなたは基本的にバッファオーバーフローしました。

ReadProcessMemory() を使用するときは常に sizeof(originalVariable) を引数のバイト数として使用する必要があるため、問題が発生することはありません。

他のプロセスのメモリに頻繁にアクセスする予定がある場合は、次の方法に従う必要があります。

uintptr_t を使用してアドレスを保存し、ターゲット プロセスのアーキテクチャに一致するようにアプリケーションをコンパイルします。x64 用にコンパイルすると 8 バイトになり、x86 では 4 バイトになります。必要に応じて、独自の typedef を作成することもできます。

ターゲット プロセスの同じアーキテクチャ用にコンパイルすることは、多くの点で役立ちます。これについては、この方法で簡単に操作できる WINAPI がいくつかあります。これを行う必要はありませんが、強くお勧めします。

于 2018-08-27T04:28:48.240 に答える