植物大战僵尸修改器-MFC

news2024/11/18 8:42:07

创建项目

创建mfc应用

基于对话框

打开资源视图下的 IDD_MFCAPPLICTION2_DIALOG

限制对话框大小 将属性中Border的值改为对话框外框

删除对话框中原有的控件

属性-外观-Caption 设置对话框标题

工具箱中拖放一个按钮

修改按钮名称

将按钮ID改为IDC_COURSE

在MFCApplication2Dlg.h中添加void CMFCApplication2Dlg::OnBtnClickedCourse();

// 实现
protected:
HICON m_hIcon;

// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
void CMFCApplication2Dlg::OnBtnClickedCourse();
};

MFCApplication2Dlg.cpp: 实现文件中添加

void CMFCApplication2Dlg::OnBtnClickedCourse() {

}

MFCApplication2Dlg.cpp中将按钮与函数绑定 添加ON_BN_CLICKED(IDC_COURSE, CMFCApplication2Dlg::OnBtnClickedCourse)

BEGIN_MESSAGE_MAP(CMFCApplication2Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_COURSE, CMFCApplication2Dlg::OnBtnClickedCourse)
END_MESSAGE_MAP()

打印调试

TRACE函数:类似于C语言的printf,只能在DEBUG调试模式下看到打印信息(F5启动)

TRACE("age is %d\n",20);

AfxMessageBox函数

CString str;
c

MessageBox函数:只在CWnd的子类中使用,功能比AfxMessageBox多

CString str;
str.Format(CString("age is %d"),20);
MessageBox(str, CString("错误"), MB_YESNO | MB_ICONERROR);

MFC-打开网页

void CMFCApplication2Dlg::OnBtnClickedCourse() {
	ShellExecute(NULL,
		CString("open"),
		CString("https://blog.csdn.net/weixin_42403632"),
		NULL, NULL,
		SW_SHOWNORMAL);
}

checkbox

拖一个Check Box 文字改为秒杀僵尸 ID改为 IDC_KILL

鼠标右击-添加事件处理程序

程序自动在头文件中添加了afx_msg void OnBnClickedKill();

声明了函数 并绑定了操作

单选框的状态读取和修改

void CMFCApplication2Dlg::OnBnClickedKill()
{
	BOOL checked = IsDlgButtonChecked(IDC_KILL);
	if (checked) {
		//勾选了
	}else {
		//没有勾选
	}

}

方法二 绑定变量

说明变量

绑定变量DDX_Control(pDX, IDC_KILL, m_bnKill);

自动绑定

鼠标右键添加变量

秒杀僵尸思路

通过CE搜索未知的初始值

通过僵尸的血量减少/未减少

扫描减少的数值/未变动的数值

找到僵尸血量的内存地址

找出是什么改写了这个地址

查看汇编代码

使用OD打开植物大战僵尸

搜索内存地址 00531319

往上看有一条

0053130F 2B7C24 20 sub edi,dword ptr ss:[esp+0x20]

分析出是植物打一下 血量减少的值

将汇编代码改为

sub edi,edi

不管哪种植物攻击 都一次血量-血量

实现僵尸秒杀

监控游戏

打开spy++工具

点击望远镜图标

将准星拖到植物大战僵尸窗口

添加线程

添加代码

// TODO: 在此添加额外的初始化代码
	// 创建一条子线程,监控游戏的打开或关闭

	CreateThread(NULL, NULL, monitorThreadFunc, NULL, NULL, NULL);
	// 保存对话框
	g_dlg = this;

全:


// CMFCApplication2Dlg 消息处理程序

BOOL CMFCApplication2Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	// 创建一条子线程,监控游戏的打开或关闭

	CreateThread(NULL, NULL, monitorThreadFunc, NULL, NULL, NULL);
	// 保存对话框
	g_dlg = this;

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

监听方法

CMFCApplication2Dlg *g_dlg;

//用来监控游戏的线程
DWORD monitorThreadFunc(LPVOID lpThreadParameter) {
	while (1) {
		// 获得植物大战僵尸窗口的句柄
		HWND windowHandle = FindWindow(CString("MainWindow"), CString("植物大战僵尸中文版"));
		if (windowHandle == NULL) {
			g_dlg->m_bnKill.SetCheck(FALSE);
			g_dlg->m_bnSun.SetCheck(FALSE);
			g_dlg->m_bnKill.EnableWindow(FALSE);
			g_dlg->m_bnSun.EnableWindow(FALSE);
		}else {
			g_dlg->m_bnKill.EnableWindow(TRUE);
			g_dlg->m_bnSun.EnableWindow(TRUE);
		}
		Sleep(1000);
	}
	return NULL;
}

