9.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏连接服务器的操作

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

上一个内容:游戏底层功能对接类GameProc的实现

码云地址(master 分支):https://gitee.com/dye_your_fingers/titan

码云版本号:44c54d30370d3621c1e9ec3d7fa1e2a028e773e9

代码下载地址,在 titan 目录下,文件名为:titan-接管游戏连接服务器的操作.zip

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

提取码:q9n5

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

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

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

提取码:78h8

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

以 游戏底层功能对接类GameProc的实现 它的代码为基础进行修改

HOOK下图红框位置:0x10617046(通过之前分析找到的)

然后在注入的时候做HOOK发现,会崩溃,然后发现hook的点没有被游戏加载,解决办法我们在HOOK之前手动的把模块加载进入,不等游戏加载了

黑兔sdk升级:首先点击属性

找到下图红框位置,主要时看$(htd)\indude,如果下图红框位置不显示 $(htd)\indude

而显示不同选项,如下图红框

这时把配置这一行设置成跟下图一样,就好了

下载完升级版的黑兔std头文件可能无法正常加载到项目中,所以要手动加,首先检查它的目录对不对,如下图红框,我这里是对的,我的头文件就放在了那里

如果不对,首先点击下图红框位置

选择头文件所在目录,这样就把头文件设置好了

然后设置dll库,库目录是下图红框位置,手动设置方法与上方设置头文件一样

全部搞完之后,选择下图重新扫描解决方案,就不会报红了(就算报红也能编译通过)

这里补充一个东西:就是当执行了黑兔SDK,但是在创建项目的时候下图红框里的东西不存在

首先不打开项目启动 Visual Studio 然后选择选项:

然后看下图红框里的目录

查看目录中是否有下图红框里的两个文件,如果没有就复制到上图红框目录下

如下图


GameProc.cpp文件的修改:新加 _OnConnect函数,修改了 InitInterface函数、LoadBase函数

#include "pch.h"
#include "GameProc.h"
#include "extern_all.h"

// typedef bool(GameWinSock::* U)(char*, unsigned);



bool _OnConnect(HOOKREFS2) {
	/*
		根据虚函数表做HOOK的操作
		截取 ecx 获取 winsock 的值(指针)
	*/
	unsigned* vtable = (unsigned*)_EDX;
	//WinSock = (GameWinSock *)_ECX;
	/*
		联合体的特点是共用一个内存
		由于 GameWinSock::OnConnect 的 OnConnect函数是 GameWinSock类的成员函数
		直接 vtable[0x34 / 4] = (unsigned)&GameWinSock::OnConnect; 这样写语法不通过
		所以使用联合体,让语法通过
	*/
	union {
		unsigned value;
		bool(GameWinSock::* _proc)(char*, unsigned);
	} vproc;

	/*
		vproc._proc = &GameWinSock::OnConnect;  这一句是把我们自己写的调用connect函数的地址的出来
	*/ 
	vproc._proc = &GameWinSock::OnConnect; 
	/*
		InitClassProc函数里做的是给指针赋值的操作
		InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);这一句的意思是把
		GameWinSock类里的_OnConnect变量的值赋值成vtable[0x34/4],这个 vtable[0x34/4] 是虚表里的函数
		vtable[0x34/4]是游戏中调用connect函数的函数地址,经过之前的分析调用connect是先调用了虚表中的
		一个函数,然后从这个函数中调用了connect函数
	*/
	InitClassProc(&GameWinSock::_OnConnect, vtable[0x34/4]);
	CString str;
	str.Format(L"===vtable:%X", vtable[0x34 / 4]);
	AfxMessageBox(str);
	DWORD oldPro,backProc;
	VirtualProtect(vtable, 0x100, PAGE_EXECUTE_READWRITE, &oldPro);
	vtable[0x34 / 4] = vproc.value;
	VirtualProtect(vtable, 0x100, oldPro, &backProc);
	return true;
}

