54.x86游戏实战-代码实现无限副本

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

本次游戏没法给

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

这是本系列最后一节,本系列属于基础,东西很简单东西也不多,下一节就会开启新的篇章学习新的技巧

工具下载:

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

提取码:6tw3

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

下方的代码不全,完整代码在百度网盘:以 51.x86游戏实战-XXX返回城镇的实现 它的代码为基础进行修改

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

提取码:q9n5

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

上一个内容:51.x86游戏实战-XXX返回城镇的实现

上一个内容找到了一个状态,通过这个状态可以得到当前玩家在做什么,比如可以得到在选择服务区、选择角色、在城镇中、在选择副本、在副本中这些状态,接下来就开始把找好的东西写成一个大功能,无限自动副本

首先打开C++项目,然后添加一个按钮

按钮的属性

然后加了停止副本

点击无限副本之后,游戏会开始自动打副本,点击停止副本之后游戏会停止自动打副本

实现无限副本的过程中发现了几个问题

第一个返回城镇会闪退

返回城镇之前是使用的第4层的代码,改为第3层不会闪退了

第二个问题

秒杀的函数有问题,加了下图红框的代码,秒杀之前需要调用FindMaster函数去找怪物,然后如果FindMaster函数没找到怪物(就算找到怪物也会存在问题),AllKill()函数通过this->masterNum.Object[i]做判断就会有问题,因为使用完没有置空,this->masterNum.Object[i]使用过一次(被秒杀过一次)内存地址就不存在了,再次使用这个内存地址就会有问题

DXXDlg.cpp文件的内容:新加 OnBnClickedButton12函数(无限副本按钮的点击事件处理函数)、OnBnClickedButton13函数(停止副本按钮点击事件处理函数)、ShuaTu函数

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

#include "pch.h"
#include "WCDXX.h"
#include "afxdialogex.h"
#include "DXXDlg.h"
#include "MyStrust.h"
#include "json.h"
#include "CLVEH.h"

HANDLE hProce = 0;
DWORD 进程是否终止 = 0;

// 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)
	ON_BN_CLICKED(IDC_BUTTON4, &DXXDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &DXXDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON6, &DXXDlg::OnBnClickedButton6)
	ON_BN_CLICKED(IDC_BUTTON7, &DXXDlg::OnBnClickedButton7)
	ON_BN_CLICKED(IDC_BUTTON8, &DXXDlg::OnBnClickedButton8)
	ON_BN_CLICKED(IDC_BUTTON9, &DXXDlg::OnBnClickedButton9)
	ON_BN_CLICKED(IDC_BUTTON10, &DXXDlg::OnBnClickedButton10)
	ON_BN_CLICKED(IDC_BUTTON11, &DXXDlg::OnBnClickedButton11)
	ON_BN_CLICKED(IDC_BUTTON12, &DXXDlg::OnBnClickedButton12)
	ON_BN_CLICKED(IDC_BUTTON13, &DXXDlg::OnBnClickedButton13)
END_MESSAGE_MAP()


// DXXDlg 消息处理程序


void DXXDlg::OnBnClickedButton1()
{
	MyStrust mystruct;
	mystruct.InitMy();
}


void DXXDlg::OnBnClickedButton2()
{

}


void DXXDlg::OnBnClickedButton3()
{
	
}


void DXXDlg::OnBnClickedButton4()
{
	MyStrust mystruct;
	mystruct.InitMy(); // 初始化玩家角色数据
	mystruct.ChangeBlooad(mystruct.My.Blood/2); // 修改血量
	
	// TODO: 在此添加控件通知处理程序代码
}


void DXXDlg::OnBnClickedButton5()
{
	MyStrust mystruct;
	mystruct.FindMaster();
}


void DXXDlg::OnBnClickedButton6()
{
	MyStrust mystruct;
	mystruct.AllKill();
}

// 断点的处理函数,ExceptionInfo里面有当前断点的寄存器的值
void fun(_EXCEPTION_POINTERS* ExceptionInfo) {
	call_logA("wetool:EIP=%X,ECX=%X,参数=%X", ExceptionInfo->ContextRecord->Eip, ExceptionInfo->ContextRecord->Ecx, *(DWORD*)(ExceptionInfo->ContextRecord->Esp + 4));
}

