首页 > 其他分享 >植物大战僵尸阳光调整教程

植物大战僵尸阳光调整教程

时间:2024-12-26 15:57:30浏览次数:8  
标签:教程 游戏 句柄 大战 修改 阳光 ctypes 进程 僵尸

这是一篇AI文章,其中代码是我两年前所写,但博文本人懒得写了

一、引言

《植物大战僵尸》作为一款风靡全球的经典塔防游戏,以其丰富的玩法和策略性深受广大玩家喜爱。在游戏中,阳光作为关键资源,用于购买各种植物来抵御僵尸的进攻,其重要性不言而喻。然而,获取阳光的过程有时会受到僵尸的干扰,导致资源紧张,影响游戏体验。因此,不少玩家对如何修改阳光值产生了兴趣,今天我们就来探讨一下使用 Python 实现植物大战僵尸阳光修改的方法。需要注意的是,修改游戏数据仅用于学习交流目的,请勿在未经授权的情况下用于商业或其他不正当用途,同时也要遵守游戏的使用条款和相关法律法规。

二、准备工作

在开始修改之前,我们需要准备好相应的工具和环境:
Python:这是我们实现修改功能的主要编程语言。如果你还没有安装 Python,请前往 Python 官方网站(https://www.python.org/downloads/)下载并安装适合你操作系统的版本,建议选择较新的稳定版本,如 Python 3.8 及以上。
win32gui、win32process、win32api、ctypes 库:这些库可以帮助我们与 Windows 系统进行交互,实现对游戏进程内存的读取和写入操作,从而达到修改阳光值的目的。它们通常包含在pywin32扩展库中。如果你的 Python 环境中尚未安装pywin32,可以通过以下命令使用pip进行安装:

pip install pywin32

安装完成后,在 Python 脚本中通过import语句导入这些库即可使用:

import win32process
import win32api
import ctypes

三、寻找阳光值内存地址

3.1 使用 CE 工具

CE(Cheat Engine)是一款功能强大且备受游戏玩家喜爱的内存修改工具,在修改《植物大战僵尸》阳光值这件事上,它可是关键角色。下面就来详细讲讲它的基本使用方法:
首先,要打开《植物大战僵尸》游戏,接着启动 CE 工具 。在 CE 界面左上角,有一个类似电脑图标的按钮,点击它,就会弹出进程列表,从中找到 “植物大战僵尸” 的进程,选中后点击 “打开”,这样就把 CE 附加到游戏进程上了。
游戏刚开始时,留意一下左上角的阳光数量,假设此时是 50 ,就在 CE 的 “数值” 输入框里填入 50 ,然后点击 “首次扫描”。这时候,CE 会对游戏内存展开搜索,不过通常会搜出一堆结果。别着急,继续游戏,当点击掉落的阳光后,阳光数变为了 75 ,再把 75 输入到 CE 里,点击 “再次扫描”。运气好的话,经过这么两轮操作,结果可能就只剩一个了,这个大概率就是存放当前阳光的地址。
但这个地址还不是基址,它是动态地址,重启游戏就失效了。所以,我们得进一步找出基址。右键单击这个找到的地址,在弹出菜单里点击 “找出是什么改写了这个地址” 。这时候,调试器会附加到当前进程,切回游戏种一棵向日葵,再切回 CE,就能看到相关指令了。双击某一行指令查看详细信息,里面会有类似 5560 这样的指针偏移量,先把它记住。
回到 CE 主界面,点击 “新的扫描”,勾选搜索框左边的 “Hex”,把刚才得到的类似 1D200FE0 这样的地址填进去,点击 “首次扫描”,会出来一批结果。这里面,要找那种看起来和其他大部分地址明显不同的,还可以对可能的地址右键 “找出是什么访问了这个地址”,逐一排查。当发现指令比较规整的时候,基本就八九不离十了。比如又找到一个新的偏移量 768,以及可能的基址 006A9EC0 。最后,点击 “手动添加地址”,勾选 “指针”,按顺序把基址、偏移量依次填好,单击 “确定”,就完成了寻找阳光基址的关键步骤。通过这样的流程,后续就能稳定修改阳光值了。

3.2 理解内存地址的意义

在《植物大战僵尸》里,找到的内存地址与阳光值有着紧密且精妙的存储关系。从游戏编程的角度看,阳光值这类游戏数据,并不是随意散落在内存中的,而是遵循着特定的存储规则。我们找到的内存地址,就像是指向阳光值这个宝藏的路标。
动态地址是游戏运行时分配给阳光值的临时存放点,每次重启游戏,这个动态地址就像变换了藏匿处,之前找到的就失效了,这就是为什么我们还得深挖基址。而基址呢,它相当于一个固定的 “大本营”,无论游戏怎么重启,它在内存中的位置都雷打不动。通过基址加上偏移量的方式,就能精准定位到阳光值所在的内存位置。
打个比方,基址如同小区的固定门牌号,偏移量则是楼号、楼层与房间号这些具体信息,组合起来,就能毫无偏差地找到阳光值这个 “住户”。理解了这种存储关系,我们就能明白修改阳光值代码的工作原理,后续编写或运用相关代码时,也能更得心应手,精准对游戏中的阳光数据进行修改,获得别样的游戏体验。

四、编写 Python 代码实现阳光修改

4.1 导入必要的模块

在 Python 中,我们需要导入win32gui、win32process、win32api和ctypes这些模块来实现对植物大战僵尸游戏进程的操作和内存的读写,从而达到修改阳光值的目的。
win32gui模块提供了一系列用于操作 Windows 图形用户界面(GUI)的函数,通过它我们可以查找窗口句柄,这是后续操作的基础。例如,使用FindWindow函数可以根据窗口的类名和标题来获取窗口的句柄,方便我们定位到正在运行的植物大战僵尸游戏窗口。
win32process模块主要用于获取与进程相关的信息和进行一些进程操作,如获取进程 ID 等。在我们的代码中,GetWindowThreadProcessId函数就是从该模块中调用的,它能够根据窗口句柄获取到对应的进程 ID,这对于后续打开进程并进行内存操作至关重要。
win32api模块提供了大量的 Windows API 函数,我们使用OpenProcess函数来打开一个已存在的进程,并获取进程句柄,以便后续对进程内存进行读写操作。只有获取了正确的进程句柄,我们才能对游戏进程的内存进行有效的访问和修改。
ctypes模块是 Python 的一个外部函数库,它提供了与 C 语言兼容的数据类型和函数调用机制,使得我们可以在 Python 中调用 C 语言编写的动态链接库(DLL)中的函数。在这里,我们通过ctypes加载kernel32.dll库,并调用其中的ReadProcessMemory和WriteProcessMemory函数来实现对游戏进程内存的读写操作,从而精准地修改阳光值。
以下是导入这些模块的代码示例:

import win32process
import win32api
import ctypes

这些模块相互配合,为我们实现植物大战僵尸阳光值的修改提供了必要的工具和功能支持,是整个修改过程的基础。

4.2 获取窗口句柄和进程 ID

在修改植物大战僵尸阳光值的过程中,获取游戏窗口的句柄和对应的进程 ID 是关键步骤之一。我们可以借助win32gui和win32process模块中的函数来实现这一目标。
首先,使用win32gui.FindWindow函数来查找植物大战僵尸游戏窗口的句柄。这个函数接受两个参数,第一个参数是窗口类名,第二个参数是窗口标题。对于植物大战僵尸中文版,我们可以这样调用:
hwnd = win32gui.FindWindow(0, "植物大战僵尸中文版")

这里将窗口类名设置为 0,表示不限制窗口类名,只通过窗口标题 “植物大战僵尸中文版” 来查找窗口句柄。如果函数返回值不为 0,则说明找到了对应的窗口,这个返回值就是窗口句柄hwnd,我们将在后续操作中使用它来获取进程相关信息。
接下来,通过win32process.GetWindowThreadProcessId函数获取游戏进程的 ID。这个函数接受一个窗口句柄作为参数,并返回一个包含线程 ID 和进程 ID 的元组。我们只需要获取其中的进程 ID 即可,示例代码如下:
_, pid = win32process.GetWindowThreadProcessId(hwnd)

这样,我们就成功获取到了植物大战僵尸游戏的进程 IDpid,后续我们将使用这个进程 ID 来打开进程,以便对其内存进行操作,从而实现阳光值的修改。这两个步骤的紧密配合,为我们进一步深入修改游戏数据奠定了基础。

4.3 打开进程并获取权限

在获取到植物大战僵尸游戏的进程 ID 后,接下来需要使用win32api.OpenProcess函数以适当的权限打开游戏进程,为后续的内存操作做好准备。
OpenProcess函数的第一个参数用于指定所需的访问权限,我们通常需要获取较高的权限,例如PROCESS_ALL_ACCESS,它包含了对进程内存进行读写等操作所需的各种权限。第二个参数表示进程句柄是否可以被子进程继承,一般设置为False,表示不允许继承。第三个参数就是我们之前获取到的进程 ID。
以下是打开进程并获取权限的示例代码:
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
phand = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)

