ReadProcessMemory с ctypes

Я работаю над небольшим тренером по игре в одиночку. Я не знаю, почему не работает функция ReadProcessMemory. Обычно он возвращает False или True, но в этом случае ничего. GetlastError() дает мне код ошибки 6.

#-*- coding: cp1252 -*-

import ctypes, win32ui, win32process ,win32api

PROCESS_ALL_ACCESS = 0x1F0FFF
HWND = win32ui.FindWindow(None,"Solitär").GetSafeHwnd()
print(HWND)
PID = win32process.GetWindowThreadProcessId(HWND)[1]
print(PID)
PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID).handle

rPM = ctypes.windll.kernel32.ReadProcessMemory
wPM = ctypes.windll.kernel32.WriteProcessMemory

ADDRESS1 = 0x00E97074
ADDRESS2 = ctypes.create_string_buffer(64)
pi = ctypes.pointer(ADDRESS2)
rPM(PROCESS,ADDRESS1,ADDRESS2,64,0)
print(ADDRESS2)
x=ctypes.windll.kernel32.GetLastError()
print(x)

person John Doe    schedule 03.10.2012    source источник
comment
Первое, что нужно попробовать, это установить тип возвращаемого значения функций в ctypes. Если вы не установите по умолчанию значение int и у вас есть bool. Во-вторых, ctypes действительно для C, а разве это не библиотека C++? Если это так, возможно, придется написать функции-оболочки C.   -  person Brian Larsen    schedule 04.10.2012
comment
Версия Python (похоже на 3.X)? версия для винды? 32- или 64-битная?   -  person Mark Tolonen    schedule 04.10.2012
comment
Это Python 3.2 и Win7 32bit! Какая именно библиотека C++?   -  person John Doe    schedule 04.10.2012


Ответы (1)


Проверьте комментарий сообщества к MSDN Страница ReadProcessMemory, цитата(sic):

W7 не будет запускать чтение памяти процесса

Возможно, вам потребуется проверить права доступа для SE_DEBUG_NAME для токена текущего процесса. Если не включен. Включил. Это должно быть сделано как администратор, конечно.

Также полностью объявите возвращаемые типы и используйте параметр use_last_error, где ctypes будет внутренне кэшировать значение GetLastError() сразу после вызова. В противном случае оно может быть неверным. Если вы работаете в 64-битной системе, SIZE_T и указатели являются 64-битными значениями, поэтому ctypes необходимо знать типы, чтобы правильно настроить стек для вызова.

...
from ctypes import wintypes
...
rPM = ctypes.WinDLL('kernel32',use_last_error=True).ReadProcessMemory
rPM.argtypes = [wintypes.HANDLE,wintypes.LPCVOID,wintypes.LPVOID,ctypes.c_size_t,ctypes.POINTER(ctypes.c_size_t)]
rPM.restype = wintypes.BOOL
wPM = ctypes.WinDLL('kernel32',use_last_error=True).WriteProcessMemory
wPM.argtypes = [wintypes.HANDLE,wintypes.LPVOID,wintypes.LPCVOID,ctypes.c_size_t,ctypes.POINTER(ctypes.c_size_t)]
wPM.restype = wintypes.BOOL

ADDRESS1 = 0x00E97074
ADDRESS2 = ctypes.create_string_buffer(64)
bytes_read = ctypes.c_size_t()
print(rPM(PROCESS,ADDRESS1,ADDRESS2,64,ctypes.byref(bytes_read)))
print(ctypes.get_last_error())

Кроме того, к вашему сведению, даже со всеми исправлениями я получаю одно и то же значение ошибки, но я не пытался включить SE_DEBUG_NAME.

РЕШЕНО

Следующая строка является проблемой:

PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID).handle

win32api.OpenProcess возвращает временный PyHANDLE, который уничтожается и закрывает дескриптор после получения дескриптора.

Решение заключается в использовании:

PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID)
...
rPM(PROCESS.handle,ADDRESS1,ADDRESS2,64,0)

PROCESS затем содержит объект PyHANDLE, и дескриптор остается действительным.

person Mark Tolonen    schedule 04.10.2012
comment
Привет, я попробовал DebugActiveProcess(PID). Я не знаю другой функции для активации SE_DEBUG_NAME. Я работаю над 32-битной системой. Кажется хитрым, я думаю здесь проблема между win7 и ctypes. - person John Doe; 04.10.2012
comment
Я написал вспомогательную функцию, чтобы включить привилегию, и проверил, что она установлена ​​через SysInternals ProcessExplorer. Я должен был быть администратором, чтобы сделать это. У меня все еще есть та же ошибка. Сейчас это сложная задача, поэтому я, вероятно, посмотрю на это снова сегодня вечером, убрав Python из поля зрения и используя только C. У меня это работало раньше, но не на Win7. - person Mark Tolonen; 04.10.2012
comment
Здравствуйте, Марк, когда я запускаю это: pastebin.com/dCaKiFht, это вывод: ▼ Согласно memoryviewer, это значение 31 @ Address1. Alt + 31 = ▼. Итак, вопрос: почему бы не запустить это с Solitär - person John Doe; 04.10.2012
comment
О нет, какая маленькая ошибка! Большое спасибо! - person John Doe; 07.10.2012
comment
Без проблем! В SO установите флажок «Проголосовать за» и «Принять», чтобы отметить ответ как полезный и правильный. Спасибо! - person Mark Tolonen; 07.10.2012