头文件中声明

friend DWORD monitorThreadFunc(LPVOID);
//子线程句柄
HANDLE m_monitorThread;

游戏打开时修改器才能使用

功能实现

封装写内存代码

HANDLE g_processHandle;

// 将某个值写入植物大战僵尸内存(后面的可变参数是地址链,要以-1结尾)
void WriteMemory(void *value, DWORD valueSize, ...) {
	if (value == NULL || valueSize == 0 || g_processHandle == NULL) return;

	DWORD tempValue = 0;

	va_list addresses;
	va_start(addresses, valueSize);
	DWORD offset = 0;
	DWORD lastAddress = 0;
	while ((offset = va_arg(addresses, DWORD)) != -1) {
		lastAddress = tempValue + offset;
		::ReadProcessMemory(g_processHandle, (LPCVOID)lastAddress, &tempValue, sizeof(DWORD), NULL);
	}
	va_end(addresses);

	::WriteProcessMemory(g_processHandle, (LPVOID)lastAddress, value, valueSize, NULL);
}

void WriteMemory(void *value, DWORD valueSize, DWORD address) {
	WriteMemory(value, valueSize, address, -1);
}

僵尸秒杀

void CMFCApplication2Dlg::OnBnClickedKill()
{
	if (m_bnKill.GetCheck()) { // 需要秒杀僵尸
		BYTE data[] = { 0xFF, 0x90, 0x90 };
		WriteMemory(data, sizeof(data), 0x00531310);
	}
	else { // 不需要秒杀僵尸
		BYTE data[] = { 0x7c, 0x24, 0x20 };
		WriteMemory(data, sizeof(data), 0x00531310);
	}

}

无限阳光

if (g_dlg->m_sunshine.GetCheck())
{ // 如果需要无限阳光
    DWORD value = 9990;
    WriteMemory(&value, sizeof(value), 0x6A9EC0, 0x320, 0x8, 0x0, 0x8, 0x144, 0x2c, 0x5560, -1);
}

::Sleep(MONITOR_REFRESH_TIME_INTERVAL);

完整代码


// MFCApplication2Dlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "MFCApplication2.h"
#include "MFCApplication2Dlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CMFCApplication2Dlg *g_dlg;
HANDLE g_processHandle;

// 将某个值写入植物大战僵尸内存(后面的可变参数是地址链,要以-1结尾)
void WriteMemory(void *value, DWORD valueSize, ...) {
	if (value == NULL || valueSize == 0 || g_processHandle == NULL) return;

	DWORD tempValue = 0;

	va_list addresses;
	va_start(addresses, valueSize);
	DWORD offset = 0;
	DWORD lastAddress = 0;
	while ((offset = va_arg(addresses, DWORD)) != -1) {
		lastAddress = tempValue + offset;
		::ReadProcessMemory(g_processHandle, (LPCVOID)lastAddress, &tempValue, sizeof(DWORD), NULL);
	}
	va_end(addresses);

	::WriteProcessMemory(g_processHandle, (LPVOID)lastAddress, value, valueSize, NULL);
}

void WriteMemory(void *value, DWORD valueSize, DWORD address) {
	WriteMemory(value, valueSize, address, -1);
}

//用来监控游戏的线程
DWORD monitorThreadFunc(LPVOID lpThreadParameter) {
	while (1) {
		// 获得植物大战僵尸窗口的句柄
		HWND windowHandle = FindWindow(CString("MainWindow"), CString("植物大战僵尸中文版"));
		if (windowHandle == NULL) {
			g_dlg->m_bnKill.SetCheck(FALSE);
			g_dlg->m_bnSun.SetCheck(FALSE);
			g_dlg->m_bnKill.EnableWindow(FALSE);
			g_dlg->m_bnSun.EnableWindow(FALSE);
		}else {
			g_dlg->m_bnKill.EnableWindow(TRUE);
			g_dlg->m_bnSun.EnableWindow(TRUE);
			// 获得植物大战僵尸的进程ID
			DWORD processPid;
			GetWindowThreadProcessId(windowHandle, &processPid);
			// 获得植物大战僵尸的进程句柄
			g_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processPid);

		}
		if (g_dlg->m_bnSun.GetCheck())
		{ // 如果需要无限阳光
			DWORD value = 9990;
			WriteMemory(&value, sizeof(value), 0x6A9EC0, 0x320, 0x8, 0x0, 0x8, 0x144, 0x2c, 0x5560, -1);
		}

		Sleep(1000);
	}
	return NULL;
}

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMFCApplication2Dlg 对话框



