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));
}
相关推荐
da_vinci_x17 小时前
在Substance Designer里“预演”你的游戏着色器(Shader)
人工智能·游戏·技术美术·着色器·游戏策划·游戏美术·substance designer
reddingtons17 小时前
ZBrush细节烘焙全“糊”了?Painter“平均法线”+“偏斜贴图”的“无笼”烘焙管线
游戏·设计师·贴图·技术美术·substance painter·游戏美术·zbrush
嘀咕博客2 天前
h5游戏免费下载:HTML5拉杆子过关小游戏
前端·游戏·html5
FairGuard手游加固2 天前
Cocos资源加密方案解析
安全·游戏·cocos2d
UWA3 天前
为什么Android游戏画面在30帧运行时有抖动现象
android·游戏
软件开发技术深度爱好者3 天前
python使用Pygame库实现避障小人行走游戏
python·游戏·pygame
星空露珠3 天前
数独生成题目lua脚本
数据结构·数据库·算法·游戏·lua
wanhengidc3 天前
云手机 基于云计算的虚拟手机
运维·服务器·游戏·智能手机·云计算
王火火(DDoS CC防护)4 天前
游戏盾是如何保障游戏安全稳定的?
游戏·网络安全·ddos攻击·sdk游戏盾
上海云盾第一敬业销售4 天前
高防CDN如何确保电商平台在购物节期间运转如常
安全·游戏·ddos