47.x86游戏实战-VEHHOOK封包函数

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:46.x86游戏实战-DXX封包实现进入地图房间

上一个内容实现了进入地图,它call了很多函数

如下图红框圈出来的都是固定的

然后它们的参数每次都要找就很麻烦,如下图,可以在函数头部下断点

然后如下图红框看,这样函数的第一个参数就是esp+4,第二个参数就是esp+4+4以此类推,接下里是采用Windows的异常链的机制来实现断点(详情看:【有道云笔记】VEH Hook异常Hook)使用Windows异常链实现的HOOK 微尘网络 给了封装好的代码(如果不嫌麻烦可以看【有道云笔记】VEH Hook异常Hook看明白之后自己实现一个,其实【有道云笔记】VEH Hook异常Hook里也实现了百分之80或90的功能了,为了不浪费时间跟课程节奏就要采用 微尘网络封装好的代码)

效果图:它就把函数的参数地址打印出来了(EIP寄存器是接下来要运行的代码的地址,也就是当前函数地址)

代码相关

首先添加两个按钮

它俩的属性

点击事件的处理函数代码

DXXDlg.cpp文件的内容

// DXXDlg.cpp: 实现文件
//

#include "pch.h"
#include "WCDXX.h"
#include "afxdialogex.h"
#include "DXXDlg.h"
#include "MyStrust.h"
#include "json.h"
#include "CLVEH.h"

// DXXDlg 对话框

IMPLEMENT_DYNAMIC(DXXDlg, CDialogEx)

DXXDlg::DXXDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG1, pParent)
{
	OutputDebugStringA("执行流程-执行DXXDlg构造函数流程1");
}

DXXDlg::~DXXDlg()
{
	OutputDebugStringA("执行流程-执行DXXDlg析构函数流程1");
}

void DXXDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(DXXDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &DXXDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &DXXDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &DXXDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &DXXDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &DXXDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON6, &DXXDlg::OnBnClickedButton6)
	ON_BN_CLICKED(IDC_BUTTON7, &DXXDlg::OnBnClickedButton7)
	ON_BN_CLICKED(IDC_BUTTON8, &DXXDlg::OnBnClickedButton8)
END_MESSAGE_MAP()


// DXXDlg 消息处理程序


void DXXDlg::OnBnClickedButton1()
{
	MyStrust mystruct;
	mystruct.InitMy();
}


void DXXDlg::OnBnClickedButton2()
{

}


void DXXDlg::OnBnClickedButton3()
{
	
}


void DXXDlg::OnBnClickedButton4()
{
	MyStrust mystruct;
	mystruct.InitMy(); // 初始化玩家角色数据
	mystruct.ChangeBlooad(mystruct.My.Blood/2); // 修改血量
	
	// TODO: 在此添加控件通知处理程序代码
}


void DXXDlg::OnBnClickedButton5()
{
	MyStrust mystruct;
	mystruct.FindMaster();
}


void DXXDlg::OnBnClickedButton6()
{
	MyStrust mystruct;
	mystruct.AllKill();
}

// 断点的处理函数,ExceptionInfo里面有当前断点的寄存器的值
void fun(_EXCEPTION_POINTERS* ExceptionInfo) {
	call_loaA("wetool:EIP=%X,ECX=%X,参数=%X", ExceptionInfo->ContextRecord->Eip, ExceptionInfo->ContextRecord->Ecx, *(DWORD*)(ExceptionInfo->ContextRecord->Esp + 4));
}

// HOOK按钮的点击事件处理函数
void DXXDlg::OnBnClickedButton7()
{
	// 调用AddVeh添加要下断点的地址,地址不要写重了,写重了关闭断点的时候游戏会闪退
	CCLVEH::Instance()->AddVeh("n1", 0, 0, 0x01127D60, 1, 0, fun);
	CCLVEH::Instance()->AddVeh("n2", 0, 0, 0x01128550, 1, 0, fun);
	CCLVEH::Instance()->AddVeh("n3", 0, 0, 0x01128580, 1, 0, fun);
	// 下断点
	CCLVEH::Instance()->InitVeh();
}

// 卸载HOOK按钮的点击事件处理函数
void DXXDlg::OnBnClickedButton8()
{
	// 关闭断点
	CCLVEH::Instance()->ExitVeh();
}

CLVEH.h文件的内容

#pragma once
#include "afxmt.h"
#include <vector>
using namespace std;


#define VEHADMIN CCLVEH::Instance()

struct _VehData
{
	char VehName_[512];
	char MoudleName_[512];
	int   MoudleOffset_;
	DWORD VehHookAdress_;
	DWORD HookCodeLen_;
	BOOL  IsOnce_;
	int OldCode_;
	void(*Fun_)(struct _EXCEPTION_POINTERS * ExceptionInfo);
};


LONG NTAPI veh_optimization(struct _EXCEPTION_POINTERS * ExceptionInfo);


class CCLVEH
{
public:
	static CCLVEH* Instance();
	CCLVEH::~CCLVEH()
	{
		ExitVeh();
	}
public:
	vector<_VehData> VehList;
	CCriticalSection cs_;
	LPVOID m_Handle = 0;
public:
	void AddVeh(char * VehName, char *MoudleName, DWORD MoudleOffset, DWORD VehHookAdress, DWORD HookCodeLen_, int IsOnce, void(*Fun)(struct _EXCEPTION_POINTERS * ExceptionInfo));

public:
	void BreakAll();
	void BreakOne(DWORD CodeAdress);
	void InitVeh();
	void BreakRun(DWORD CodeAdress, _EXCEPTION_POINTERS * ExceptionInfo);
	void ExitVeh();
};

