python有哪些库可以读写内存_使用Python学习win32库进行内存读写2

根据上一篇 使用Python读写游戏1 中,使用Python win32库,对一款游戏进行了读内存 操作。

今天来写一下对内存进行写的操作

正文

要进行32位的读写,首先了解一下要用到的几个函数,通过百度找到的,大多都是C/C++的资料。

更详细的分析看上一篇。

写入函数 是 WriteProcessMemory

此函数能写入某一进程的内存区域(直接写入会出Access Violation错误,故需此函数)。

VC++声明

BOOL WriteProcessMemory(

HANDLE hProcess,//要修改的进程内存的句柄。句柄必须具有对进程的进程_vm_写和进程_vm_操作的访问权限

LPVOID lpBaseAddress,//指向写入数据的指定进程中的基地址的指针。在进行数据传输之前,系统将验证指定大小的基址和内存中的所有数据都可用于写访问,如果无法访问,则函数将失败。

LPVOID lpBuffer,//指向缓冲区的指针,其中包含要在指定进程的地址空间中写入的数据

DWORD nSize,//要写入指定进程的字节数。

LPDWORD lpNumberOfBytesWritten//指向接收传输到指定进程的字节数的变量的指针。此参数是可选的。如果lpNumberOfBytesWritten是零,则忽略该参数。

);

返回值

如果函数成功,则返回值为非零

如果函数失败,则返回值为0(零)。若要获取扩展错误信息,请调用GetLastError,如果请求的写操作跨入进程中无法访问的区域,则函数将失败。

对单机植物大战僵尸进行读取与写入操作

对植物大战僵尸分析,请看

首先是对阳光数量的读取

阳光的基址偏移是:

阳光:PlantsVsZombies.exe+2A9EC0+768+5560

不能直接读PlantsVsZombies.exe+2A9EC0,所以把该值添加到CE中,查看地址栏中的十六进制值 006A9EC0

image

读写操作,与上一篇文章写法相似

# -*- 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()

kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")

hwnd = FindWindow(None,u"植物大战僵尸中文版")

ReadProcessMemory = kernel32.ReadProcessMemory

hpid, pid = win32process.GetWindowThreadProcessId(hwnd)

hProcess = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

addr = ctypes.c_ulong()

ReadProcessMemory(int(hProcess), address, ctypes.byref(addr), bufflength, None)

win32api.CloseHandle(hProcess)

return addr.value

def main():

sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

print ("阳光的数量:%d" % sun)

if __name__ == '__main__':

main()

sun 分解写法:

def main():

ret = GetProcssID(0x006A9EC0,4)

ret2 = GetProcssID(ret+0x768,4)

sun = GetProcssID(ret2+0x5560,4)

print ("阳光的数量:%d" % sun)

#sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

image

根据之前的分析,植物大战僵尸可以开启自动收集功能。具体的地址是

自动收集:PlantsVsZombies.exe+3158B 初始值:5274496 修改后:22051712

十六进制:0043158B

声明一个函数

def WriteMemeryInt(_address,Data):

hGameHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

WriteProcessInt = kernel32.WriteProcessMemory // 从kernel32动态链接库中调用这个函数

WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)

return Data

代码分析:

WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)

BOOL WriteProcessInt(

int(hGameHandle), //传入的句柄

_address, //要写入的地址

ctypes.byref(ctypes.c_ulong(Data)), //要写入的数据

4, //要写入指定进程的字节数。

None //指向接收传输到指定进程的字节数的变量的指针。此参数是可选的。如果lpNumberOfBytesWritten是零,则忽略该参数。

);

修改植物大战僵尸阳光数量

def _modifySunshine():

sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

sun_write = WriteMemeryInt(GetProcssID( GetProcssID( 0x006A9EC0, 4) + 0x768,4) + 0x5560, 100)

print("修改前阳光的数量:" , sun)

if sun_write:

print("###################修改阳光数量成功##############################")

sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

print("修改后阳光的数量:" , sun)

else:

print("###################修改阳光数量失败,错误信息:##################",GetLastError)

sun_write 分解写法:

def _modifySunshine():

ret = GetProcssID(0x006A9EC0, 4)

