前言:
上一周,在52的精華帖中,看到有位大佬用Python制作了鬼泣5的修改器,看完才知道,原來Python也可以對內存進行操作,出於對技術的好奇,看完以后,決定自己也嘗試一下。
要用到的工具:
CE,Ollybdg,
用Python,讀取這款游戲中,人物的血量。
先打開游戲吧,打開CE,對游戲附加。


輸入199在輸入框中,先進行一次掃描

接着去打怪,扣血以后在進行一次掃描

等一會,人物會自動回血,然后你會神奇的發現,這兩個數據中有一個的數值會變成199,然后上次數值哪里顯示198,那就是我們要找的數據
26B871F0

打開OD,把地址放在里面搜索,斷點,然后使用巴拉拉魔法力量,找出偏移量
[[[[D0DF1C]+1C]+28]+288]

……………………………………………………………………………………………………………………………………………………………
現在開始進入Python
要進行32位的讀寫,首先了解一下要用到的幾個函數,通過百度找到的,大多都是C/C++的資料。
FindWindowA在Python中為FindWindow
FindWindow這個函數檢索處理頂級窗口的類名和窗口名稱匹配指定的字符串。這個函數不搜索子窗口。
HWND FindWindowA(
LPCSTR lpClassName,//窗口類名
LPCSTR lpWindowName//窗口名稱,例如計算器
);
GetWindowThreadProcessId
在得到窗口句柄后我們可以通過GetWindowThreadProcessId這個函數來獲得窗口所屬進程ID和線程ID,從而判斷創建窗口的進程和線程。
DWORD GetWindowThreadProcessId(
HWND hWnd, //傳入的窗口句柄
LPDWORD lpdwProcessId //返回的進程ID地址。
);
OpenProcess
OpenProcess 函數用來打開一個已存在的進程對象,並返回進程的句柄。
HANDLE OpenProcess(
DWORD dwDesiredAccess, //想擁有的該進程訪問權限
BOOL bInheritHandle,//表示所得到的進程句柄是否可以被繼承
DWORD dwProcessId//被打開進程的PID
);
ReadProcessMemory
是一個內存操作函數, 其作用為根據進程句柄讀入該進程的某個內存空間;函數原型為BOOL. 當函數讀取成功時返回1, 失敗則返回0
BOOL ReadProcessMemory(
HANDLE hProcess, //進程句柄
LPCVOID lpBaseAddress,//讀出數據的地址
LPVOID lpBuffer,//存放讀取數據的地址
SIZE_T nSize,//讀出的數據大小
SIZE_T *lpNumberOfBytesRead//數據的實際大小
);
首先導入模塊
# -*- coding: utf-8 -*-
import win32process#進程模塊
from win32con import PROCESS_ALL_ACCESS #Opencress 權限
import win32api#調用系統模塊
import ctypes#C語言類型
from win32gui import FindWindow#界面
對游戲的一個讀操作,讀取血量。
def GetProcssID(address,bufflength):
pid = ctypes.c_ulong() // 設置 pid 為 無符號單精度類型
kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")//加載動態鏈接庫
hwnd = FindWindow("XYElementClient Window", u"口袋西游")//獲取窗口句柄
hpid, pid = win32process.GetWindowThreadProcessId(hwnd)//獲取窗口ID
hProcess = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)//獲取進程句柄
ReadProcessMemory = kernel32.ReadProcessMemory
addr = ctypes.c_ulong()
ReadProcessMemory(int(hProcess), address, ctypes.byref(addr), bufflength, None)//讀內存
win32api.CloseHandle(hProcess)//關閉句柄
return addr.value
def main():
addr = GetProcssID(0xD0DF1C, 4)
ret = addr + 0x1C
ret2 = GetProcssID(ret, 4)
ret3 = ret2 + 0x28
ret4 = GetProcssID(ret3, 4)
ret5 = ret4 + 0x288
ret6 = GetProcssID(ret5, 4) // 傳入偏移地址
print ("Hp:%d" % ret6)
if __name__ == '__main__':
main()
ReadProcessMemory(int(hProcess), address, ctypes.byref(addr), bufflength, None)
參數解析:1.傳入進程句柄 2.地址,就是血量的地址,那幾條偏移. 3. 第三個要傳入指針 。4.長度
運行結果:
