63.网游逆向分析与插件开发-游戏增加自动化助手接口-自动化助手UI与游戏菜单的对接

内容来源于:易道云信息技术研究院VIP课

上一个内容:游戏公告类的C++还原-CSDN博客

码云地址(master分支):https://gitee.com/dye_your_fingers/sro_-ex.git

码云版本号:19a2828def451a280ee211c62dcd1074ed422054

代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-自动化助手UI与游戏菜单的对接.zip

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg

提取码:q9n5

--来自百度网盘超级会员V4的分享

HOOK引擎,文件名为:黑兔sdk.zip

链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw

提取码:78h8

--来自百度网盘超级会员V4的分享

游戏公告类的C++还原-CSDN博客 它的代码为基础进行修改

效果图:可能需要调节一下分辨率才能看到,我们的mfc窗口

游戏失去焦点之后就不会渲染了,然后会导致下图的中的样子发生

htdMfcDll.h文件的修改,新加 ui_helper变量

cpp 复制代码
// htdMfcDll.h: htdMfcDll DLL 的主标头文件
//

#pragma once

#ifndef __AFXWIN_H__
	#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif

#include "resource.h"		// 主符号
#include "CUI.h"
#include "GameProtect.h"
#include "GameEx.h"
#include "GameBase.h"

// ChtdMfcDllApp
// 有关此类实现的信息,请参阅 htdMfcDll.cpp
//

class ChtdMfcDllApp : public CWinApp
{
public:
	ChtdMfcDllApp();

// 重写
public:
	virtual BOOL InitInstance();
	DECLARE_MESSAGE_MAP()
protected:
	GameProtect protect;
	GameEx game_ex;
	GameBase game_base;
	CUI ui_helper;
};

htdMfcDll.cpp文件的修改,删除无用函数,新加 _ui变量、extern_all.h头文件的引入,修改了 InitInstance函数

cpp 复制代码
// htdMfcDll.cpp: 定义 DLL 的初始化例程。
//

#include "pch.h"
#include "framework.h"
#include "htdMfcDll.h"
#include "extern_all.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// #define WNDHOOK
#ifdef WNDHOOK
typedef struct htdDll
{
	HHOOK     keyHook;
	unsigned  KbdProc;
	unsigned  SetDll;

}*PHtdDll;
void htdSetDll(htdDll hDll);
htdDll mDll;
#endif

#pragma data_seg("_hdata")
int client = 0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:_hdata,RWS")

BEGIN_MESSAGE_MAP(ChtdMfcDllApp, CWinApp)
END_MESSAGE_MAP()

CUI* _ui;

// ChtdMfcDllApp 构造

ChtdMfcDllApp::ChtdMfcDllApp()
{
	
}

ChtdMfcDllApp theApp;
ChtdMfcDllApp* PtheApp;

HHOOK keyHook;
LRESULT CALLBACK KeyCallBack(int nCode, WPARAM w, LPARAM l);

BOOL ChtdMfcDllApp::InitInstance()
{
	CWinApp::InitInstance();
	protect.CheckMult();
	game_ex.InitInterface();// 初始化游戏扩展接口
	client++;
	ui_helper.Create(IDD_MAIN);
	_ui = &ui_helper;
	return TRUE;
}

extern_all.h文件的修改

cpp 复制代码
#pragma once
#include "GameBase.h"
#include "CUI.h"

extern CUI* _ui;
extern GameBase* _pgamebase;

CUI.cpp文件的修改,新加 UIShow函数、ShowUI变量

cpp 复制代码
// CUI.cpp: 实现文件
//

#include "pch.h"
#include "htdMfcDll.h"
#include "CUI.h"
#include "afxdialogex.h"


// CUI 对话框

IMPLEMENT_DYNAMIC(CUI, CDialogEx)

CUI::CUI(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MAIN, pParent)
{

}

CUI::~CUI()
{
}

void CUI::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TAB1, mTab);
}

BOOL CUI::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	
	InstallPage(new CUIWnd_0(), IDD_PAGE_0, L"信息显示", TRUE);
	InstallPage(new CUIWnd_1(), IDD_PAGE_1, L"变态功能");


	//PageINJ.Init(wAppPath);
	//PageRAN.SetAppPath(wAppPath);

	return TRUE;
}

bool CUI::InstallPage(CDialogEx* wnd, int IDD_WND, CString&& _Name, BOOL IsShow)
{

	if (CurPage >= MAX_PAGE_MAIN) return false;
	Pages[CurPage] = wnd;
	Pages[CurPage]->Create(IDD_WND, this);
	//Pages[CurPage]->SetParent(this);
	Pages[CurPage]->ShowWindow(IsShow);

	CRect rect;
	mTab.GetClientRect(&rect);
	rect.top += 46;
	rect.left += 20;
	rect.bottom += 5;
	rect.right += 5;
	Pages[CurPage]->MoveWindow(&rect);
	mTab.InsertItem(CurPage, _Name);

	CurPage++;
	return true;
}

BEGIN_MESSAGE_MAP(CUI, CDialogEx)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CUI::OnTcnSelchangeTab1)
END_MESSAGE_MAP()


// CUI 消息处理程序


void CUI::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	int n = mTab.GetCurSel();
	for (int i = 0; i < CurPage; i++)
	{
		Pages[i]->ShowWindow(i == n);
	}
}

void CUI::UIShow()
{
	auto hwndClient = ::FindWindow(L"CLIENT", L"SRO_CLIENT");
	::SetParent(this->m_hWnd, hwndClient);
	this->ShowWindow(ShowUI = !ShowUI);
}