CLVEH.cpp

#include "pch.h"
#include "CLVEH.h"

#pragma  warning(disable:4996)
void VehWriteMemCode(DWORD Adress, DWORD ArgAdress, DWORD ArgLen)
{
	DWORD OldPro;
	VirtualProtect((LPVOID)Adress, ArgLen, PAGE_EXECUTE_READWRITE, &OldPro);

	_try{
		
		memcpy((void*)Adress, (void*)ArgAdress, ArgLen);
	}
	_except(1)
	{

	}

	VirtualProtect((LPVOID)Adress, ArgLen, OldPro, NULL);
}
LONG NTAPI veh_optimization(struct _EXCEPTION_POINTERS * ExceptionInfo)
{

	DWORD Addr = (DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress;
	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
	{
		//Call_输出调试信息("BreakRun\n");
		CCLVEH::Instance()->BreakRun(Addr, ExceptionInfo);
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	else if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)
	{
		//Call_输出调试信息("BreakOne\n");
		CCLVEH::Instance()->BreakOne(Addr);
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	return EXCEPTION_EXECUTE_HANDLER;
}


CCLVEH* CCLVEH::Instance()
{
	static CCLVEH instance;
	return &instance;
}



void CCLVEH::AddVeh(char * VehName, char *MoudleName, DWORD MoudleOffset, DWORD VehHookAdress, DWORD HookCodeLen_, int IsOnce, void(*Fun)(struct _EXCEPTION_POINTERS * ExceptionInfo))
{
	_VehData Data;

	strcpy(Data.VehName_, VehName);

	if (MoudleName != NULL)
		strcpy(Data.MoudleName_, MoudleName);
	else
		memset(Data.MoudleName_, 0, 512);

	Data.MoudleOffset_ = MoudleOffset;
	Data.VehHookAdress_ = VehHookAdress;
	Data.HookCodeLen_ = HookCodeLen_;
	Data.IsOnce_ = IsOnce;
	Data.Fun_ = Fun;
	VehList.push_back(Data);

}
void CCLVEH::BreakAll()
{
	cs_.Lock();
	vector<_VehData>::iterator It = VehList.begin();

	for (; It != VehList.end(); It++)
	{
		if (It->MoudleName_[0] != 0)
		{
			It->VehHookAdress_ = (DWORD)GetModuleHandleA(It->MoudleName_) + It->MoudleOffset_;
		}

		It->OldCode_ = *(BYTE*)It->VehHookAdress_;
		DWORD SetCodeData = 0xcc;
	
		VehWriteMemCode(It->VehHookAdress_, (DWORD)&SetCodeData, 1);

	}
	cs_.Unlock();
}
void CCLVEH::BreakOne(DWORD CodeAdress)
{
	cs_.Lock();
	vector<_VehData>::iterator It = VehList.begin();

	for (; It != VehList.end(); It++)
	{
	
		if (It->MoudleName_[0] != 0)
		{
			It->VehHookAdress_ = (DWORD)GetModuleHandleA(It->MoudleName_) + It->MoudleOffset_;
		}
		if (CodeAdress == It->VehHookAdress_ + It->HookCodeLen_)
		{
			DWORD SetCodeData = 0xcc;
			VehWriteMemCode(It->VehHookAdress_, (DWORD)&SetCodeData, 1);
			break;
		}


	}
	cs_.Unlock();
}

void CCLVEH::BreakRun(DWORD CodeAdress, _EXCEPTION_POINTERS * ExceptionInfo)
{
	cs_.Lock();
	vector<_VehData>::iterator It = VehList.begin();

	for (; It != VehList.end(); It++)
	{
		if (It->MoudleName_[0] != 0)
		{
			It->VehHookAdress_ = (DWORD)GetModuleHandleA(It->MoudleName_) + It->MoudleOffset_;
		}
		if (CodeAdress == It->VehHookAdress_)
		{
			VehWriteMemCode(It->VehHookAdress_, (DWORD)&It->OldCode_, 1);
		//	Call_输出调试信息("It->IsOnce_=%d\n", It->IsOnce_);
			if (It->IsOnce_ == 0)
			{
			//	Call_输出调试信息("IsOnce_\n");
				ExceptionInfo->ContextRecord->EFlags |= 0x100;
			}

			if (It->Fun_ != NULL)
			{
				It->Fun_(ExceptionInfo);
			}

			break;
		}
		

	}
	cs_.Unlock();
}
void CCLVEH::InitVeh()
{
	m_Handle = AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)veh_optimization);

	BreakAll();
}



void CCLVEH::ExitVeh()
{
	cs_.Lock();
	RemoveVectoredExceptionHandler(m_Handle);


	vector<_VehData>::iterator It = VehList.begin();

	for (; It != VehList.end(); It++)
	{
		if (It->MoudleName_[0] != 0)
		{
			It->VehHookAdress_ = (DWORD)GetModuleHandleA(It->MoudleName_) + It->MoudleOffset_;
		}

		VehWriteMemCode(It->VehHookAdress_, (DWORD)&It->OldCode_, 1);
	}
	
	cs_.Unlock();
}

上方的代码不全,只有手写的代码

完整代码:以 44.x86游戏实战-C++实现吸怪加秒杀 它的代码为基础进行修改

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg?pwd=q9n5

提取码:q9n5

复制这段内容后打开百度网盘手机App,操作更方便哦


img

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值