8

私は小さなソリティアトレーナーに取り組んでいます。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)
4

1 に答える 1

12

MSDN ReadProcessMemoryページへのコミュニティコメントを確認してください。quote (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.OpenProcessPyHANDLE破棄された一時的なものを返し、ハンドルが取得された後にハンドルを閉じます。

解決策は次を使用することです。

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

PROCESSその後、PyHANDLEオブジェクトを保持し、ハンドルは有効なままです。

于 2012-10-04T04:14:41.340 に答える