免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
工具下载:
链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3 提取码:6tw3 复制这段内容后打开百度网盘手机App,操作更方便哦
上一个内容:31.x86游戏实战-使用物品call
封装上一个内容里写的代码,也就是下方的代码
pushad
push object
mov ecx, 0x1A5FB24
mov ecx, [ecx]
mov eax, 0x7B9130
call eax
popad
然后打开之前MFCdll的项目,最后一次写代码在24.x86游戏实战-血量与封装人物属性,然后新加一个按钮如下图
![]()
然后双击下图红框
![]()
双击完就创建了使用物品按钮的点击事件处理函数,如下图红框
![]()
然后开始写使用物品的代码,首先写下图红框的内容
![]()
然后右击函数名,然后选择下图红框的选项
![]()
然后它的内容
![]()
写完代码使用注入器,注入到游戏中
![]()
然后点击使用物品,游戏里就会使用物品了,游戏效果图不能贴出来,自行脑补一下
![]()
DXXDlg.cpp文件的修改:新加 OnBnClickedButton3函数(使用物品按钮点击事件处理函数)
// DXXDlg.cpp: 实现文件
//
#include "pch.h"
#include "WCDXX.h"
#include "afxdialogex.h"
#include "DXXDlg.h"
#include "MyStrust.h"
// DXXDlg 对话框
IMPLEMENT_DYNAMIC(DXXDlg, CDialogEx)
DXXDlg::DXXDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG1, pParent)
{
OutputDebugStringA("执行流程-执行DXXDlg构造函数流程1");
}
DXXDlg::~DXXDlg()
{
OutputDebugStringA("执行流程-执行DXXDlg析构函数流程1");
}
void DXXDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(DXXDlg, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1, &DXXDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &DXXDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &DXXDlg::OnBnClickedButton3)
END_MESSAGE_MAP()
// DXXDlg 消息处理程序
void DXXDlg::OnBnClickedButton1()
{
MyStrust mystruct;
mystruct.InitMy();
}
void DXXDlg::OnBnClickedButton2()
{
}
void DXXDlg::OnBnClickedButton3()
{
MyStrust mystruct;
mystruct.UseObject(0);
}
MyStrust.h文件的修改:新加UseObject函数
#pragma once
struct Myself {
DWORD Blood;// 血量
FLOAT X; // x坐标
FLOAT Y; // y坐标
wchar_t* Name; // 名字
};
class MyStrust
{
public:
Myself My;
void InitMy();
void UseObject(DWORD object);
};
MyStrust.cpp文件的修改:新加UseObject函数
#include "pch.h"
#include "MyStrust.h"
void MyStrust::InitMy()
{
// [[0x1AB7CDC]+0x258] 名字
/*
*这个符号表示地址,在c++中被称为指针或指针类型
int表示4字节数字
int*就表示指针类型的int
(int*)0x1AB7CDC;这样表示0x1AB7CDC地址里的内容是4字节的数字
*/
int* address = (int*)0x1AB7CDC;
/*
取出地址中的值,也就是取出0x1AB7CDC里的内容
*address这样在左边只写一个*表示取内存地址里的值
也就是取address它的值,address是0x1AB7CDC,也就是取0x1AB7CDC它的值
*/
int addressValue = *address;
/*
(*(int*)addressValue)意思是
把addressValue转成int*,也就是把
addressValue的值当成内存地址,addressValue的值现在是[0x1AB7CDC]+0x258这个
现在这个地址里面的值是名字的地址,所以在左边加了一个*让把名字的地址去除了出来
取出来之后就得到了名字,名字是UNICODE类型,UNICODE又被称为宽字节,宽字节的数据是用两个字节描述一个文字或字母
在c++里wchar_t类型就是UNICODE
然后在c++中名字这种数据被称为字符串,如果要用字符串必须用指针类型也就是wchar_t*
右边加上*让wchar_t变成指针类型的wchar_t,才能在c++中使用字符串
*/
wchar_t* name = (wchar_t*)(*(int*)(addressValue+0x258));
// 一般函数名后面是W就表示有UNICODE,也就是要用宽字节
OutputDebugStringW(name);
// [[0x1AB7CDC]+0x18C]x坐标
// [[0x1AB7CDC]+0x190]y坐标
/*
取出地址中的值,也就是取出0x1AB7CDC里的内容
*address这样在左边只写一个*表示取内存地址里的值
也就是取address它的值,address是0x1AB7CDC,也就是取0x1AB7CDC它的值
*/
float xZuoBiao = *(float*)(addressValue + 0x18C);
float yZuoBiao = *(float*)(addressValue + 0x190);
char buf[256] = { 0 };
// 拼接文字,%f表示拼接一个小数(单浮点数)
sprintf(buf, "x=%f;y=%f", xZuoBiao, yZuoBiao);
OutputDebugStringA(buf);
// [[0x1AB7CDC]+0x36A0]血量
int xueliang = *(int*)(addressValue + 0x36A0);
// 拼接文字,%d表示拼接一个整数(32位的整数)
sprintf(buf, "血量 = %d", xueliang);
OutputDebugStringA(buf);
}
void MyStrust::UseObject(DWORD object)
{
object += 3; // 背包物品序号
/*
try的作用
如果
__asm {
pushad
push object
mov ecx, 0x1A5FB24 // 背包基址
mov ecx, [ecx]
mov eax, 0x7B9130 // 使用物品的函数地址
call eax
popad
}
这个代码运行过程中出现错误了,我不会让游戏崩溃,出现错误之后会执行
catch (...) {
OutputDebugStringA("MyStrust::UseObject error");
}
这个catch里面的代码,现在也就是执行OutputDebugStringA("MyStrust::UseObject error");这一行
*/
try {
__asm {
pushad
push object
mov ecx, 0x1A5FB24 // 背包基址
mov ecx, [ecx]
mov eax, 0x7B9130 // 使用物品的函数地址
call eax
popad
}
}
catch (...) {
OutputDebugStringA("MyStrust::UseObject error");
}
}
上方的代码不全,只有手写的代码
完整代码:以 24.x86游戏实战-血量与封装人物属性 它的代码为基础进行修改
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg?pwd=q9n5
提取码:q9n5
复制这段内容后打开百度网盘手机App,操作更方便哦