ret2 = GetProcssID(ret + 0x768, 4)

sun_write = WriteMemeryInt(ret2+0x5560,100)

#ret2+0x5560 要写入的地址,不能在GetProcessID读取,不然写入的地址就不正确

#100 为修改的数量。

if sun_write:

print("###################修改阳光数量成功##############################")

else:

print("###################修改阳光数量失败,错误信息:##################",GetLastError)

运行代码

image

# -*- 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()

kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")

hwnd = FindWindow(None,u"植物大战僵尸中文版")

ReadProcessMemory = kernel32.ReadProcessMemory

hpid, pid = win32process.GetWindowThreadProcessId(hwnd)

hProcess = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

addr = ctypes.c_ulong()

ReadProcessMemory(int(hProcess), address, ctypes.byref(addr), bufflength, None)

win32api.CloseHandle(hProcess)

return addr.value

def WriteMemeryInt(_address,Data):

hGameHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

WriteProcessInt = kernel32.WriteProcessMemory // 从kernel32动态链接库中调用这个函数

WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)

return Data

def _modifySunshine():

sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

sun_write = WriteMemeryInt(GetProcssID(GetProcssID( 0x006A9EC0, 4) + 0x768,4) + 0x5560, 100)

print("修改前阳光的数量:" , sun)

if sun_write:

print("###################修改阳光数量成功##############################")

sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

print("修改后阳光的数量:" , sun)

else:

print("###################修改阳光数量失败,错误信息:##################",GetLastError)

def main():

_modifySunshine()

if __name__ == '__main__':

main()

基本代码就这些了,接下来按照我写C的格式,把代码格式改一下,因为看起来真的挺乱的

先把FindWindow 等基础操作用函数给封装

# -*- coding: utf-8 -*-

import win32process#进程模块

from win32con import PROCESS_ALL_ACCESS #Opencress 权限

import win32api#调用系统模块

import ctypes#C语言类型

from win32gui import FindWindow#界面

kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")

GetLastError = kernel32.GetLastError

def _GetProcessId(className,windowName):

hGameWindow = FindWindow(className, windowName)

pid = win32process.GetWindowThreadProcessId(hGameWindow)[1]

return pid

def _GetPorcessHandle(pid):

hGameHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

return hGameHandle

def _ReadMemeryInt(hGameHandle,_address,bufflength):

addr = ctypes.c_ulong()

ReadProcessInt = kernel32.ReadProcessMemory

ReadProcessInt(int(hGameHandle), _address, ctypes.byref(addr), bufflength, None)

return addr.value

def WriteMemeryInt(hGameHandle,_address,Data):

WriteProcessInt = kernel32.WriteProcessMemory

WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)

return Data

def main():

ProcessId = _GetProcessId(None,u"植物大战僵尸中文版")

_hGameHandle = _GetPorcessHandle(ProcessId)

win32api.CloseHandle(_hGameHandle)

if __name__ == '__main__':

main()

在开始写功能,先是读取阳光数量和修改阳光数量:

def _modifySunshine(hGameHandle):

sun = _ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle,0x006A9EC0, 4) + 0x768, 4) + 0x5560, 4)

sun_write = WriteMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle, _ReadMemeryInt(hGameHandle, 0x006A9EC0, 4) + 0x768,4) + 0x5560, 100)

print("修改前阳光的数量:" , sun)

if sun_write:

print("###################修改阳光数量成功##############################")

sun = _ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle, _ReadMemeryInt(hGameHandle, 0x006A9EC0, 4) + 0x768,4) + 0x5560, 4)

print("修改后的阳光数量:", sun)

else:

print("###################修改阳光数量失败,错误信息:##################",GetLastError)

接着,根据分析,有自动收集阳光功能,基址是:

自动收集:PlantsVsZombies.exe+3158B 初始值:5274496 修改后:22051712

十六进制:0043158B

def _collectSunshine(hGameHandle):

collect = WriteMemeryInt(hGameHandle,0x0043158B,22051712)

if collect:

print("###################启动自动收集功能成功#########################")

else:

print("###################修改自动收集功能失败,错误信息:##################",GetLastError)

接下来是秒杀功能,因为不一定每次都守得住

普通僵尸秒杀基址:

秒杀普通僵尸: PlantsVsZombies.exe+13178A 初始值:1284214911 修改后:1284214928

十六进制:0053178A

def _Seckill(hGameHandle):

seckill = WriteMemeryInt(hGameHandle,0x0053178A,1284214928)

if seckill:

print("###################启动秒杀普通僵尸功能成功#########################")

else:

print("###################修改秒杀功能失败,错误信息:#########################",GetLastError)

除了普通僵尸,还有头盔僵尸:

头盔僵尸基址:

秒杀带护甲: PlantsVsZombies.exe+13186D 初始值:1347618942 修改后:1347653776

十六进制:0053186D

def _SecKillHelmet(hGameHandle):

seckillHelemet = WriteMemeryInt(hGameHandle,0x53186D ,1347653776)

if seckillHelemet:

print("###################启动秒杀头盔僵尸功能成功#########################")

else:

print("###################修改头盔僵尸秒杀功能失败,错误信息:#################",GetLastError)

完整代码:

# -*- coding: utf-8 -*-

import win32process#进程模块

from win32con import PROCESS_ALL_ACCESS #Opencress 权限

import win32api#调用系统模块

import ctypes#C语言类型

from win32gui import FindWindow#界面

kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")

GetLastError = kernel32.GetLastError

def _GetProcessId(className,windowName):

hGameWindow = FindWindow(className, windowName)

pid = win32process.GetWindowThreadProcessId(hGameWindow)[1]

return pid

def _GetPorcessHandle(pid):

hGameHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

return hGameHandle

def _ReadMemeryInt(hGameHandle,_address,bufflength):

addr = ctypes.c_ulong()

ReadProcessInt = kernel32.ReadProcessMemory

ReadProcessInt(int(hGameHandle), _address, ctypes.byref(addr), bufflength, None)

return addr.value

def WriteMemeryInt(hGameHandle,_address,Data):

WriteProcessInt = kernel32.WriteProcessMemory

WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)

return Data

def _modifySunshine(hGameHandle):

sun = _ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle,0x006A9EC0, 4) + 0x768, 4) + 0x5560, 4)

sun_write = WriteMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle, _ReadMemeryInt(hGameHandle, 0x006A9EC0, 4) + 0x768,4) + 0x5560, 100)

print("修改前阳光的数量:" , sun)

if sun_write:

print("###################修改阳光数量成功##############################")

sun = _ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle, _ReadMemeryInt(hGameHandle, 0x006A9EC0, 4) + 0x768,4) + 0x5560, 4)

print("修改后的阳光数量:", sun)

else:

print("###################修改阳光数量失败,错误信息:##################",GetLastError)

def _collectSunshine(hGameHandle):

collect = WriteMemeryInt(hGameHandle,0x0043158B,22051712)

if collect:

print("###################启动自动收集功能成功#########################")

else:

print("###################修改自动收集功能失败,错误信息:##################",GetLastError)

def _Seckill(hGameHandle):

seckill = WriteMemeryInt(hGameHandle,0x0053178A,1284214928)

if seckill:

print("###################启动秒杀普通僵尸功能成功#########################")

else:

print("###################修改秒杀功能失败,错误信息:#########################",GetLastError)

def _SecKillHelmet(hGameHandle):

seckillHelemet = WriteMemeryInt(hGameHandle,0x53186D ,1347653776)

if seckillHelemet:

print("###################启动秒杀头盔僵尸功能成功#########################")

else:

print("###################修改头盔僵尸秒杀功能失败,错误信息:#################",GetLastError)

def main():

ProcessId = _GetProcessId(None,u"植物大战僵尸中文版")

_hGameHandle = _GetPorcessHandle(ProcessId)

_modifySunshine(_hGameHandle)

_collectSunshine(_hGameHandle)

_Seckill(_hGameHandle)

_SecKillHelmet(_hGameHandle)

win32api.CloseHandle(_hGameHandle)

if __name__ == '__main__':

main()

运行代码:

image

结尾

借用一句看到很不错的话:

技术不分对错.人性才分善恶.

学习逆向的人必须身心放正.

身心放正之人手握屠龙刀,也是保家卫民.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值