免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
内容来源于:易道云信息技术研究院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变量
// 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函数
// 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文件的修改
#pragma once
#include "GameBase.h"
#include "CUI.h"
extern CUI* _ui;
extern GameBase* _pgamebase;
CUI.cpp文件的修改,新加 UIShow函数、ShowUI变量
// 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变量
#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变量位置调节
#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));
}