73.游戏分析工具的添加对象与删除对象

news2024/11/13 22:32:01

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

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

上一个内容:72.树形列表绑定对应的右键菜单

以它的代码为基础进行修改

删除对象在 CwndRAN 文件中添加了事件,函数名为:OnDeleteClass

COBJContext.cpp 新加 构造函数、GetSize、GetAddress、GetNote、Delete函数

#include "pch.h"
#include "COBJContext.h"

COBJContext::~COBJContext()
{
    if (data)delete[]data;
}

void COBJContext::Save()
{
    CString val;
    val.Format(L"%d", Size);
    WritePrivateProfileString(L"main", L"address", txtAddress.GetBuffer(), txtFile);
    WritePrivateProfileString(L"main", L"size", val.GetBuffer(), txtFile);
    WritePrivateProfileString(L"main", L"note", txtNote.GetBuffer(), txtFile);
}

void COBJContext::Delete()
{
    DeleteFile(txtFile);
}

BOOL COBJContext::UpdateData(HANDLE _hProcess)
{
    return ReadProcessMemory(_hProcess, Address, data, Size, NULL);
}

void COBJContext::Set(const wchar_t* _name, const wchar_t* _address, DWORD _size, const wchar_t* _note, bool IsSet){

    CString _txtName;
    _txtName.Format(L"%s", _name);
    txtAddress.Format(L"%s", _address);
    txtNote.Format(L"%s", _note);

    if (_size > Size) {
        Size = _size;
        if (data) delete[]data;

        data = new char[Size];
    }
    Address = (LPVOID)wcstoul(_address, 0, 16);
    if(_txtName!=txtName && IsSet){
        DeleteFile(txtFile);

    }
    txtName = _txtName;
    Save();
}

DWORD COBJContext::GetSize()
{
    // TODO: 在此处插入 return 语句
    return Size;
}

CString& COBJContext::GetAddress()
{
    // TODO: 在此处插入 return 语句
    return txtAddress;
}

CString& COBJContext::GetNote()
{
    // TODO: 在此处插入 return 语句
    return txtNote;
}

COBJContext::COBJContext(const wchar_t* folder, const wchar_t* _name) {
    txtFile = folder;
    txtFile = txtFile + _name + L".ini";
    wchar_t _address[0xFF]{};
    wchar_t _note[0xFF]{};
    GetPrivateProfileString(L"main", L"address", L"0", _address, 0xFF, txtFile);
    GetPrivateProfileString(L"main", L"note", L"", _note, 0xFF, txtFile);
    DWORD _size = GetPrivateProfileInt(L"main", L"size", 0, txtFile);

    Set(_name, _address, _size, _note, false);
}

COBJContext::COBJContext(const wchar_t* folder, const wchar_t* _name, const wchar_t* _address, DWORD _size, const wchar_t* _note)
{
    txtFile = folder;
    txtFile = txtFile + _name + L".ini";
    Set(_name, _address, _size, _note, false);
}

COBJContext.h文件修 新加 构造函数、GetSize、GetAddress、GetNote、Delete函数

#pragma once
class COBJContext
{
    CString txtFile;
    CString txtName;
    LPVOID Address;// 内存地址
    /**
        内存地址不是一个简单的数字,它有可能是一个 基址 加上 一个数字,有可能还是一个指针算出来的
        然后这种的通过字符串进行记录,让它通过字符串可以算出内存地址
        Address 与 txtAddress配套使用
    */
    CString txtAddress;
    DWORD Size{};
    CString txtNote;
    char* data;
public:
    COBJContext(const wchar_t* folder, const wchar_t* _name);
    COBJContext(const wchar_t* folder, const wchar_t* _name, const wchar_t * _address, DWORD _size, const wchar_t* _note);
    ~COBJContext();
public:
    void Save();
    void Delete();
    BOOL UpdateData(HANDLE _hProcess);
    void Set(const wchar_t* _name, const wchar_t* _address, DWORD _size, const wchar_t* _note, bool IsSet=true);
public:
    DWORD GetSize();
    CString& GetAddress();
    CString& GetNote();
};

typedef struct TREE_DATA {
    DWORD MenuId{};
    LPVOID DATA_PTR{};
}*PTREE_DATA;

CwndRAN.h

#pragma once
#include "CWndAddClass.h"
#include "CWindProcess.h"
#include "COBJContext.h"

// CwndRAN 对话框

