免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
本次游戏没法给
内容参考于:微尘网络安全
工具下载:
链接: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,操作更方便哦