// HOOK按钮的点击事件处理函数
void DXXDlg::OnBnClickedButton7()
{
	// 调用AddVeh添加要下断点的地址,地址不要写重了,写重了关闭断点的时候游戏会闪退
	CCLVEH::Instance()->AddVeh("n1", 0, 0, 0x01127D60, 1, 0, fun);
	CCLVEH::Instance()->AddVeh("n2", 0, 0, 0x01128550, 1, 0, fun);
	CCLVEH::Instance()->AddVeh("n3", 0, 0, 0x01128580, 1, 0, fun);
	CCLVEH::Instance()->AddVeh("n4", 0, 0, 0x011285B0, 1, 0, fun);
	// 下断点
	CCLVEH::Instance()->InitVeh();
}

// 卸载HOOK按钮的点击事件处理函数
void DXXDlg::OnBnClickedButton8()
{
	// 关闭断点
	CCLVEH::Instance()->ExitVeh();
}

// 秒进地图按钮点击事件处理函数
void DXXDlg::OnBnClickedButton9()
{
	MyStrust mystruct;
	mystruct.StartIn();

}


// 副本内瞬移按钮点击事件处理函数
void DXXDlg::OnBnClickedButton10()
{
	MyStrust mystruct;
	mystruct.MoveInMap(1, 1);
}

// 返回城镇按钮点击事件处理函数
void DXXDlg::OnBnClickedButton11()
{
	MyStrust mystruct;
	mystruct.ComeBackTwon();
}

// 自动打副本核心,它是根据某个副本写死的逻辑只能打一个副本
// 通过网络获取副本信息的方式实现自动打副本会很复杂不适合在基础里整
void ShuaTu()
{
	MyStrust mystruct;
	while (true)
	{
		Sleep(2000);
		if (进程是否终止 == 1)
		{
			return;
		}
		mystruct.InitMy();
		switch (mystruct.My.State)
		{
		case 1:
		{
			mystruct.StartIn();
			Sleep(2000);
		}
		case 2:
		{
			Sleep(1000);
			/*mystruct.StartIn();
			Sleep(2000);*/
		}
		case 3:
		{
			if (mystruct.My.RoomX == 0 && mystruct.My.RoomY == 1 && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(1, 1);

			}




			if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(1, 0);

				//	mystruct.My.UpState = 1;
			}


			if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 0) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(1, 1);

				if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.UpState = 1;
				}




			}

			if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				//mystruct.AllKill();
				mystruct.MoveInMap(1, 2);

				//mystruct.My.DownState = 1;
			}


			if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 2) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(1, 1);

				if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.DownState = 1;
				}


			}


			if ((mystruct.My.RoomX == 1) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 1) && 进程是否终止 == 0)
			{
				//	mystruct.AllKill();
				mystruct.MoveInMap(2, 1);

				mystruct.My.DownState = 0;
				mystruct.My.UpState = 0;

			}










			if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(2, 0);
				//	mystruct.My.UpState = 1;

			}


			if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 0) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(2, 1);
				if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.UpState = 1;
				}




			}

			if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				//mystruct.AllKill();
				mystruct.MoveInMap(2, 2);
				//mystruct.My.DownState = 1;

			}


			if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 2) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(2, 1);

				if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.DownState = 1;
				}




			}


			if ((mystruct.My.RoomX == 2) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 1) && 进程是否终止 == 0)
			{
				//	mystruct.AllKill();
				mystruct.MoveInMap(3, 1);
				mystruct.My.DownState = 0;
				mystruct.My.UpState = 0;

			}








			if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(3, 0);

			}


			if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 0) && (mystruct.My.UpState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(3, 1);
				mystruct.My.UpState = 1;
				if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.UpState = 1;
				}



			}

			if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				//mystruct.AllKill();
				mystruct.MoveInMap(3, 2);
				//mystruct.My.DownState = 1;

			}


			if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 2) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 0) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(3, 1);

				if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 1))
				{
					mystruct.My.DownState = 1;
				}



			}


			if ((mystruct.My.RoomX == 3) && (mystruct.My.RoomY == 1) && (mystruct.My.UpState == 1) && (mystruct.My.DownState == 1) && 进程是否终止 == 0)
			{
				//	mystruct.AllKill();
				mystruct.MoveInMap(4, 1);
				mystruct.My.DownState = 0;
				mystruct.My.UpState = 0;

			}


			if ((mystruct.My.RoomX == 4) && (mystruct.My.RoomY == 1) && 进程是否终止 == 0)
			{
				mystruct.AllKill();
				Sleep(2000);
				mystruct.MoveInMap(5, 1);

				;
			}

			if ((mystruct.My.RoomX == 5) && (mystruct.My.RoomY == 1) && 进程是否终止 == 0)
			{
				Sleep(4000);
				mystruct.AllKill();

				call_logA("wetool:allkillover");
				Sleep(8000);
				mystruct.ComeBackTwon();

				call_logA("wetool:ComeBackTwon");

			}


		}
		default:
			break;
		}
	}
}