在这段代码中,首先定义了PROCESS_ALL_ACCESS权限组合,然后使用OpenProcess函数打开进程,并将返回的进程句柄赋值给phand变量。这个进程句柄将在后续的内存读写操作中被频繁使用,确保我们能够对游戏进程的内存进行有效的访问和修改,从而实现阳光值的调整等操作。需要注意的是,获取进程权限时要确保操作的合法性和安全性,避免对系统和其他程序造成不必要的影响。

4.4 读取和修改阳光值

4.4.1 读取阳光值内存地址

为了修改阳光值,我们首先需要找到阳光值在游戏进程内存中的地址。这可以通过ctypes库和kernel32.dll中的ReadProcessMemory函数来实现。
ReadProcessMemory函数用于从指定进程的内存中读取数据,它的参数包括进程句柄、要读取的内存地址、用于存储读取数据的缓冲区指针、要读取的字节数以及一个指向实际读取字节数的指针(在 Python 中可以设置为None)。
在我们的代码中,首先需要定义一个ctypes.c_long类型的变量来存储读取到的数据,例如:
date = ctypes.c_long()

然后加载kernel32.dll库:
mydll = ctypes.windll.LoadLibrary('kernel32.dll')

接下来,使用ReadProcessMemory函数读取阳光值的内存地址。假设我们已经通过之前介绍的方法找到了阳光值的基址为0x6A9EC0(实际情况中这个地址需要通过工具如 CE 来查找),我们可以这样读取:
mydll.ReadProcessMemory(int(phand), 0x6A9EC0, ctypes.byref(date), 4, None)
mydll.ReadProcessMemory(int(phand), date.value + 0x768, ctypes.byref(date), 4, None)

