Pythonで他プロセスのメモリを読む

はじめに

Windows上のPythonで他のプロセスのメモリの内容を読んで見る
使うのはWin32apiで他の言語同様調べれば良い
今回はなんとなく斑鳩のスコアを読み出してみる
プレイ時間と同時に取れたらグラフ化したりしてモチベに繋がらないかなって思ったので
予めメモリの必要な番地は適当に調べておきます
今回はうさみみで調べておきました

読み方

プロセスを取ってハンドルを取得したらReadProcessMemoryを呼ぶだけ
読み出すだけならこんな感じにシンプルに書ける

 1from ctypes import windll, create_string_buffer
 2import time
 3import sys
 4
 5pid = 11111
 6
 7OpenProcess = windll.kernel32.OpenProcess
 8ReadProcessMemory = windll.kernel32.ReadProcessMemory
 9CloseHandle = windll.kernel32.CloseHandle
10PROCESS_ALL_ACCESS = 0x1F0FFF
11# ツールで見た時の番地
12address = 0x09412838
13size = 64
14buf = create_string_buffer(size)
15
16processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
17if ReadProcessMemory(processHandle, address, buf, size, None):
18    print buf.raw

斑鳩のスコアを読む

今回の目的の斑鳩はうさみみで調べると0x09412838からリトルエンディアンで入ってるみたいなのでひたすら読み出して変換して表示するだけ
こんな感じでスコアが取れる

 1# coding:utf-8
 2from ctypes import windll, create_string_buffer
 3import time
 4import sys
 5import struct
 6import win32gui
 7
 8def getProcessId(classname):
 9	result = []
10
11	def window(hwnd, a):
12		# if win32gui.IsWindowVisible(hwnd):
13		# 	print win32gui.GetClassName(hwnd)
14		# 	print win32gui.GetWindowText(hwnd)
15		if win32gui.GetClassName(hwnd) == classname:
16			result.append(win32process.GetWindowThreadProcessId(hwnd)[1])
17
18	win32gui.EnumWindows(window, None)
19	return result
20
21pid = getProcessId("Ikaruga")[0]
22
23OpenProcess = windll.kernel32.OpenProcess
24ReadProcessMemory = windll.kernel32.ReadProcessMemory
25CloseHandle = windll.kernel32.CloseHandle
26
27PROCESS_ALL_ACCESS = 0x1F0FFF
28# ツールで見た時の番地
29address = 0x09412838
30size = 64
31buf = create_string_buffer(size)
32
33processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
34
35while True:
36	if ReadProcessMemory(processHandle, address, buf, size, None):
37
38	    sys.stdout.write("\rScore: %d" % struct.unpack("<i", buf.raw[:4]))
39	    sys.stdout.flush()
40	else:
41	    sys.stdout.write("Failed")
42	    sys.stdout.flush()
43	time.sleep(0.1)
44
45CloseHandle(processHandle)