// 无限副本按钮
void DXXDlg::OnBnClickedButton12()
{
	进程是否终止 = 0;
	hProce = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ShuaTu, NULL, NULL, NULL);
}

// 停止副本按钮
void DXXDlg::OnBnClickedButton13()
{
	if (hProce)
	{
		进程是否终止 = 1;
	}
}

MyStrust.cpp文件的内容:修改了 ComeBackTwon函数、AllKill函数

#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++中使用字符串

	*/
	this->My.Name = (wchar_t*)(*(int*)(addressValue+0x258));
	// 一般函数名后面是W就表示有UNICODE,也就是要用宽字节
	// OutputDebugStringW(this->My.Name);
	// L""这两个"之间表示字符串,L""表示这个字符串是宽字节(使用Unicode编码)
	call_logW(L"wetool:人物姓名=%ws,测试=%ws", this->My.Name,L" 52am");
	//  [[0x1AB7CDC]+0x18C]x坐标
	//  [[0x1AB7CDC]+0x190]y坐标
	/*
		取出地址中的值,也就是取出0x1AB7CDC里的内容
		*address这样在左边只写一个*表示取内存地址里的值
		也就是取address它的值,address是0x1AB7CDC,也就是取0x1AB7CDC它的值

	*/
 
	this->My.X= *(float*)(addressValue + 0x18C);
	this->My.Y = *(float*)(addressValue + 0x190);
	char buf[256] = { 0 };
	// 拼接文字,%f表示拼接一个小数(单浮点数)
	sprintf(buf, "wetool:x=%f;y=%f", this->My.X, this->My.Y);
	OutputDebugStringA(buf);

	// [[0x1AB7CDC]+0x36A0]血量
	this->My.Blood = *(int*)(addressValue + 0x36A0);
	// 拼接文字,%d表示拼接一个整数(32位的整数)
	sprintf(buf, "wetool:血量 = %d", this->My.Blood);
	OutputDebugStringA(buf);

	My.RoomX = ReadDword(ReadDword(ReadDword(ReadDword(0x1A5FB18) + 0x20A050) + 0x8C) + 0x610);
	My.RoomY = ReadDword(ReadDword(ReadDword(ReadDword(0x1A5FB18) + 0x20A050) + 0x8C) + 0x614);
	My.State = ReadDword(ReadDword(ReadDword(0x1A5FB4C) + 0x14) + 0x28);
	call_logA("wetool:副本内x坐标:%d,副本内y坐标:%d,State:%d", My.RoomX, My.RoomY, My.State);

}

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");
	}
}

void MyStrust::ChangeBlooad(int v)
{
	try {
		__asm {
			pushad
			push 0
			push 0
			push 0
			push v
			mov ecx, 0x1AB7CDC // 里面有我们玩家角色数据的基址
			mov ecx, [ecx]
			mov eax, 0x8174E0 // 修改血量的函数地址
			call eax
			popad
		}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::ChangeBlooad error");
	}
}

void MyStrust::NewChangeBlooad(DWORD nEcx)
{
	try {
		__asm {
			pushad
			push 0
			push 0
			push 0
			push 0
			mov ecx, nEcx
			mov eax, 0x8174E0 // 修改血量的函数地址
			call eax
			popad
		}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::NewChangeBlooad error");
	}
}

