Using Python to learn win32 library for memory reading and writing

Keywords: C Python

Use according to the previous article Using Python to learn win32 library for memory reading and writing Using Python Win32 library, a game is read in memory.

Today, let's write the operation of writing to memory

text

For 32-bit reading and writing, first of all, we need to understand several functions to be used. Most of the functions found through Baidu are C/C + + data.

For a more detailed analysis, see the previous one.

The write function is WriteProcessMemory

This function can write to the memory area of a process (direct write will result in Access Violation error, so this function is required).

VC++ statement

BOOL WriteProcessMemory(
HANDLE hProcess,//Handle to the process memory to modify. Handle must have access to process vm write and process vm operation of the process
LPVOID lpBaseAddress,//Pointer to the base address in the specified process where data is written. Before data transfer, the system will verify that all data in the base address and memory of the specified size are available for write access, and if not, the function will fail.
LPVOID lpBuffer,//Pointer to the buffer containing the data to be written in the address space of the specified process
DWORD nSize,//The number of bytes to write to the specified process.
LPDWORD lpNumberOfBytesWritten//Pointer to a variable that receives the number of bytes transmitted to the specified process. This parameter is optional. If lpNumberOfBytesWritten is zero, this parameter is ignored.
);

Return value

If the function succeeds, the return value is nonzero
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError and the function will fail if the requested write crosses an inaccessible area of the process.

Read and write to single plant vs. zombie

Analysis of zombies in plant Wars

Plants vs. Zombies (1)

Plants vs. Zombies (2)

Plants vs. Zombies (3)

The first is reading the amount of sunlight

The base offset of sunlight is:

Sunshine: PlantsVsZombies.exe+2A9EC0+768+5560   

You can't read PlantsVsZombies.exe+2A9EC0 directly, so add the value to CE and check the hex value 006A9EC0 in the address bar


Reading and writing operation, similar to the writing method of the previous article

# -*- coding: utf-8 -*-
import win32process#Process module
from win32con import PROCESS_ALL_ACCESS #Opencress permission
import win32api#Call system module
import ctypes#C language type
from win32gui import FindWindow#Interface

def GetProcssID(address,bufflength):
    pid = ctypes.c_ulong()
    kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")
    hwnd = FindWindow(None,u"Chinese version of plant war zombie")
    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 ("The amount of sunlight:%d" % sun)

if __name__ == '__main__':
    main()

sun decomposition:

def main():
   	ret  = GetProcssID(0x006A9EC0,4)
    ret2 = GetProcssID(ret+0x768,4)
    sun = GetProcssID(ret2+0x5560,4)
    print ("The amount of sunlight:%d" % sun)
    #sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)

write

According to the previous analysis, Plants vs. Zombies can turn on automatic collection. The specific address is

Auto collection: PlantsVsZombies.exe+3158B initial value: 5274496 modified: 22051712
		Hex: 0043158B

Declare a function

def WriteMemeryInt(_address,Data):
	hGameHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    WriteProcessInt = kernel32.WriteProcessMemory // from kernel32 This function is invoked in the dynamic link library.
    WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)
    return Data

Code analysis:


    WriteProcessInt(int(hGameHandle),_address,ctypes.byref(ctypes.c_ulong(Data)),4,None)
    BOOL WriteProcessInt(
    int(hGameHandle),   //Incoming handle
    _address,   //Address to write
    ctypes.byref(ctypes.c_ulong(Data)),  //Data to write
    4,    //The number of bytes to write to the specified process.
    None  //Pointer to a variable that receives the number of bytes transmitted to the specified process. This parameter is optional. If lpNumberOfBytesWritten Is zero, the parameter is ignored.
    );



Modify the number of zombie sunshine in plant Wars


    def _modifySunshine():
        sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)
        sun_write = WriteMemeryInt(GetProcssID( GetProcssID( 0x006A9EC0, 4) + 0x768,4) + 0x5560, 100)
        print("Number of sunshine before modification:" , sun)
        if sun_write:
            print("###################Modification of sunshine quantity succeeded##############################")
            sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)
            print("Number of modified sunlight:" , sun)
        else:
            print("###################Failed to modify sunshine quantity, error message:##################",GetLastError)



Sun write decomposition method:


    def _modifySunshine():
        ret = GetProcssID(0x006A9EC0, 4)
        ret2 = GetProcssID(ret + 0x768, 4)
        sun_write = WriteMemeryInt(ret2+0x5560,100) 
        #ret2+0x5560 the address to be written cannot be read in GetProcessID, otherwise the written address is incorrect
        #100 is the number of modifications.
        if sun_write:
            print("###################Modification of sunshine quantity succeeded##############################")
        else:
            print("###################Failed to modify sunshine quantity, error message:##################",GetLastError)