CMFCApplication2Dlg::CMFCApplication2Dlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCAPPLICATION2_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFCApplication2Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);

	DDX_Control(pDX, IDC_KILL, m_bnKill);
	DDX_Control(pDX, IDC_SUN, m_bnSun);
}

BEGIN_MESSAGE_MAP(CMFCApplication2Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_COURSE, CMFCApplication2Dlg::OnBtnClickedCourse)
	ON_BN_CLICKED(IDC_KILL, &CMFCApplication2Dlg::OnBnClickedKill)
	ON_BN_CLICKED(IDC_SUN, &CMFCApplication2Dlg::OnBnClickedSun)
END_MESSAGE_MAP()


// CMFCApplication2Dlg 消息处理程序

BOOL CMFCApplication2Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	// 创建一条子线程,监控游戏的打开或关闭

	CreateThread(NULL, NULL, monitorThreadFunc, NULL, NULL, NULL);
	// 保存对话框
	g_dlg = this;

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMFCApplication2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMFCApplication2Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFCApplication2Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMFCApplication2Dlg::OnBtnClickedCourse() {
	ShellExecute(NULL,
		CString("open"),
		CString("https://blog.csdn.net/weixin_42403632"),
		NULL, NULL,
		SW_SHOWNORMAL);
}

void CMFCApplication2Dlg::OnBnClickedKill()
{
	if (m_bnKill.GetCheck()) { // 需要秒杀僵尸
		BYTE data[] = { 0xFF, 0x90, 0x90 };
		WriteMemory(data, sizeof(data), 0x00531310);
	}
	else { // 不需要秒杀僵尸
		BYTE data[] = { 0x7c, 0x24, 0x20 };
		WriteMemory(data, sizeof(data), 0x00531310);
	}

}