// 遍历怪物列表函数,加吸怪
void MyStrust::FindMaster()
{
	wchar_t* Tmp1;
	/* 
		[[[[[0x1A5E258]+3*4+0xA8]+0x14]+0x88]+0x10]
		下方 ReadDword 函数通过 [[[[[0x1A5E258]+3*4+0xA8]+0x14]+0x88]+0x10] 这个取值算法得到附近列表(怪物列表)
	*/
	DWORD Tmp = ReadDword(ReadDword(ReadDword(ReadDword(ReadDword(0x1A5E258) + 0x3 * 4 + 0xA8) + 0x14) + 0x88) + 0x10);
	if (Tmp != 0) {// 如果是0说明没有找到怪物列表
		for (size_t i = 0; i < 100; i++)// 这里的100是随便写的
		{
			if (ReadDword(Tmp + i * 4)>0 && (ReadDword(ReadDword(Tmp + i * 4) + 0x90) == 0x211)) {
			//if (ReadDword(Tmp + i * 4)>0) {
				Tmp1 = (wchar_t*)ReadDword(ReadDword(Tmp + i * 4) + 0x258); // 0x258位置是名字
				if (Tmp1 == 0) {// 如果是0说明没有名字
					 //call_logW(L"wetool:NULL\n");
					 this->masterNum.Name[i] = L"";
				}
				else {
					/*
						打印名字到 Dbgview.exe,其中 wetool这个是为了过滤 Dbgview.exe打印的一些跟我们不相关的日志

					*/
					//call_logW(L"wetool:%ws\n", Tmp1);
					this->masterNum.Name[i] = Tmp1;
				}
				// 血量与玩家角色不是一个位置,可以在修改血量的位置追,这个不重要,后面有机会再找
				//masterNum.Blood[i] = ReadDword(ReadDword(Tmp + i * 4) + 0x90); 
				this->masterNum.type[i] = ReadDword(ReadDword(Tmp + i * 4) + 0x90);
				this->masterNum.x[i] = ReadFloat(ReadDword(Tmp + i * 4) + 0x18C);
				this->masterNum.y[i] = ReadFloat(ReadDword(Tmp + i * 4) + 0x190);
				
				this->masterNum.x[i] = this->My.X;
				this->masterNum.y[i] = this->My.Y;
				this->masterNum.Object[i] = ReadDword(Tmp + i * 4);
				
				*(FLOAT*)(ReadDword(ReadDword(Tmp + i * 4) + 0xA8) + 0xC) = this->My.X; // 修改之后会瞬移的坐标,把它的值赋值成我们玩家的坐标
				*(FLOAT*)(ReadDword(ReadDword(Tmp + i * 4) + 0xA8) + 0x10) = this->My.Y; // 修改之后会瞬移的坐标,把它的值赋值成我们玩家的坐标
				call_logW(L"wetool:第%d个对象:%x 怪物名字:%ls type:0x%x x:%f y:%f", i, this->masterNum.Object[i], this->masterNum.Name[i], this->masterNum.type[i], this->masterNum.x[i], this->masterNum.y[i]);
			}
		}
	}
	else {
		call_logA("wetool:Tmp error");
	}
}

// 吸怪加秒杀
void MyStrust::AllKill()
{
	try {
	this->InitMy();
	this->FindMaster();
	for (size_t i = 0; i < 100; i++)
	{
		if (this->masterNum.Object[i] > 0 && (this->masterNum.type[i] == 0x211)) {
		
				call_logW(L"wetool:AllKill-第%d个对象:%x 怪物名字:%ls type:0x%x x:%f y:%f", i, this->masterNum.Object[i], this->masterNum.Name[i], this->masterNum.type[i], this->masterNum.x[i], this->masterNum.y[i]);
				this->NewChangeBlooad(this->masterNum.Object[i]);// 调用修改血量的函数
				this->masterNum.Object[i] = 0;
		}
	}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::AllKill error");
	}
}

void MyStrust::StartIn()
{
	try {
		__asm
		{
			pushad
			// 切换地图
			push 0x26
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			push 0xE
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0x2
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0x1E
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x10F
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x5
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0xE
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x1
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			// 进入副本选择界面
			push 0xF
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			// 进入副本
			push 0x10
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			push 0x68
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			mov eax, 0x1127EC0
			call eax

			popad

			// 进入副本选择界面
			pushad

			push 0xF
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			popad

		}
	}
	catch (...)
	{
		OutputDebugStringA(" MyStrust::StartIn error");
	}

}

void MyStrust::MoveInMap(DWORD x, DWORD y)
{
	try {
		DWORD nEcx = *(DWORD*)0x1AEB6E4;
		__asm {
			pushad

			push 0x30
			mov ecx, nEcx
			mov eax, 0x1127D60
			call eax

			// 这里的0x2它是地图x的数据
			push x
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 这里的0x1它是地图y的数据
			push y
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax

			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax

			mov ecx, nEcx
			mov eax, 0x1127EC0
			call eax

			popad
		}
	}catch (...) {
		OutputDebugStringA(" MyStrust::StartIn error");
	}
	Sleep(2000);
	InitMy();
}

void MyStrust::ComeBackTwon()
{
	try {
		DWORD nEcx = *(DWORD*)0x1AEB6E4;
		__asm {

			pushad
			mov ecx, 0x1a3cbf4
			mov ecx, [ecx]
			push 0x18
			mov eax, 0x004E8EA0
			call eax
			popad


		/*	pushad
			mov ecx, 0x1A3CBF4
			mov ecx, [ecx]
			push 0x138D
			mov eax, 0x4E9740
			call eax
			popad*/
		}
	}
	catch (...) {
		OutputDebugStringA(" MyStrust::ComeBackTwon error");
	}
}

img

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值