21.第二阶段x86游戏实战2-C++实现寻路

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:20.第二阶段x86游戏实战2-进一步寻找寻路call1

上一个内容里找到了游戏中寻路的call,本次通过C++语言实现寻路功能

首先打开之前的dll项目,然后添加下图所示的三个控件,蓝色的是编辑框,红色的按钮

按钮的属性(编辑的属性是默认的所以编辑框没有属性的截图)

上图属性窗口如果没了,点击下图红框位置可以打开属性框,鼠标右击Dialog任意位置然后鼠标左键单机属性就可以了

然后给输入框添加一个变量

添加变量,如下图,写完点完成

另一个输入框添加变量

添加变量如下图,然后点完成

然后双击下图红框位置

然后就会创建下图红框的代码,本次观看代码的入口就是从下方函数开始(完整代码放到了百度网盘,本次设计代码写到了下方,文件名是CM.cpp)

然后新加一个文件

新加的文件类型与文件名

然后再创建一个文件,这次是在头文件里创建

下方代码中有些函数名用的中文,用中文有时候会有编码问题,编码问题效果就是函数名写的没问题但就是报错,这时把中文改成英文(字母)就可以了

通用.cpp文件的修改

#include "pch.h"
#include "通用.h"

/**
	... 是可变参数,意思是可以给Call_输出调式信息函数传递无限个参数
*/
void Call_输出调式信息(char * pszFormat, ...)
{
#ifdef _DEBUG
	char szbufFormat[0x1000];
	char szbufFormat_Game[0x1100] = "";
	va_list argList;
	/**
		当前函数 Call_输出调式信息(char * pszFormat, ...)这样声明的
		va_start(argList, pszFormat);意思是获取 ... 这个可变参数
		它会把 pszFormat 后面都会当做成可变参数赋值给 argList
	*/
	va_start(argList, pszFormat);
	/**
		vsprintf_s(szbufFormat, pszFormat, argList);
		意思是把 pszFormat 和 argList数据进行拼接,拼接完
		放到 szbufFormat 这种
		通过 vsprintf_s 让Call_输出调式信息函数
		支持了 %d 替换成数字这样的功能
	*/
	vsprintf_s(szbufFormat, pszFormat, argList);
	/**
		strcat_s(szbufFormat_Game, szbufFormat);
		意思是把 szbufFormat 的内容放到 szbufFormat_Game 中
	*/
	strcat_s(szbufFormat_Game, szbufFormat);
	/**
		OutputDebugStringA(szbufFormat_Game);
		把 szbufFormat_Game 它的内容打印到日志
		这个日志可以通过 Dbgview.exe 查看
		Dbgview放到百度网盘了
	*/
	OutputDebugStringA(szbufFormat_Game);
	// va_end(argList);表示可变参数使用完了
	va_end(argList);
#endif // _DEBUG

}

DWORD ReadDword(DWORD Adress) {
	/*
		(void*)Adress意思是把Adress的值转成void*也就是void的地址类型
		也就是把Adress它的值当成内存地址
		IsBadReadPtr函数是判断传的内存地址是否可读,可以直接复制IsBadReadPtr去百度搜,答案一大堆

		*(DWORD*)Adress;这个意思
		(DWORD*)Adress它把Adress的值当成了内存地址
		然后*(DWORD*)Adress,这个最左边的*意思是把内存地址的值取出来
	
	*/
	if (IsBadReadPtr((void*)Adress, sizeof(DWORD)) == 0)
		return *(DWORD*)Adress;
	return 0;
}

通用.h文件的修改

#pragma once
void Call_输出调式信息(char*pszFormat, ...);
DWORD ReadDword(DWORD Adress);

结构.h文件的修改:新加 坐标结构

#pragma once
struct R_人物属性
{
	DWORD 状态;

	void 初始化();
};

struct 坐标 {
	FLOAT x;
	FLOAT y;
};


pch.h文件的修改:新引入多个头文件,方便后续使用

// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"
#include <afxcontrolbars.h>
#include "通用.h"
#include "结构.h"
#include "Call.h"
#include <Windows.h>

#endif //PCH_H

新加的Call.h文件的内容:

#pragma once
void Call_xunlu(DWORD x, DWORD y);

新加的Call.cpp文件的内容:

#include "pch.h"
void Call_xunlu(DWORD x, DWORD y) {
	// 通过用OD对MessageBoxA函数打断点,然后用CTRL+F9跳转到我们的代码里
	// 然后就能调试我们写的代码了
	//MessageBoxA(0,0,0,0);
	DWORD 寻路基址 = (DWORD)GetModuleHandleA("Game.exe") + 0x5A6A10;
	DWORD jz = ReadDword(寻路基址);
	坐标 zb;
	zb.x = x;
	zb.y = y;
	DWORD 坐标的内存地址 = (DWORD)&zb;
	
	__asm {
		pushad
		mov ecx, jz
		push 坐标的内存地址
		mov eax, [ecx]
		mov eax, [eax + 0x4C]
		call eax
		popad
	}

}

CM.cpp文件的内容:新建OnBnClickedButton2函数

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

#include "pch.h"
#include "tl.h"
#include "CM.h"
#include "afxdialogex.h"


// CM 对话框

IMPLEMENT_DYNAMIC(CM, CDialogEx)

CM::CM(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG1, pParent)
	, edi_x(_T(""))
{

}

CM::~CM()
{
}

void CM::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, edi_x);
	DDX_Text(pDX, IDC_EDIT2, edi_y);
}


BEGIN_MESSAGE_MAP(CM, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CM::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CM::OnBnClickedButton2)
END_MESSAGE_MAP()


// CM 消息处理程序


void CM::OnBnClickedButton1()
{
	R_人物属性 a;
	a.初始化();
	Call_输出调式信息("人物信息:人物状态%d",a.状态);
}


void CM::OnBnClickedButton2()
{
	UpdateData(TRUE);
	CString str1 = edi_x;
	CString str2 = edi_y;
	// strtol((const char*)CW2A(str1.GetBuffer(0)), NULL, 10);把字符串转成int数字类型
	int x = strtol((const char*)CW2A(str1.GetBuffer(0)), NULL, 10);
	int y = strtol((const char*)CW2A(str2.GetBuffer(0)), NULL, 10);
	Call_xunlu(x, y);
}

CM.h文件的内容:新加 edi_x、edi_y变量

#pragma once


// CM 对话框

class CM : public CDialogEx
{
	DECLARE_DYNAMIC(CM)

public:
	CM(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CM();

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

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

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedButton1();
	afx_msg void OnBnClickedButton2();
	CString edi_x;
	CString edi_y;
};

上方的代码不全,只有手写的代码

完整代码:

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg?pwd=q9n5

提取码:q9n5

复制这段内容后打开百度网盘手机App,操作更方便哦


img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值