这里进行了两次ReadProcessMemory调用,第一次是从基址0x6A9EC0读取数据,得到一个地址值,存储在date变量中。第二次是从date.value加上偏移量0x768的地址处再次读取数据,进一步定位到阳光值的实际存储地址,最终date变量中存储的就是阳光值的内存地址。
通过这样的方式,我们就能够准确地找到阳光值在游戏进程内存中的存放位置,为后续修改阳光值做好准备。

4.4.2 修改阳光值

在成功读取到阳光值的内存地址后,我们就可以使用WriteProcessMemory函数将新的阳光值写入该地址,从而实现阳光值的修改。
WriteProcessMemory函数的参数与ReadProcessMemory函数类似,包括进程句柄、要写入的内存地址、要写入的数据缓冲区指针、要写入的数据字节数以及一个指向实际写入字节数的指针(在 Python 中可以设置为None)。
假设我们要将阳光值修改为9999,示例代码如下:
new_date = ctypes.c_long(9999)
mydll.WriteProcessMemory(int(phand), date.value + 0x5560, ctypes.byref(new_date), 4, None)

在这段代码中,首先创建一个ctypes.c_long类型的变量new_date,并将其值设置为我们想要修改的阳光值9999。然后,使用WriteProcessMemory函数将new_date中的值写入到之前找到的阳光值内存地址(date.value + 0x5560)中,写入的字节数为 4 字节(因为ctypes.c_long类型在 32 位系统中占用 4 字节)。
这样,就完成了阳光值的修改操作。当我们再次回到游戏中时,就会发现阳光值已经变成了我们设定的9999,从而可以更轻松地进行游戏,享受无限阳光带来的乐趣。不过,需要再次强调的是,这种修改游戏数据的行为仅用于学习和研究目的,在实际游戏中应遵守游戏规则和相关法律法规,避免不正当使用导致的不良后果。