class CwndRAN : public CDialogEx
{
    DECLARE_DYNAMIC(CwndRAN)

public:
    CwndRAN(CWnd* pParent = nullptr);   // 标准构造函数
    virtual ~CwndRAN();

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_PAGE_2 };
#endif

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    DECLARE_MESSAGE_MAP()
private:
    void OnOK();
    void OnCancel();
public:
    CTreeCtrl mTree;
    CListCtrl LstData;
    CWindProcess wndSelProcess;
    CWndAddClass wndAddClass;
    HANDLE hProcess{};
    CString wAppPath;
    CString wAnlyPath;
    CString wAnlyData;


    afx_msg void OnBnClickedButton1();
    afx_msg void OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
    virtual BOOL OnInitDialog();
    afx_msg void OnNMRClickTree1(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnLoadGame();
    void SetAppPath(const wchar_t * path);

    HTREEITEM InsertItemEx(const wchar_t* txt, DWORD _menuId, LPVOID _data, HTREEITEM h = TVI_ROOT);
    void DeleteItemEx(HTREEITEM h);
    afx_msg void OnAddClass();
    afx_msg void OnDeleteClass();

    HTREEITEM GetFirstItem(HTREEITEM h);
};

CwndRAN.cpp文件中修改了 OnAddClass、OnLoadGame函数,添加了 GetFirstItem

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

#include "pch.h"
#include "GAMEHACKER2.h"
#include "CwndRAN.h"
#include "afxdialogex.h"


// CwndRAN 对话框

IMPLEMENT_DYNAMIC(CwndRAN, CDialogEx)

CwndRAN::CwndRAN(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_PAGE_2, pParent)
{

}

CwndRAN::~CwndRAN()
{
}

void CwndRAN::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TREE1, mTree);
    DDX_Control(pDX, IDC_LIST1, LstData);
}

void CwndRAN::OnOK()
{
}

void CwndRAN::OnCancel()
{
}


BEGIN_MESSAGE_MAP(CwndRAN, CDialogEx)
    ON_BN_CLICKED(IDC_BUTTON1, &CwndRAN::OnBnClickedButton1)
    ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CwndRAN::OnTvnSelchangedTree1)
    ON_NOTIFY(NM_RCLICK, IDC_TREE1, &CwndRAN::OnNMRClickTree1)
    ON_COMMAND(ID_32773, &CwndRAN::OnLoadGame)
    ON_COMMAND(ID_32774, &CwndRAN::OnAddClass)
    ON_COMMAND(ID_32784, &CwndRAN::OnDeleteClass)
END_MESSAGE_MAP()


// CwndRAN 消息处理程序


void CwndRAN::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    // 添加一个数据
    auto val = mTree.InsertItem(L"第一层", TVI_ROOT);
    // 给val添加一个子数据
    mTree.InsertItem(L"第二层", val);
    // 删除一个数据
    // mTree.DeleteItem(val);

    // 获取跟节点(第一行的第一层数据)
    // auto _root = mTree.GetRootItem();
    // 获取下一个跟节点
    // mTree.GetNextSiblingItem(_root);
    // 获取子数据
    // auto childData = mTree.GetChildItem(_root);
    // mTree.GetParentItem(childData);
}


void CwndRAN::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
}

BOOL CwndRAN::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    LONG_PTR lStyle;
    // 得到窗口的样式,GWL_STYLE在GetWindowLongPtr说明中有
    lStyle = GetWindowLongPtr(LstData.m_hWnd, GWL_STYLE);
    lStyle |= LVS_REPORT;
    SetWindowLongPtr(LstData.m_hWnd, GWL_STYLE, lStyle);

    DWORD dStyle = LstData.GetExtendedStyle();
    dStyle |= LVS_EX_FULLROWSELECT;
    dStyle |= LVS_EX_GRIDLINES;
    LstData.SetExtendedStyle(dStyle);

    LstData.InsertColumn(0, L"内存地址", 0, 200);
    LstData.InsertColumn(1, L"偏移", 0, 200);
    LstData.InsertColumn(2, L"类型", 0, 200);
    LstData.InsertColumn(3, L"名称", 0, 200);
    LstData.InsertColumn(4, L"值", 0, 200);
    LstData.InsertColumn(5, L"注释", 0, 200);

    return TRUE;
}


