免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
工具下载:
链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3
提取码:6tw3
复制这段内容后打开百度网盘手机App,操作更方便哦
上一个内容:52.第二阶段x86游戏实战2-c++实现自动打怪1
CMeLua.cpp文件的修改,修改了 Lua_lu函数,Lua_lu函数也是当前代码查看的入口
c++
#include "pch.h"
#include "CMeLua.h"
extern CMessage* pMsg; // 前面带 extern 说明是全局变量,也就是说在其它文件中对 pMsg 这个名字的变量进行的修改那么这里也会被影响到
int CMeLua::LUA_Xulu(LuaState * pState)
{
LuaStack args(pState);
DWORD x = args[1].GetInteger();
DWORD y = args[2].GetInteger();
Msg_xl(x, y);
return 0;
}
void Lua_lu(int x, int y, string Scene)
{
// 寻路目的地的地图id
int SceneId = FUN_GetSceneID(Scene.c_str());
// 获取当前角色所在的地图id,之前找地图id的时候找的的GetSceneID函数
int id = pMsg->msg_getnumber("g_GetValue = GetSceneID()");
/**
如果目的地地图id和寻路的目的地地图id一样说明是当前地图寻路,就调用短寻路
两个id不一样说明是跨地图寻路就调用长寻路
*/
if (SceneId == id)
{
pMsg->msg_dostring("AutoRunToTarget(%d, %d)", (int)x, (int)y);
}
else
{
pMsg->msg_dostring("AutoRunToTargetEx(%d, %d, %d)", (int)x, (int)y, SceneId);
}
}
Hook.cpp文件的修改,新加 pMsg变量,修改了 Call_主线程回调函数函数
c++
#include "pch.h"
// 获取全局变量pMsg,它是在CM.cpp文件中声明的
extern CMessage* pMsg;
HHOOK g_Hook返回;
const DWORD g_My消息ID = RegisterWindowMessageA("MyMsyCode");// 注册一个消息号
HWND Call_获取窗口句柄()
{
// 获取游戏存放的窗口句柄,通过CE搜索spy++的句柄找到的
//HWND hGame = (HWND)((DWORD)GetModuleHandleA("CEGUIBase.dll") + 0x251030);
HWND hGame = (HWND)((DWORD)GetModuleHandleA("Game.exe") + 0x73AD98);
hGame = *(HWND*)hGame;
return hGame;
}
void Msg_xl(DWORD X, DWORD Y)
{
T寻路参数 寻路;
寻路.X = X;
寻路.Y = Y;
::SendMessageA(Call_获取窗口句柄(), g_My消息ID, ID_寻路, (LPARAM)&寻路);
}
//主线程回调函数
LRESULT CALLBACK Call_主线程回调函数(int nCode, WPARAM wParam, LPARAM lparam)
{
/*
::SendMessageA(Call_获取窗口句柄(), g_My消息ID, ID_寻路, (LPARAM)&寻路);
CWPSTRUCT类型的参数分别对应SendMessageA函数的入参,如下
LPARAM lParam = (LPARAM)&寻路
WPARAM wParam = ID_寻路
UINT message = g_My
HWND hwnd = Call_获取窗口句柄()
*/
CWPSTRUCT *lpArg = (CWPSTRUCT*)lparam;//结构 hwnd message wParam lParam
if (nCode == HC_ACTION)//自己进程的消息
{
if (lpArg->hwnd == Call_获取窗口句柄() && lpArg->message == g_My消息ID)//我们自己的消息
{
string luaText;
switch (lpArg->wParam)
{
T寻路参数*寻路;
T参数*get;
case ID_寻路:
寻路 = (T寻路参数*)lpArg->lParam;
Call_xunlu(寻路->X, 寻路->Y);
return 1;
//break;
case LUA_GETVALUE:
get = (T参数*)lpArg->lParam;
pMsg->telua_getnumber((char*)get->Y, (PVOID)get->X);
return 1;
//break;
}
}
}
return CallNextHookEx(g_Hook返回, nCode, wParam, lparam);
}
DWORD Call_Hook主线程()
{
HWND hGame = Call_获取窗口句柄();
// 通过句柄获取窗口的线程id
DWORD ndThreadId = GetWindowThreadProcessId(hGame, NULL);
if (ndThreadId != 0)
{
// 注册窗口HOOK,SetWindowsHookEx是微软提供
g_Hook返回 = SetWindowsHookEx(WH_CALLWNDPROC, Call_主线程回调函数, NULL, ndThreadId);
}
return 1;
}
Message.h文件的修改,新加 CriticalSectionLock类、T参数结构体、LUA_GETVALUE宏
c++
#pragma once
#include "pch.h"
// 专门用来处理lua的类
typedef int(*Glua_dostring)(int, const char *);//do_string
typedef int(*Glua_pushstring)(int, const char *);//pushstring
typedef void(*Glua_gettable)(int, int);//gettable
typedef double(*Glua_tonumber)(int, double);//tonumber
typedef int(*Glua_settop)(int, int);//settop
typedef const char*(*Glua_tostring)(int, int);//tostring
typedef int(*Glua_pushcclosure)(int, int, int);//
typedef void(*Glua_settable)(int, int);
typedef int(*Glua_loadfile)(int, const char*);
typedef int(*Gplua_call)(int, int, int, int);
typedef int(*Glua_type)(int, int);
typedef int(*Glua_dofile)(int, const char*);
class CMessage
{
public:
CMessage() {};
~CMessage() {};
void Init() {
//初始化游戏lua函数,lua状态机
InitLuaFun();//初始化游戏lua库函数
lua_state = getlua_state();//获取游戏lua状态机指针
LUAInitialize();
};
public:
void msg_dostring(const char* _Format, ...);
const char* telua_tostring(int n);
private:
int getlua_state();
BOOL LUAInitialize();
int InitLuaFun();//获取lua库函数
CCriticalSection m_State;
public:
/************************************************************************/
/* 游戏的lua函数接口定义 */
/************************************************************************/
int telua_loadfile(const char*file);
bool telua_register(const char *FuncName, int pFun);
bool telua_dostring(const char * args);
bool telua_getglobal(const char*name);
double telua_tonumber(int n);
bool CMessage::call_dostring(const char * buf);
void telua_pop(int n);
int msg_getnumber(char* _Format, ...);
/************************************************************************/
/* 游戏的lua函数指针定义 */
/************************************************************************/
Glua_dostring GLua_Dostring = nullptr;
Glua_pushstring GLua_Pushstring = nullptr;
Glua_gettable GLua_Gettable = nullptr;
Glua_tonumber GLua_Tonumber = nullptr;
Glua_settop GLua_Settop = nullptr;
Glua_tostring GLua_Tostring = nullptr;
Glua_pushcclosure GLua_Pushcclosure = nullptr;
Glua_settable GLua_Settable = nullptr;
Glua_loadfile GLua_Loadfile = nullptr;
Gplua_call GpLua_Call = nullptr;
Glua_type Gplua_type = nullptr;
Glua_dofile Gplua_dofile = nullptr;
int lua_state = 0;//lua状态机指针
/************************************************************************/
/* lua取值的函数 */
/************************************************************************/
bool telua_getnumber(const char* buf, PVOID out);
bool telua_getstring(const char* buf, const char* want_get_string);
string msg_getstring(const char * str_arg, char * _Format, ...);
typedef int(*lplua_dostring)(int, const char *);
lplua_dostring g_lplua_dostring;
};
//封装的临界区线程同步的类
class CriticalSectionLock
{
public:
CriticalSectionLock(CCriticalSection* cs)
{
m_cs = cs;
m_cs->Lock();
}
~CriticalSectionLock()
{
m_cs->Unlock();
}
private:
CCriticalSection* m_cs;
};
struct T参数
{
WPARAM X;
LPARAM Y;
};
// 获取当前地图id
#define LUA_GETVALUE WM_USER + 801
Message.cpp文件的修改,新加 telua_getnumber函数、telua_pop函数、msg_getnumber函数、telua_dostring函数、telua_getglobal函数、telua_tonumber函数、call_dostring函数
c++
#include "pch.h"
#include "Message.h"
#include "stringex.h"
HMODULE hDll;
extern CMessage* pMsg;
void CMessage::msg_dostring(const char * _Format, ...)
{
}
int CMessage::getlua_state()
{
return 0;
}
int CMessage::InitLuaFun()
{
HMODULE LuaPlus = GetModuleHandleA("LuaPlus.dll");
if (LuaPlus)
{
g_lplua_dostring = (lplua_dostring)GetProcAddress(GetModuleHandleA("LuaPlus.dll"), "lua_dostring");
GLua_Dostring = (Glua_dostring)GetProcAddress(LuaPlus, "lua_dostring");
GLua_Gettable = (Glua_gettable)GetProcAddress(LuaPlus, "lua_gettable");
GLua_Pushstring = (Glua_pushstring)GetProcAddress(LuaPlus, "lua_pushstring");
GLua_Tonumber = (Glua_tonumber)GetProcAddress(LuaPlus, "lua_tonumber");
GLua_Tostring = (Glua_tostring)GetProcAddress(LuaPlus, "lua_tostring");
GLua_Settop = (Glua_settop)GetProcAddress(LuaPlus, "lua_settop");
GpLua_Call = (Gplua_call)GetProcAddress(LuaPlus, "lua_pcall");
GLua_Settable = (Glua_settable)GetProcAddress(LuaPlus, "lua_settable");
GLua_Pushcclosure = (Glua_pushcclosure)GetProcAddress(LuaPlus, "lua_pushcclosure");
GLua_Loadfile = (Glua_loadfile)GetProcAddress(LuaPlus, "luaL_loadfile");
Gplua_type = (Glua_type)GetProcAddress(LuaPlus, "lua_type");
Gplua_dofile = (Glua_dofile)GetProcAddress(LuaPlus, "lua_dofile");
if (GLua_Dostring && GLua_Gettable && GLua_Pushstring
&& GLua_Tonumber && GLua_Tostring &&GLua_Settop)
{
return 1;//获取lua函数地址成功
}
else
{
return 0;//获取地址失败,模块句柄获取成功
}
}
return -1;//无效模块句柄
}
BOOL CMessage::LUAInitialize()
{
LuaStateOwner* pState = new LuaStateOwner(true);
// 在自定义资源中释放出sys
//HRSRC hResc = FindResource(hDll, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA);
//if (hResc == NULL)
//{
// Call_输出调试信息("hResc=%d,getlasterorr=%d", hResc, GetLastError());
// //dbgPrint("system.luaGetLastError == %d pMe->hDll=%s MAKEINTRESOURCE(IDR_RCDATA2)=%d", ::GetLastError(), pMe->hDll, MAKEINTRESOURCE(IDR_RCDATA2));
// return FALSE;
//}
//Call_输出调试信息("hResc=%d,getlasterorr=%d", hResc, GetLastError());
//DWORD dwImageSize = SizeofResource(hDll, hResc);
//HGLOBAL hResourecImage = LoadResource(hDll, hResc);
//Call_输出调试信息("hResourecImageetlasterorr=%d", GetLastError());
//if (hResourecImage == NULL)
//{
// return FALSE;
//}
//string luaText = (char*)hResourecImage;
//PVOID pMemory = LockResource(hResourecImage);//<<<<<quchu dizhi
//Call_输出调试信息("pMemorygetlasterorr=%d", GetLastError());
//pMsg->msg_dostring(luaText.c_str());
//if (pMemory == NULL)
//{
// Call_输出调试信息("pMemory=NULL");
// return FALSE;
//}
return TRUE;
}
bool CMessage::telua_getnumber(const char* buf, PVOID out)
{
__try {
// telua_dostring执行lua代码
if (telua_dostring(buf))
{
// 获取 g_GetValue的值
if (telua_getglobal("g_GetValue"))
{
Call_输出调试信息("g_GetValue无异常");
/**
从栈里获取一个数据,-1表示从栈顶获得一个数据,现在也就是获取g_GetValue的值
获取之后把它的值强制转成一个数字
*/
*(int*)out = (int)telua_tonumber(-1);
// 从栈中删除一个数据,telua_pop(1)这意思是删除栈顶的数据
telua_pop(1);
return true;
}
else
{
Call_输出调试信息("%s telua_getglobal erro", __FUNCTION__);
return false;
}
}
else
{
Call_输出调试信息("%s telua_dostring erro", __FUNCTION__);
return false;
}
}
__except (1) {
Call_输出调试信息(__FUNCTION__); return false;
}
}
void CMessage::telua_pop(int n)
{
__try {
/**
这是lua的api,意思是:
GLua_Settop 用来调整 lua 栈的栈顶位置
也就是从栈里删除一个数据,删除的位置是n
它实际的作用是修改lua栈顶的位置
正数:如果 index 是正数,那么栈会被调整为该索引位置。若 index 大于当前栈顶索引,会在栈顶填充 nil;
若 index 小于当前栈顶索引,栈会被截断,高于该索引的元素会被移除。
负数:当 index 为负数时,它表示相对于栈顶的位置。例如,-1 代表当前栈顶,-2 代表栈顶下面的元素。
栈会被调整到相对于栈顶 index 位置处。
零:若 index 为 0,栈会被清空,所有元素都会被移除。
*/
GLua_Settop(lua_state, -(n)-1);
}
__except (1) {
Call_输出调试信息(__FUNCTION__);
}
}
int CMessage::msg_getnumber(char* _Format, ...)//获取整形值
{
// 创建一个临界区,防止其它线程写东西导致执行代码有问题
CriticalSectionLock lock(&m_State);
int nValue = 0;
try
{
char getnumberBuf[2048] = { 0 };//用于存放getnumber的字符串缓冲区
/**
va_list list;
va_start(list, _Format);
vsprintf(getnumberBuf, _Format, list);
va_end(list);
这一段的意思是获取可变参数
就是获取 int CMessage::msg_getnumber(char* _Format, ...) 这里的...
*/
va_list list;
va_start(list, _Format);
vsprintf(getnumberBuf, _Format, list);
va_end(list);
//dbgPrint(getnumberBuf);
/**
struct T参数
{
WPARAM X;
LPARAM Y;
};
*/
T参数 getnumber;
getnumber.X = (WPARAM)&nValue;
getnumber.Y = (LPARAM)getnumberBuf;
/**
使用游戏的线程调用游戏的函数
如果不用游戏的线程调用游戏的函数,游戏有时候会崩溃退出
*/
::SendMessageA(Call_获取窗口句柄(), RegisterWindowMessageA("MyMsyCode"), LUA_GETVALUE, (LPARAM)&getnumber);
}
catch (...)
{
Call_输出调试信息(__FUNCTION__);
}
return nValue;
}
bool CMessage::telua_dostring(const char * buf)
{
stringex a = buf;
// 执行lua代码
if (call_dostring(a.c_str()))
return 1;
return 0;
}
bool CMessage::telua_getglobal(const char*name)
{
__try {
// 这是lua的api,意思是将一个参数放到lua的栈顶
GLua_Pushstring(lua_state, name);
/**
这是lua的api,意思是:
-10001是lua中的一个常量值,表示_G,_G的意思是全局表
GLua_Gettable(lua_state, -10001);这一行代码的意思
从栈顶获取一个值(键,或者说一个变量名,数据的名字),然后使用这个值(名字)
去全局表里找它对应的数据,找到数据之后把数据放到lua的栈顶
*/
GLua_Gettable(lua_state, -10001);
return true;
}
__except (1) { Call_输出调试信息("telua_getglobal异常"); return false; }
}
double CMessage::telua_tonumber(int n)
{
__try {
/**
这是lua的api,意思是:
GLua_Tonumber函数的作用是从栈里获取一个数据
GLua_Tonumber(lua_state, n)意思是n是一个序号,如果n是3,那就获取栈中第三个数据
*/
return GLua_Tonumber(lua_state, n);
}
__except (1) {
Call_输出调试信息(__FUNCTION__);
return 1.234567;
}
}
bool CMessage::call_dostring(const char * buf)
{
__try {
//Call_输出调试信息("GLua_Dostring%s", buf);
// 接收一个字符串参数并当成lua代码执行
GLua_Dostring(lua_state, buf);
return true;
}
__except (1) {
Call_输出调试信息("GLua_Dostring异常");
return false;
}
}
上方的代码不全,只有手写的代码
完整代码:以 52.第二阶段x86游戏实战2-c++实现自动打怪1 它的代码为基础进行修改
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg?pwd=q9n5
提取码:q9n5
复制这段内容后打开百度网盘手机App,操作更方便哦