4.5 总代码

小声:只有这里是我自己写的

import win32gui
import win32process
import win32api
import ctypes


def change_sunshine(phand, sunshine_num):
    date = ctypes.c_long()
    mydll = ctypes.windll.LoadLibrary('kernel32.dll')
    
    # 读进程内存,找到阳光地址
    mydll.ReadProcessMemory(int(phand), 0x6A9EC0, ctypes.byref(date), 4, None)
    mydll.ReadProcessMemory(int(phand), date.value + 0x768, ctypes.byref(date), 4, None)

    # 写进程内存
    new_date = ctypes.c_long(sunshine_num)
    mydll.WriteProcessMemory(int(phand), date.value + 0x5560, ctypes.byref(new_date), 4, None)


if __name__ == '__main__':
    # 全部权限
    PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
    # 窗口句柄
    hwnd = win32gui.FindWindow(0, "植物大战僵尸中文版")
    # 进程ID
    _, pid = win32process.GetWindowThreadProcessId(hwnd)
    # 进程句柄
    phand = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    # 调用修改阳光函数
    change_sunshine(phand, 9999)

image

五、代码优化与扩展

5.1 优化代码结构

随着代码功能的增加,优化代码结构变得尤为重要,它能提高代码的可读性、可维护性和可扩展性,使代码更加清晰易懂,便于后续的修改和完善。以下是一些优化建议:
函数封装:将获取窗口句柄、进程 ID、打开进程以及读写内存等操作封装成独立的函数。这样可以使主程序逻辑更加清晰,每个函数只负责一个特定的任务,便于理解和调试。

通过这样的封装,在主程序中调用这些函数时,代码的逻辑结构更加清晰

读取阳光值内存地址

address = read_memory(phand, 0x6A9EC0)
address = read_memory(phand, address + 0x768)

修改阳光值

write_memory(phand, address + 0x5560, 9999)

使用类来组织代码:创建一个GameMemoryEditor类,将与游戏内存编辑相关的函数和数据封装在类中,这样可以更好地管理代码的状态和行为。例如:

这种方式使得代码的结构更加清晰,数据和操作都封装在类中,便于管理和维护。通过这些优化措施,可以使代码更加健壮和易于扩展,为后续添加更多功能提供了良好的基础。

5.2 添加更多功能

在实现了阳光值修改的基础上,我们还可以进一步扩展代码的功能,让游戏体验更加丰富和有趣。以下是一些可以尝试添加的功能及实现思路:
无限阳光:要实现无限阳光的功能,可以在一个循环中不断地将阳光值设置为一个较大的数值,例如 99999 。可以使用time.sleep函数来设置一个合适的时间间隔,避免过度占用系统资源

七、总结

通过以上步骤,我们成功地使用 Python 实现了对植物大战僵尸阳光值的修改,从最初的准备工作,到寻找内存地址,再到编写和优化代码,每一个环节都至关重要。这不仅让我们对游戏的内部机制有了更深入的了解,也展示了 Python 在游戏修改领域的强大能力。
然而,需要再次强调的是,修改游戏数据应该仅用于学习和研究目的,遵守游戏的使用条款和相关法律法规是我们必须坚守的原则。在合法合规的前提下,大家可以继续探索 Python 在游戏修改中的更多可能性,比如尝试修改其他游戏参数或者为游戏添加新的功能,不断提升自己的编程技能和对游戏机制的理解,享受探索的乐趣。希望这篇文章能够对大家有所帮助,祝大家在编程和游戏的世界里都能收获满满!

标签:教程,游戏,句柄,大战,修改,阳光,ctypes,进程,僵尸
From: https://www.cnblogs.com/timmoc/p/18633214