Run code

# -*- coding: utf-8 -*-
import win32process#Process module
from win32con import PROCESS_ALL_ACCESS #Opencress permission
import win32api#Call system module
import ctypes#C language type
from win32gui import FindWindow#Interface

def GetProcssID(address,bufflength):
    pid = ctypes.c_ulong()
    kernel32 = ctypes.windll.LoadLibrary("kernel32.dll")
    hwnd = FindWindow(None,u"Chinese version of plant war zombie")
    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 // from kernel32 This function is invoked in the dynamic link library.
    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("Number of sunshine before modification:" , sun)
    if sun_write:
        print("###################Modification of sunshine quantity succeeded##############################")
        sun = GetProcssID(GetProcssID(GetProcssID(0x006A9EC0, 4)+0x768, 4)+0x5560, 4)
        print("Number of modified sunlight:" , sun)
    else:
        print("###################Failed to modify sunshine quantity, error message:##################",GetLastError)

def main():
    _modifySunshine()

if __name__ == '__main__':
    main()

This is the basic code. Next, change the code format according to the format I wrote in C, because it looks really messy

First, encapsulate the basic operation functions such as FindWindow

# -*- coding: utf-8 -*-
import win32process#Process module
from win32con import PROCESS_ALL_ACCESS #Opencress permission
import win32api#Call system module
import ctypes#C language type
from win32gui import FindWindow#Interface

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"Chinese version of plant war zombie")

    _hGameHandle = _GetPorcessHandle(ProcessId)

    win32api.CloseHandle(_hGameHandle)
   
if __name__ == '__main__':
    main()

In the start write function, first read the number of sunshine and modify the number of sunshine:

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("Number of sunshine before modification:" , sun)
    if sun_write:
        print("###################Modification of sunshine quantity succeeded##############################")
        sun = _ReadMemeryInt(hGameHandle,_ReadMemeryInt(hGameHandle, _ReadMemeryInt(hGameHandle, 0x006A9EC0, 4) + 0x768,4) + 0x5560, 4)
        print("Modified amount of sunlight:", sun)
    else:
        print("###################Failed to modify sunshine quantity, error message:##################",GetLastError)

Then, according to the analysis, it has the function of automatically collecting sunlight. The base site is:

Auto collection: PlantsVsZombies.exe+3158B initial value: 5274496 modified: 22051712
		Hex: 0043158B
def _collectSunshine(hGameHandle):
    collect = WriteMemeryInt(hGameHandle,0x0043158B,22051712)
    if collect:
        print("###################Auto collection started successfully#########################")
    else:
        print("###################Failed to modify the auto collection function, error message:##################",GetLastError)

Next is the second kill function, because it's not always defensible

Common zombie seckill base address:

Seckill ordinary Zombies: PlantsVsZombies.exe+13178A initial value: 1284214911 modified value: 1284214928  
			Hex: 0053178A
def _Seckill(hGameHandle):
    seckill = WriteMemeryInt(hGameHandle,0x0053178A,1284214928)
    if seckill:
        print("###################Start seckill ordinary zombie function successfully#########################")
    else:
        print("###################Failed to modify seckill function, error message:#########################",GetLastError)

In addition to ordinary zombies, there are helmets:

Helmet zombie base:

Seckill with armor: PlantsVsZombies.exe+13186D initial value: 1347618942 modified: 1347653776  
			Hex: 0053186D
def _SecKillHelmet(hGameHandle):
    seckillHelemet = WriteMemeryInt(hGameHandle,0x53186D ,1347653776)
    if seckillHelemet:
        print("###################Start seckill helmet zombie function successfully#########################")
    else:
        print("###################Failed to modify the helmet zombie seckill function, error message:#################",GetLastError)

**Complete code: * * it's not intended to drain when you go to the blog. You can also splice it according to the above, because I don't know if you can send it.

Run code:

Ending

reminder:

Protect yourself actively. Wear masks and wash hands frequently.

Read more microblogs and search for official information. Don't take rumors lightly.

To borrow a good sentence:

Technology is right and wrong. Human nature is good and evil

He who learns the opposite must be in the right place

A man with a proper mind and body holds a dragon slaying knife, which is also a guardian of his family

Take advantage of this time to stay at home and study hard to study how to pass the third-party test.

Published 2 original articles, won praise 2, visited 8223
Private letter follow

Posted by kylebud on Fri, 24 Jan 2020 01:57:45 -0800