void CwndRAN::OnNMRClickTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
    DWORD dMenuId = 1;
    if (hProcess) {
        auto hSel = mTree.GetSelectedItem();
        if (hSel) {
            PTREE_DATA val = (PTREE_DATA)mTree.GetItemData(hSel);
            if (val)dMenuId = val->MenuId; else dMenuId = 0;
        }
        else dMenuId = 0;
    }
    if (dMenuId == 0)return;
    // 获取最后一个消息发生时的鼠标位置
    DWORD dwPos = GetMessagePos();
    CPoint point(LOWORD(dwPos), HIWORD(dwPos));
    CMenu menu;
    menu.LoadMenuW(IDR_MENU1);
    CMenu* pop = menu.GetSubMenu(dMenuId);
    pop->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
    
}


void CwndRAN::OnLoadGame()
{
    if (wndSelProcess.DoModal() == IDOK) {
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, wndSelProcess.dPid);
        if (hProcess) {
            auto troot = InsertItemEx(wndSelProcess.wExe, 2, NULL);
            InsertItemEx(L"公共数据",3, NULL ,troot);
            InsertItemEx(L"公共函数",4, NULL ,troot);
            InsertItemEx(L"HOOK分析",5, NULL ,troot);
        /*    mTree.InsertItem(L"公共数据", troot);
            mTree.InsertItem(L"公共函数", troot);
            mTree.InsertItem(L"HOOK分析", troot);*/

            wAnlyData = wAnlyPath + wndSelProcess.wExe+L"\\";
            
            if (!PathIsDirectory(wAnlyData)) {
                if (!CreateDirectory(wAnlyData, NULL)) {
                    AfxMessageBox(L"创建文件夹失败!");
                    return;
                }
            }

            // 遍历文件夹下的文件
            WIN32_FIND_DATA fileData;
            HANDLE hFind = FindFirstFile(wAnlyData + L"\\*.ini", &fileData);
            while (hFind != INVALID_HANDLE_VALUE) {
                CString _Name = fileData.cFileName;
                _Name.Replace(L".ini", L"");
                COBJContext* obj = new COBJContext(wAnlyData, _Name);
                auto hRoot = InsertItemEx(_Name, 6, obj, TVI_ROOT);
                auto hBase = InsertItemEx(L"基本信息", 6, NULL, hRoot);
                CString txtVal;
                        txtVal = L"内存地址:" + obj->GetAddress();
                        InsertItemEx(txtVal, 6, NULL, hBase);
                        txtVal.Format(L"对象大小:[%d]", obj->GetSize());
                        InsertItemEx(txtVal, 6, NULL, hBase);
                        txtVal = L"注释:" + obj->GetNote();
                        InsertItemEx(txtVal, 6, NULL, hBase);
                InsertItemEx(L"成员变量", 6, NULL, hRoot);
                InsertItemEx(L"成员函数", 6, NULL, hRoot);
                if (!FindNextFile(hFind, &fileData))break;
            }
            FindClose(hFind);
        }
        else {
            AfxMessageBox(L"游戏加载失败");
        }
    }
}

void CwndRAN::SetAppPath(const wchar_t* path)
{
    wAppPath = path;
    wAnlyPath = wAppPath + L"RAN\\";
}

HTREEITEM CwndRAN::InsertItemEx(const wchar_t* txt, DWORD _menuId, LPVOID _data, HTREEITEM h)
{
    auto _rt = mTree.InsertItem(txt, h);
    PTREE_DATA DATA_PTR = new TREE_DATA{ _menuId, _data };
    mTree.SetItemData(_rt, (DWORD_PTR)DATA_PTR);
    return _rt;
}

void CwndRAN::DeleteItemEx(HTREEITEM h)
{
    PTREE_DATA val = (PTREE_DATA)mTree.GetItemData(h);
    if (val)delete val;

}


void CwndRAN::OnAddClass()
{
    // TODO: 在此添加命令处理程序代码
    if (!hProcess)return;
    if (wndAddClass.DoModal() == IDOK) {
        auto h = mTree.GetRootItem();
        while (h)
        {
            h = mTree.GetNextSiblingItem(h);
            auto txt = mTree.GetItemText(h);
            if (txt == wndAddClass.txtName) {
                AfxMessageBox(L"该对象已存在!请勿添加重名对象!");
                return;
            }
        }

        COBJContext* obj = new COBJContext(wAnlyData, wndAddClass.txtName, wndAddClass.txtAddress, wndAddClass.Size, wndAddClass.txtNote);
        obj->Save();

        auto hRoot = InsertItemEx(wndAddClass.txtName, 6, obj, TVI_ROOT);
        auto hBase = InsertItemEx(L"基本信息", 6, NULL, hRoot);
        CString txtVal;
        txtVal = L"内存地址:" + obj->GetAddress();
        InsertItemEx(txtVal, 6, NULL, hBase);
        txtVal.Format(L"对象大小:[%d]", obj->GetSize());
        InsertItemEx(txtVal, 6, NULL, hBase);
        txtVal = L"注释:" + obj->GetNote();
        InsertItemEx(txtVal, 6, NULL, hBase);
        InsertItemEx(L"成员变量", 6, NULL, hRoot);
        InsertItemEx(L"成员函数", 6, NULL, hRoot);
    }
}


