TL;DR
まとめただけなのでこの記事にあまり価値はないです
ctypes大事
環境
OS:Windows 10
Python:3.9.0
スクショ取得
pillowを使います
from PIL import ImageGrab
def get_screenshot():
region=get_region() #こちらは各自で実装してください
img=ImageGrab.grab(region)
return region
キー入力
pyautoguiを使うを失敗します(原因わからん)
なのでctypesを利用して直接win32apiをたたきます。
そこでこの記事
(日本語英語以外を毛嫌いしてたら一生見なかったかも)
コード抜粋、変更
import ctypes
PUL = ctypes.POINTER(ctypes.c_ulong)
key = {"up":0x48, "down":0x50, "left":0x4D, "right":0x4B,"z":0x2C,"Enter":0x1C,"Shift":54}
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def PressKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))
x = Input(ctypes.c_ulong(1), ii_)
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
x = Input(ctypes.c_ulong(1), ii_)
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))
プロセスメモリ参照
うさみみハリケーンで実験を行った後にReadProcessMemory関数でメモリ参照を行います。
ただ正直よくわからなかったので下の記事を参考に必要部分のみをコードに書き起こしました。
以下抜粋コード(コピペばかりでごめんなさい)
defines.py
from ctypes import *
# types
DWORD = c_ulong
PVOID = c_void_p
ULONG_PTR = c_ulong
LONG = c_long
# constant
INFINITE = 0xFFFFFFFF
DBG_CONTINUE = 0x00010002
DBG_EXCEPTION_NOT_HANDLED = 0x80010001
PROCESS_ALL_ACCESS= ( 0x000F0000 ) | ( 0x00100000 ) |0xFFFF #ここだけ追加
class EXCEPTION_RECORD(Structure):
pass
EXCEPTION_RECORD._fields_ = [
("ExceptionCode", DWORD),
("ExceptionFlags", DWORD),
("ExceptionRecord", POINTER(EXCEPTION_RECORD)),
("ExceptionAddress", PVOID),
("NumberParameters", DWORD),
("ExceptionInformation", ULONG_PTR*15),
]
class EXCEPTION_RECORD(Structure):
_fields_ = [
("ExceptionCode", DWORD),
("ExceptionFlags", DWORD),
("ExceptionRecord", POINTER(EXCEPTION_RECORD)),
("ExceptionAddress", PVOID),
("NumberParameters", DWORD),
("ExceptionInformation", ULONG_PTR*15),
]
class EXCEPTION_DEBUG_INFO(Structure):
_fields_ = [
("ExceptionRecord", EXCEPTION_RECORD),
("dwFirstCance", DWORD),
]
class U(Union):
_fields_ = [
("Exception", EXCEPTION_DEBUG_INFO),
]
class DEBUG_EVENT(Structure):
_fields_ = [
("dwDebugEventCode", DWORD),
("dwProcessId", DWORD),
("dwThreadId", DWORD),
("u", U),
]
class LUID(Structure):
_fields_ = [
("LowPart", DWORD),
("HighPart", LONG),
]
class LUID_AND_ATTRIBUTES(Structure):
_fields_ = [
("Luid", LUID),
("Attributes", DWORD),
]
class TOKEN_PRIVILEGES(Structure):
_fields_ = [
("PrivilegeCount", DWORD),
("Privileges", LUID_AND_ATTRIBUTES),
]
from ctypes import *
from defines import *
#from privilege import set_debug_privilege
#from page_protection import get_page_info, set_page_protection, show_protection
kernel32 = windll.kernel32
#set_debug_privilege() #書かなくても動いたけど、場合によっては必要かも
def open_process(pid):
h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if not h_process:
print(WinError(GetLastError()))
return False
return h_process
def read_process_memory(h_process, address, length):
data = None
read_buf = create_string_buffer(length)
count = c_ulonglong(0)
if not kernel32.ReadProcessMemory(h_process, address, read_buf, length, byref(count)):
print(WinError(GetLastError()))
return False
else:
data += str(read_buf.raw)
return data
def address_main():
pid = input("pid: ")#後述の方法で自動化可能
h_process = open_process(int(pid))
address=0x004F7844
data = read_process_memory(h_process, address, 1)
print(data)
if __name__ == "__main__":
address_main()
実行時の残基を表示するコードです
PID取得
tasklistコマンドを使う
東方輝針城の場合
tasklist | find "th14.exe"
以下実行結果例
th14.exe 16984 Console 1 159,780 K
これを加工すればpython側で自動取得できます
import subprocess
def get_pid():
r=subprocess.run("tasklist | find \"th14.exe\"",shell=True,stdout=subprocess.PIPE)
return int(r.split()[1].stdout.decode())
追記
新規の情報ほぼ0のしょうもない記事すぎる...