GameProc::GameProc()
{
	hooker = new htd::hook::htdHook2();
	Init();
	InitInterface();
}

void GameProc::LoadBase()
{
	LoadLibraryA("fxnet2.dll");
}

void GameProc::Init()
{
}



void GameProc::InitInterface()
{
	LoadBase();
	MessageBoxA(0, "1", "1", MB_OK);
	hooker->SetHook((LPVOID)0x10617046, 0x1, _OnConnect, 0, true);
}

新加GameWinSock.h文件:

#pragma once
class GameWinSock
{
	typedef bool(GameWinSock::* PROC)(char*, unsigned);
public:
	static PROC _OnConnect;
	bool OnConnect(char* ip, unsigned port);
};

新加GameWinSock.cpp文件:

#include "pch.h"
#include "GameWinSock.h"
#include "extern_all.h"

GameWinSock::PROC GameWinSock::_OnConnect{};
// 这个函数拦截了游戏的连接
bool GameWinSock::OnConnect(char* ip, unsigned port)
{
    // this是ecx,HOOK的点已经有ecx了
    WinSock = this;
    MessageBoxA(0, ip, ip, MB_OK);
	bool b = (this->*_OnConnect)(ip, port);
	// 下方注释的代码时为了防止多次注入,导致虚函数地址不恢复问题导致死循环,通过一次性HOOK也能解决
	/*unsigned* vtable = (unsigned*)this;
	vtable = (unsigned*)vtable[0];
	union {
		unsigned value;
		bool(GameWinSock::* _proc)(char*, unsigned);
	} vproc;

	vproc._proc = _OnConnect;

	DWORD oldPro, backProc;
	VirtualProtect(vtable, 0x100, PAGE_EXECUTE_READWRITE, &oldPro);
	vtable[0x34 / 4] = vproc.value;
	VirtualProtect(vtable, 0x100, oldPro, &backProc);*/

    return b;
}

htdMfcDll.cpp文件的修改:修改了 InitInstance函数

// htdMfcDll.cpp: 定义 DLL 的初始化例程。这是一个MFC的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

BEGIN_MESSAGE_MAP(ChtdMfcDllApp, CWinApp)
END_MESSAGE_MAP()


// ChtdMfcDllApp 构造

ChtdMfcDllApp::ChtdMfcDllApp()
{
	
}

ChtdMfcDllApp theApp;
ChtdMfcDllApp* PtheApp;

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

BOOL ChtdMfcDllApp::InitInstance()
{
	CWinApp::InitInstance();
	PtheApp = this;
#ifdef WNDHOOK
	mDll.KbdProc = (DWORD)(KeyCallBack);
	mDll.SetDll = 0;
#else
	keyHook = SetWindowsHook(WH_KEYBOARD, KeyCallBack);// 代码一开始,在这注册一个键盘事件的钩子
#endif
	PGameProc = new GameProc();
	return TRUE;
}

// 钩子处理事件
LRESULT CALLBACK KeyCallBack(int nCode, WPARAM w, LPARAM l)
{

	if (nCode == 0)
	{
		if ((l & (1 << 31)) == 0)
		{
			switch (w)
			{
			case VK_HOME:

				if (PtheApp->wndMain == NULL)
				{

					PtheApp->wndMain = new CUI();
					PtheApp->wndMain->Create(IDD_MAIN);

				}

				PtheApp->wndMain->ShowWindow(TRUE);
				break;
			}
		}
	}
	return CallNextHookEx(keyHook, nCode, w, l);
}
#ifdef WNDHOOK
void htdInit(htdDll* hDll)
{
	hDll->KbdProc = mDll.KbdProc;
	hDll->keyHook = mDll.keyHook;
	hDll->SetDll = mDll.SetDll;
}

void htdSetDll(htdDll hDll)
{
	mDll = hDll;
}
#else
void htdInit()
{
}
#endif

新加extern_all.h文件:

/*
	此文件是用来存放全局变量、全局函数(通用函数)
*/
#pragma once
#include "GameWinSock.h"
#include "GameProc.h"

extern 	GameWinSock* WinSock;
extern GameProc* PGameProc;
extern void InitClassProc(LPVOID proc_addr, unsigned value);

新加extern_all.cpp文件

/*
	此文件是用来存放全局变量、全局函数(通用函数)
*/
#include "pch.h"
#include "extern_all.h"
GameWinSock* WinSock = nullptr;
GameProc* PGameProc = nullptr;

void InitClassProc(LPVOID proc_addr, unsigned value)
{
	unsigned* writer = (unsigned*)proc_addr;
	writer[0] = value;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/411644.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

五种多目标优化算法(MSSA、MOJS、NSWOA、MOPSO、MOAHA)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解过程可以分为以下几个步骤&#xff1a; 1. 定义问题&#xff1a;首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数&#xff0c;这些目标函数可能…

ONLYOFFICE 8.0版本深度测评:革新之作还是失望之作?

引言 &#xff1a; 随着办公自动化需求的不断升级&#xff0c;拥有一款功能全面、操作便捷的办公软件显得尤为重要。在这个背景下&#xff0c;ONLYOFFICE作为一款集文档编辑、表格处理、演示制作等多功能于一体的办公套件&#xff0c;吸引了众多用户的关注。近期&#xff0c;O…

IO进程线程day8作业

信号灯集二次函数封装 sem.c #include<myhead.h>union semun {int val; /* Value for SETVAL */struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */unsigned short *array; /* Array for GETALL, SETALL */struct seminfo *__buf; /* B…

校园微社区微信小程序源码/二手交易/兼职交友微信小程序源码

云开发校园微社区微信小程序开源源码&#xff0c;这是一款云开发校园微社区-二手交易_兼职_交友_项目微信小程序开源源码&#xff0c;可以给你提供快捷方便的校园生活&#xff0c;有很多有趣实用的板块和功能&#xff0c;如&#xff1a;闲置交易、表白交友、疑问互答、任务兼职…

读书笔记之《没有工作的世界》:AI是否会取代人类?

《没有工作的世界—如何应对科技性失业与财富不平等》作者是 [英]丹尼尔苏斯金德&#xff0c; 原作名: A WORLD WITHOUT WORK&#xff1a;Technology,Automation,and How We Should Respond 丹尼尔苏斯金德&#xff08;Daniel Susskind &#xff09;&#xff1a;曾任英国首相战…

jvm面试题目补充

jdk&jre Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK&#xff08;Java Development Kit&#xff09;。 把Java API类库中的Java SE API子集 [1] 和Java虚拟机这两部分统称为JRE&#xff08;Java Runtime Environment&#xff09;&#xff0c;JRE是支持…

python学习笔记 - 标准库函数

概述 为了方便程序员快速编写Python脚本程序&#xff0c;Python提供了很多好用的功能模块&#xff0c;它们内置于Python系统&#xff0c;也称为内置函数(Built-in Functions&#xff0c;BlF)&#xff0c;Python 内置函数是 Python 解释器提供的一组函数&#xff0c;无需额外导…

网络层的DDoS攻击与应用层的DDoS攻击之间的区别

DDoS攻击&#xff08;即“分布是拒绝服务攻击”&#xff09;&#xff0c;是基于DoS的特殊形式的拒绝服务攻击&#xff0c;是一种分布式、协作的大规模攻击方式&#xff0c;主要瞄准一些企业或政府部门的网站发起攻击。根据攻击原理和方式的区别&#xff0c;可以把DDoS攻击分为两…

“一代传奇”宗庆后谢幕,500亿元饮料帝国迎交棒时刻

宗庆后同志逝世 2月25日&#xff0c;娃哈哈集团发布讣告&#xff0c;娃哈哈创始人、董事长宗庆后同志&#xff0c;因病医治无效&#xff0c;于 2024-02-25 10:30 逝世&#xff0c;享年 79 岁。 这是一位伟大的企业家。 伟大的地方不仅仅在于&#xff0c;宗庆后 42 岁开始白手起…

【网站项目】437物流管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Python字符串访问与拼接你搞懂了吗?

使用下标访问字符串&#xff0c;从0开始计数&#xff0c;-1表示最后一个字符。三种遍历字符串的方法&#xff1a;for循环、len()和enumerate()。字符串拼接只能是字符串之间使用&#xff0c;不能与数字拼接。 1.下标访问字符串 通过下标访问字符串的内容&#xff0c;下标从 0 …

蛋白结构预测模型评价指标

欢迎浏览我的CSND博客&#xff01; Blockbuater_drug …点击进入 文章目录 前言一、蛋白结构预测模型评价指标TM-scorelDDT 二、Alphafold中的评价指标pLDDTpTMPAE 三、AlphaFold-multimer 蛋白结构的评价指标DockQipTM 总结参考资料 前言 本文汇总了AlphaFold和AlphaFold-mul…

C语言函数递归

一、什么是递归 递归实际上就是函数自己调用自己。 递归在书写的时候&#xff0c;有2个必要条件&#xff1a; • 递归存在限制条件&#xff0c;当满足这个限制条件的时候&#xff0c;递归便不再继续。 • 每次递归调用之后越来越接近这个限制条件。 在下面的例子中&#xff0…

将一个 PostgreSQL 数据库复制到另一个数据库中

以管理员身份进入cmd窗口&#xff0c;输入如下命令 语法&#xff1a; pg_dump -C -h 本机IP -U 本机postgresql用户名 源数据库名 | psql -h 服务器IP -U 服务器postgresql用户名 目标数据库名 示例&#xff1a; pg_dump -C -h 127.0.0.1 -U postgres test01-dbname | psql…

leetcode:1925. 统计平方和三元组的数目(python3解法)

难度&#xff1a;简单 一个 平方和三元组 (a,b,c) 指的是满足 a2 b2 c2 的 整数 三元组 a&#xff0c;b 和 c 。 给你一个整数 n &#xff0c;请你返回满足 1 < a, b, c < n 的 平方和三元组 的数目。 示例 1&#xff1a; 输入&#xff1a;n 5 输出&#xff1a;2 解释…

AI绘画丨精美3D立体插图

利用衍纸艺术制作的3D立体精美插图&#xff0c;以星星作为主题&#xff0c;错落在整个画面中&#xff0c;一起看看他的生成关键词吧~ 使用关键词&#xff1a;A gorgeous multi-dimensional paper illustration, paper quilling, 3D diorama of a vintage stargazing illustrat…

JSON:简介与基本使用

目录 什么是JSON&#xff1f; JSON的基本结构 JSON的基本使用 在JavaScript中使用JSON 创建JSON对象 解析JSON字符串 生成JSON字符串 在其他编程语言中使用JSON 总结 什么是JSON&#xff1f; JSON&#xff0c;全称为JavaScript Object Notation&#xff0c;是一种轻量…

NCDA视觉传达设计大赛终极攻略:助你斩获佳绩

第十二届全国高校未来设计师数字艺术设计大赛&#xff08;NCDA&#xff09; A类&#xff1a;视觉传达设计 参赛对象&#xff1a; 大学生小组&#xff1a;分①研究生组②本科生组③专科生组&#xff0c;三组分别进行评审 教师小组&#xff1a;普通高校教师&#xff0c;不分小…

解除网页复制限制

chrome 中右击点检查&#xff0c; 找到要复制的文字块 把如图所示右边的 copy里的事件全部remove 然后就可以右击复制了

043 多态

示例 public class A {public void say(){System.out.println("I am A");} } public class B extends A {Overridepublic void say(){System.out.println("I am B");} } public class Test {public static void main(String[] args) {A a new B(); // …