CUI.h文件的修改,新加 UIShow函数、ShowUI变量

cpp 复制代码
#pragma once
#include "afxdialogex.h"
//增加页面头文件
#include "CUIWnd_0.h"
#include "CUIWnd_1.h"
//游戏辅助UI类
// CUI 对话框
#define MAX_PAGE_MAIN 3
class CUI : public CDialogEx
{
	DECLARE_DYNAMIC(CUI)

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

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

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

	DECLARE_MESSAGE_MAP()

	CDialogEx* Pages[MAX_PAGE_MAIN];
	short      CurPage = 0;
	bool ShowUI = false;
public:
	CTabCtrl mTab;
	virtual BOOL OnInitDialog();
	bool    InstallPage(CDialogEx* wnd, int IDD_WND, CString&& _Name, BOOL IsShow=FALSE);
	afx_msg void OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
	void UIShow();
};

GameEx.cpp文件的修改,修改了 ExitGame函数、AutoHelper函数,vip变量位置调节

cpp 复制代码
#include "pch.h"
#include "GameEx.h"
#include "htdHook2.h"
#include "GameProtect.h"
#include "extern_all.h"

extern int client;
extern GameProtect* _protect;
extern unsigned _stdcall GetFunctionAddress(int index);
htd::hook::htdHook2 hooker;
bool vip = true;
SRO_String vip_notice;

bool AutoHelper(HOOKREFS2) {
    // 使用通过获取游戏中的sro_string结构
    //auto read = _pgamebase->SRO_Res->ReadTitle((wchar_t*)0xEBC968);
    // 使用自己创建的sro_string结构
    /**
        sro_string str;
        str.Ptitle = L"您还没有开通VIP服务,只能使用普通药水辅助功能,开通VIP可以使用更高级的自动化助手功能!";
        str.lenth = 47;
        str.size = 48 * 2 + 1;
        auto read = &str;
        unsigned* _ecx = (unsigned*)0x1256E3C;
        unsigned readEcx = _ecx[0];
        unsigned _call = 0x848580;
        _asm {
            mov ecx, readEcx
            push read
            call _call
        }
    */
    _pgamebase->Init();
    DWORD* desp = (DWORD*)_ESP;
    if (vip) {
        _ui->UIShow();
        return false;
    }
    else {
        if (desp[1] == 1) {
            _pgamebase->SRO_Notice->NetNotice(&vip_notice);
            _pgamebase->SRO_Notice->ChatNotice(vip_notice.wcstr(), 0xFFFF0000);
            _pgamebase->SRO_Notice->NormalNotice(&vip_notice);
        }

        return true;
    }
}

bool ExitGame(HOOKREFS2) {
    if (vip) {
        _pgamebase->Init();
        auto read = _pgamebase->SRO_Res->ReadTitle((wchar_t*)0xEBC968);
        *read = L"自动助手 [VIP] (%s)";
    }

	DWORD* _esp = (DWORD*)_ESP;
	DWORD _val = _esp[1];

	if (_val == 0x1035D0C) {
		// AfxMessageBox(L"游戏退出!");
		auto hMuls = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, L"system_seamp");
		if (hMuls) ReleaseSemaphore(hMuls, 1, 0);
        client--;
		ExitProcess(0);
	}
	return true;
}

GameEx::GameEx()
{
    vip_notice = L"(自动化助手公告)您还没有海通VIP服务,只能使用普通的药水设定功能,开通VIP后可以享受全自动辅助功能!";
	// AfxMessageBox(L"注册hook!");
	// auto h = GetModuleHandle(NULL);
	// DWORD address = (DWORD)h;
    // DWORD* addRExit = (DWORD*)(address + 0x88C77E);
    /**addRExit = 0;*/
	// CString txt;
    // txt.Format(L"addRExit[0]D:%d,addRExit[0]X:%X,addRExit:%X", addRExit[0], addRExit[0], addRExit);
    // AfxMessageBox(txt);

    // hooker.SetHook((LPVOID)addRExit, 3, ExitGame);
    //AddVectoredExceptionHandler(1, 异常回调);
    //设置线程的dr寄存器(GetCurrentThread());
}

void GameEx::InitInterface()
{
    unsigned addr_cps =  GetFunctionAddress(0);
    hooker.SetHook((LPVOID)(addr_cps + 0x30 - 2), 0x3, ExitGame);
    hooker.SetHook((LPVOID)(addr_cps + 0x51 - 2), 0x3, ExitGame);

    unsigned addr_autohelper = GetFunctionAddress(1);
    hooker.SetHook((LPVOID)(addr_autohelper), 0x03, AutoHelper, (LPVOID)(addr_autohelper + 0x90));
}
相关推荐
番茄电脑全能王8 分钟前
《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失如何修复?
经验分享·游戏·电脑
m0_748251722 天前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
gantengsheng2 天前
基于51单片机和OLED12864的小游戏《贪吃蛇》
单片机·嵌入式硬件·游戏·51单片机
264玫瑰资源库2 天前
从零开始C++棋牌游戏开发之第三篇:游戏的界面布局设计
开发语言·c++·python·游戏·pygame·源代码管理
264玫瑰资源库2 天前
从零开始C++游戏开发之第七篇:游戏状态机与回合管理
开发语言·c++·游戏
windwind20002 天前
游戏关卡设计方法的杂感
游戏·关卡设计
白乐天_n3 天前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏
这是我583 天前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
tealcwu3 天前
【游戏设计原理】21 - 解谜游戏的设计
游戏·游戏策划
清梦20203 天前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法