void CwndRAN::OnDeleteClass()
{
    // TODO: 在此添加命令处理程序代码
    auto hSel = mTree.GetSelectedItem();
    auto hRoot = mTree.GetRootItem();
    if (hSel == hRoot)return;
    auto h = GetFirstItem(hSel);
    PTREE_DATA VAL = (PTREE_DATA)mTree.GetItemData(h);
    if (VAL) {
        COBJContext* p = (COBJContext*)VAL->DATA_PTR;
        if (p) {
            p->Delete();
            delete p;
        }
        delete VAL;
    }
    DeleteItemEx(h);
}

HTREEITEM CwndRAN::GetFirstItem(HTREEITEM h)
{
    HTREEITEM newH = h;
    HTREEITEM oldH;
    do{
        oldH = newH;
        newH = mTree.GetParentItem(oldH);
    } while (newH);
    return oldH;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

猎码安卓APP开发IDE,amix STUDIO中文java,HTML5开发工具

【无爱也能发电】Xili 2024/8/2 10:41:20 猎码安卓APP开发IDE,amix java开发工具 我研发这些只有一小部分理由是为了赚钱&#xff0c;更多是想成就牛逼的技术产品。 目前的产品就够我赚钱的&#xff0c;我持续更新就好了&#xff0c;没必要继续研究。 IDE不赚钱&#xff0c;谁…

【Redis进阶】缓存应用

目录 缓存击穿 概念 缓存击穿的原因 缓存击穿的影响 缓存击穿的应对措施 设置分布式锁 提前更新缓存 请求分级和降级 缓存穿透 概念 缓存穿透的原因 缓存穿透的应对措施 缓存空值 布隆过滤器 限流和黑名单 缓存雪崩 缓存雪崩概念 缓存雪崩的原因 应对措施 缓…

gogs的安装和使用(docker)

1.docker安装gogs 1.1 拉取gogs镜像 docker pull gogs/gogs #也可改为自己需要的版本号 1.2 创建存储目录 mkdir /root/gogs 1.3 运行镜像 docker run --namegogs -d -p 10022:22 -p 13000:3000 -v /root/gogs:/data gogs/gogs 1.3.1 指令解析 --namegogs: 指定名称…

力扣刷题-轮转数组

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 首先&#xff0c;我们现在这里提供的是一种特别简单的思路&#xff0c;我们先来看一下这段代码&#xff1a; void rotate(int* nums, int numsSize, int k) {k%numsSize;int n…

深入了解核函数:连接机器学习与统计学的桥梁

引言 在机器学习中&#xff0c;支持向量机&#xff08;SVM&#xff09;是一种强大的监督学习模型&#xff0c;特别适合处理分类问题。然而&#xff0c;SVM最初被设计用于线性可分的数据集&#xff0c;现实中的数据往往不是线性可分的。为了解决这一问题&#xff0c;我们引入了…

第十一届MathorCup高校数学建模挑战赛-C题:基于有限差分法的散热机理建模与海底数据中心优化设计

目录 摘 要 1 问题重述 1.1 问题背景 1.2 问题重述 2 问题分析 3 模型假设 4 符号说明 5 我们的工作 6 模型的建立与求解 6.1 建模前的准备 6.2 问题一的建模与求解 6.3 问题二的建模与求解 6.4 问题三的建模与求解 6.5 问题四的建模与解决 7 结果检验及误差分析 8 模型评价 9 …

[Modbus] Modbus协议开发-基本概念(一)

历史 ModBus官网是Modicon&#xff08;Modicon早年已被施耐德收购&#xff09;公司为其PLC通讯而开发的一种通讯协议。 概述 通过Modbus协议&#xff0c;控制器之间、或控制器经由网络&#xff08;如以太网&#xff09;可以和其它设备之间进行通信。 优点 免费、好用、成熟…

springboot项目搭建集成 redis/跨域/远程请求

目录 一&#xff0c;创建maven项目 1&#xff0c;左上角file > new > maven project 2&#xff0c;next 到 创建 Group id 和 Artifact id​编辑​编辑 二&#xff0c;配置springboot 1&#xff0c;配置pom文件&#xff0c; 2&#xff0c;创建启动类 3&#xff…

五段式S型算法笔记

设定已知&#xff1a;v0 vmax j&#xff1b; 减加速段&#xff1a;tm到tmax 加加速段&#xff1a;0到tm tm&#xff1a;中点时间 vm&#xff1a;中点速度 vmax&#xff1a;最大速度&#xff1b; j加速度的斜率 -j相反加速度的斜率 这个图首先说明&#xff…

大数据面试SQL(六):共同使用ip用户检测问题

文章目录 共同使用ip用户检测问题 一、题目 二、分析 三、SQL实战 四、样例数据参考 共同使用ip用户检测问题 一、题目 现有用户登录日志表&#xff0c;记录了每个用户登录的IP地址&#xff0c;请查询共同使用过3个及以上IP的用户对。 样例数据&#xff1a; 结果数据&…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]jicao

题目&#xff1a; 这段PHP代码的意思是&#xff1a; 对index.php文件进行语法高亮显示&#xff0c;插入flag.php文件&#xff0c;变量id的值为POST传递的值&#xff0c;变量json的值为GET传递的json类型的值。当id值为wllmNB且json中含有键为“x”&#xff0c;值为“wllm”的时…

【Android】安卓四大组件之Service用法

文章目录 使用Handler更新UIService基本特点启动方式非绑定式服务使用步骤 绑定式服务步骤 生命周期非绑定式启动阶段结束阶段 绑定式启动阶段结束阶段 前台Service使用步骤结束结束Service本身降级为普通Service降级为普通Service 使用Handler更新UI 主线程创建Handler对象&a…

文件描述符中设置FD_CLOEXEC的用处

linux中&#xff0c;父进程fork出子进程&#xff0c;子进程本身会继承父进程的所有文件描述符。若子进程再调用exec系列函数转化为新的进程实体&#xff0c;其实父进程的描述符对其没有意义。此时文件上只需要设置FD_CLOEXEC即可。 下面是例子说明&#xff1a; #include <…

vue3、uniapp-vue3模块自动导入

没有使用插件 使用插件,模块自动导入 安装: npm i -D unplugin-auto-importvite.config.js (uniapp没有此文件,在项目根目录下创建) import { defineConfig } from "vite"; import uni from "dcloudio/vite-plugin-uni"; import AutoImport from &qu…

SpringBoot 自定义 Starter 实现

一、定义&#xff0c;什么是Starter SpringBoot Starter 是”一站式服务&#xff08;one-stop service&#xff09;“的依赖 Jar 包&#xff1a; 包含 Spring 以及相关技术&#xff08;比如Redis&#xff09;的所有依赖提供了自动配置的功能&#xff0c;开箱即用提供了良好的…

7. Kubernetes核心资源之Service服务实战

**service分类 : ** **ClusterIP : ** 默认类型&#xff0c;自动分配一个【仅集群内部】可以访问的虚拟IP **NodePort : ** 对外访问应用使用&#xff0c;在ClusterIP基础上为Service在每台机器上绑定一个端口&#xff0c;就可以通过: ipNodePort来访问该服务 **LoadBalanc…

[24年新算法]NRBO-XGBoost回归+交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测

[24年新算法]NRBO-XGBoost回归交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测 多输入单输出 程序已调试好&#xff0c;无需更改代码替换数据直接使用&#xff01;&#xff01;&#xff01;数据格式为excel格式&#xff01;如下。 中文注释清晰&#xff0c;图很丰富 …

2. C++的指针作用

目录 1.问题描述及分析 2.结论 不同类型所产生的指针在C语言中有什么作用&#xff1f;带着这个疑问&#xff0c;对C的指针进行简介。 1.问题描述及分析 在如下的一段代码中&#xff0c;分别有4个指针&#xff0c;这四个指针有什么不一样的地方么&#xff1f; class ZooAni…

Unity物理模块 之 ​2D刚体

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​ 1.刚体是什么 在 Unity 中&#xff0c;刚体&#xff08;Rigidbody&#xff09; 是物理引擎中最基本的组件之一&#x…

Python 函数(2)

2、函数 2.1、函数传递列表 将列表传递给函数后&#xff0c;函数就能直接访问其内容。 下列为一个实例&#xff1a;将一个名字列表传递给一个名为greet_users()的函数&#xff0c;这个函数将会向列表中的每一个元素执行相应的信息。 def greet_users(name):for name in name…