ReadProcessMemory с адресом __int64

Привет, ребята, я хочу получить немного памяти из процесса, который я уже знаю с CheatEngine. Я определил область, которую хочу сканировать (0x190D186FF->0x190D1870A), но адрес слишком велик для хранения в простом int. Вот почему я использую __int64, но с этой модификацией ReadProcessMemory больше не обрабатывает адрес.

При компиляции я получил 3 предупреждения для VirtualProtectEx и ReadProcessMemory: приведение к указателю из целого числа разного размера

Как я могу прочитать действительно большой адрес из памяти?

int main( int argc, char *argv[] ) {
HWND            hWnd;
DWORD           PID;
HANDLE          hProc;
__int64         address;
char            mem = 0;
PDWORD          oldProtect = 0;
int             valid = 0;
char            inputPID[4];

printf( "What is the program PID ?\n" );
fgets( inputPID, sizeof( inputPID ), stdin );
PID = (DWORD)atoi( inputPID );

hProc = OpenProcess( PROCESS_VM_READ, false, PID );

if ( !hProc ) {
    printf( "Error: Couldn't open process '%i'\n", PID );
    return 0;
}

for ( address = 0x190D186FF; address <= 0x190D1870A; address++ ) {

    VirtualProtectEx( hProc, (PVOID)address, (SIZE_T)sizeof( address ), PAGE_READONLY, oldProtect );

    valid = ReadProcessMemory( hProc, (PCVOID)address, &mem, (DWORD)sizeof( char ), NULL );

    if ( valid ) {
        printf( "Memory value at 0x%I64x: '%c'\n", address, mem );
    }

    VirtualProtectEx( hProc, (PVOID)address, (SIZE_T)sizeof( address ), (DWORD)oldProtect, NULL );
}

system( "pause" );

}


person Zenny H.    schedule 25.09.2016    source источник
comment
Вам нужно скомпилировать как 64-битный процесс.   -  person Ben    schedule 05.10.2016
comment
У меня 64-битная ОС, поэтому я думаю, что по умолчанию компилируется 64-битный процесс. (+ я пробовал с -m64, и у меня не реализовано: 64-битный режим не скомпилирован в blablabla)   -  person Zenny H.    schedule 05.10.2016
comment
У меня 64-битная ОС, поэтому я думаю, что компилировать 64-битный процесс по умолчанию - это не гарантия. Чтобы убедиться, что вы получаете 64-битный исполняемый файл, вам, вероятно, придется явно настроить свой компилятор для 64-битного вывода, предполагая, что у него даже есть такая опция. В зависимости от настроек вашего компилятора он может создавать 32-битный исполняемый файл при работе в 64-битной ОС и 64-битный исполняемый файл при работе в 32-битной ОС.   -  person Remy Lebeau    schedule 09.07.2020


Ответы (1)


Ваша проблема в том, что вы пытаетесь втиснуть 64-битные данные в 32-битные переменные. Вам нужно переключить свой проект на сборку x64.

Ваш компилятор не компилируется автоматически как x64 в 64-битной ОС. Вам нужно изменить тип сборки конфигурации для компиляции для x64.

Есть 2 способа облегчить себе задачу.

1) Скомпилируйте для той же архитектуры процесса, что и процесс, с которым вы собираетесь взаимодействовать, это устраняет многие проблемы. Используйте uintptr_t или UINT_PTR, которые разрешат правильный размер указателя, 32-битный или 64-битный, в зависимости от того, для чего вы компилируете, для всех ваших адресов и смещений.

2) Создайте свой собственный TYPEDEF, например

#define TARGET_X64

#ifdef TARGET_X64
typedef unsigned __int64 addr_ptr
#else
typedef unsigned int addr_ptr
#endif

Затем определите TARGET_X64, когда вы взаимодействуете с процессом x64. Если вы делаете это так и компилируете как x32, есть определенные API, которые имеют сложности при доступе к процессам x64 и наоборот.

Я настоятельно рекомендую использовать первый метод.

person GuidedHacking    schedule 07.02.2018