相关文章

  • Rocky8.10搭建zabbix​6.4详细教程
    zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。zabbix由2部分构成,zabbixserver与可选组件zabbixagent。zabbixs......
  • 在Lazarus下的Free Pascal编程教程——在Lazarus中使用计时器组件TTimer
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和“2.已......
  • 【comfyui教程】ComfyUI喂饭教程!一个适合新手的工作流搭建思路!
    前言在[《解锁ComfyUI:新手到高手的五级跳》]这篇文章中,我分享了自己学习ComfyUI的五个阶段,而最后一个阶段——创建自己的工作流,尚未详细介绍。今天我就来填坑啦~自己动手,丰衣足食,自己从头到尾搭建一个工作流,才是真正掌握ComfyUI精髓的王道。我们马上开始吧!一、明确目标......
  • IntelliJ IDEA 2024.3 安装教程与激活方法(附常见问题解决)
    IntelliJIDEA概述IntelliJIDEA是JetBrains公司推出的一款功能强大的Java集成开发环境(IDE),凭借其丰富的功能和工具集,极大地提升了开发者的编程效率和工作体验。温馨提示:本文中的方法仅供学习交流使用,如果条件允许,请支持正版软件。删除旧版本IntelliJIDEA如果您的电脑中已......
  • DataGrip2024.3完整版的安装教程(附激活,常见问题处理)
    卸载老版本DataGrip首先,如果小伙伴的电脑上有安装老版本的DataGrip,需要将其彻底卸载掉,如下所示(没有安装则不用管,直接安装即可):TIP:如果你之前使用过本站提供的 激活到2025年版本脚本,需要执行对应卸载脚本/适用2024版本/JetBrains2023最新全家桶/jetbra/scripts/unin......
  • AI绘画,一步一步徒手搭建ComfyUI工作流,教你编辑和修改工作流,ComfyUI入门教程
    前言:“探索AI绘画的魅力,从零开始,一步步带你徒手搭建ComfyUI工作流。本教程将详细介绍如何编辑和修改工作流,助你轻松入门ComfyUI,开启创意无限的艺术之旅。跟随我的步伐,让我们一起揭开AI绘画的神秘面纱!”在上一篇文章中,我们讲过如何自己一步一步手动搭建ComfyUI的基本工作......
  • AIGC | 有手就行的AI绘画教程!全程干货,速来学习!
    AI绘画工具的出现,让设计岗的同事更会画画了,还让策划/制片/三维/后期/运营……也能“画”一画了。今天小源就教一教大伙,萌新小白都能迅速上手的_AI绘画教程_,从零开始,产出你画不出来的“画”!AI绘画,即利用人工智能进行绘画,是人工智能生成内容的典型应用场景之一。其大概......
  • Navicat Premium 17 激活破解版下载及安装教程
    前言NavicatPremium是一套可创建多个连接的数据库开发工具,让你从单一应用程序中同时连接MySQL、MariaDB、MongoDB、SQLServer、Oracle、PostgreSQL和SQLite。它与OceanBase数据库及AmazonRDS、AmazonAurora、AmazonRedshift、MicrosoftAzure、OracleCloud、Mongo......
  • Sealos Devbox 基础教程:使用 Cursor 从零开发一个 One API 替代品
    随着技术的成熟和AI的崛起,很多原本需要团队协作才能完成的工作现在都可以通过自动化和智能化的方式完成。于是乎,单个开发者的能力得到了极大的提升-借助各种工具,一个人就可以完成开发、测试、运维等整条链路上的工作,渡劫飞升成为真正的“全干工程师”。之前我们分享过一些入......
  • 【建议收藏】渗透测试零基础入门教程,全程干货!
    转眼间,从大三开始学安全,到现在也有五年了,也算是对渗透测试有一定理解,公众号准备出一些入门教程,以实操为主,希望可以帮助到想入门渗透测试的小白。如果觉得有用,可以在文章后面支持一下我,作为我写下去的动力。1.什么是渗透测试渗透测试就是模拟真实黑客的攻击手法对目标网站......