void CMFCApplication2Dlg::OnBnClickedSun()
{
	// TODO: 在此添加控件通知处理程序代码
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2200498.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

django(二):定义第一个函数及url介绍

1.定义index函数 """ django里的第一个函数必须是request,不写会报错 """def index(request):return HttpResponse("Hello, world. Youre at the index of djangoProject.")注意&#xff01; ①.index函数里的形参必须为request ②.r…

STM32输入捕获模式详解(上篇):原理、测频法与测周法

1. 前言 在嵌入式系统的开发过程中&#xff0c;常常需要对外部信号进行精确的时间测量&#xff0c;如测量脉冲信号的周期、频率以及占空比等。STM32系列微控制器提供了丰富的定时器资源&#xff0c;其中的输入捕获&#xff08;Input Capture, IC&#xff09;模式能实现对信号的…

【测试】BUG篇——BUG

bug的概念 定义&#xff1a;⼀个计算机bug指在计算机程序中存在的⼀个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault)&#xff0c;这些bug使程序⽆法正确的运⾏。Bug产⽣于程序的源代码或者程序设计阶段的疏忽或者错误。 准确的来说&#xff1a; 当且仅当规格说明&am…

网站集群批量管理-Ansible(ad-hoc)

1. 概述 1. 自动化运维: 批量管理,批量分发,批量执行,维护 2. 无客户端,基于ssh进行管理与维护 2. 环境准备 环境主机ansible10.0.0.7(管理节点)nfs01 10.0.0.31(被管理节点)backup10.0.0.41(被管理节点) 2.1 创建密钥认证 安装sshpass yum install -y sshpass #!/bin/bash ##…

SpringBoot整合MyBatis记录

整体目录结构 创建数据库 创建一个MySQL的表&#xff0c;表名是student。 create table student (id int auto_increment comment 唯一标识idprimary key,name varchar(30) not null comment 姓名,age int not null comment 年龄 ) 插入一条数据记录到数据库当中去…

【数据结构与算法-高阶】并查集

【数据结构与算法-高阶】并查集 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;数据结构与算法&#x1f345; &#x1f33c;文章目录&#x1f33c; 1. 并查集原理 2. 并查集实现 3. 并查集应用 1. 并查集原理 在一些应用问题中&…

Matlab|基于遗传粒子群算法的无人机路径规划【遗传算法|基本粒子群|遗传粒子群三种方法对比】

目录 主要内容 模型研究 部分代码 结果一览 下载链接 主要内容 为了更高效地完成复杂未知环境下的无人机快速探索任务&#xff0c;很多智能算法被应用于无人机路径规划方面的研究&#xff0c;但是传统粒子群算法存在粒子更新思路单一、随机性受限、收敛速度慢…

修改calibre-web最大文件上传值

修改calibre-web最大文件上传值 Windows安装calibre-web&#xff0c;Python-CSDN博客文章浏览阅读541次&#xff0c;点赞10次&#xff0c;收藏11次。pip install calibreweb报错&#xff1a;error: Microsoft Visual C 14.0 or greater is required. Get it with "Microso…

案例:问题处理与原因分析报告的模板

系统上线后暴露的问题也是一种财富&#xff0c;我们需要从中吸收经验教训&#xff0c;规避其他类似的问题。对于上线后的问题如何进行原因分析&#xff0c;我提供两个分析报告的模板&#xff0c;供大家参考。 模板案例1&#xff1a;共性现象的原因分析报告 模板案例二&#xf…

C(十三)for、while、do - while循环的抉择 --- 打怪闯关情景

前言&#xff1a; 继C&#xff08;十&#xff09;for循环 --- 黑神话情景之后&#x1f449; https://blog.csdn.net/2401_87025655/article/details/142684637 今天&#xff0c;杰哥想用一个打怪闯关的场景让与大家一起初步认识一下for、while、do - while循环的抉择。&#xf…

Docker在linux系统中的下载与使用

Docker在linux系统中的下载与使用 一、docker作用,下载及安装二、docker镜像三、创建容器四、容器数据卷 一、docker作用,下载及安装 ubuntu下载安装docker 命令&#xff1a;在ubuntu上面执行这个命令 Docker version:查看docker是否安装成功 配置阿里云镜像加速:进入阿里云网站…

阿里140滑块-滑块验证码逆向分析思路学习

一、声明&#xff01; 原创文章&#xff0c;请勿转载&#xff01; 本文内容仅限于安全研究&#xff0c;不公开具体源码。维护网络安全&#xff0c;人人有责。 文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;均已做脱敏处…

JUC高并发编程8:读写锁

1 概述 1.1 悲观锁和乐观锁 在并发编程中&#xff0c;锁机制是用来控制多个线程对共享资源的访问。悲观锁和乐观锁是两种不同的并发控制策略。 1.1.1 悲观锁&#xff08;Pessimistic Locking&#xff09; 悲观锁假设在最坏的情况下&#xff0c;多个线程会同时访问和修改共享…

Qt-QDockWidget浮动窗口相关操作(49)

目录 描述 使用 描述 在 Qt 中&#xff0c;浮动窗⼝也称之为铆接部件。浮动窗⼝是通过 QDockWidget类 来实现浮动的功能。浮动窗口⼀般是位于核心部件的周围&#xff0c;可以有多个。 使用 创建我们可以参考下面的语法格式 使用起来也很简单&#xff0c;不过只能创建一个 Q…

【C语言】使用结构体实现位段

文章目录 一、什么是位段二、位段的内存分配1.位段内存分配规则练习1练习2 三、位段的跨平台问题四、位段的应用五、位段使用的注意事项 一、什么是位段 在上一节中我们讲解了结构体&#xff0c;而位段的声明和结构是类似的&#xff0c;它们有两个不同之处&#xff0c;如下&…

创建osd加入集群

故障原因&#xff1a;ceph节点一个磁盘损坏&#xff0c;其中osd69 down了&#xff0c;需要更换磁盘并重新创建osd加入ceph集群。 信息采集&#xff1a; 更换磁盘前&#xff0c;查询osd69对应的盘符&#xff1a; 将对应的故障磁盘更换后&#xff0c;并重做raid&#xff0c;然后查…

SDK4(note下)

以下代码涉及到了很多消息的处理&#xff0c;有些部分注释掉了&#xff0c;主要看代码 #include <windows.h> #include<tchar.h> #include <stdio.h> #include <strsafe.h> #include <string> #define IDM_OPEN 102 /*鼠标消息 * 键盘消息 * On…

76.【C语言】perror函数介绍

1.cplusplus的官网介绍 cplusplus的介绍 点我跳转 2.翻译 函数 perror void perror ( const char * str ); 打印错误信息 将errno(最后一个错误数字)的值解释为错误信息,之后把它打印到stderr中(标准错误输出流,通常是控制台)(备注有关"流"的概念在75.【C语言】文件…

k8s-pod的管理及优化设置

Pod是Kubernetes&#xff08;k8s&#xff09;中最小的资源管理组件&#xff0c;也是最小化运行容器化应用的资源对象。以下是对Pod的详细介绍&#xff1a; 一、Pod的基本概念 定义&#xff1a;Pod是Kubernetes中可以创建和管理的最小单元&#xff0c;是资源对象模型中由用户创…

网站排名,让网站快速有排名的几个方法

要让网站快速获得并提升排名&#xff0c;需要综合运用一系列专业策略和技术&#xff0c;这些策略涵盖了内容优化、技术调整、外链建设、用户体验提升等多个方面。以下是让网站快速有排名的几个方法&#xff1a; 1.内容为王&#xff1a;创造高质量、有价值的内容 -深入…