[5]创建线程获取人物信息

1.创建一个线程获取游戏中的人物数据并存储在自己申请的一块内存空间中(使用VirtualAlloc)

人物信息地址:

寻找自身相应的信息基址

自身基址:pMyBase=client.dll+0x2CC078

自身X坐标:*pMyBase+0x2c8

自身Y坐标:*pMyBase+0x2cc

自身Z坐标:*pMyBase+0x2d0

自身水平转轴:*pMyBase+0x2d4

自身纵向转轴:*pMyBase+0x2d8

寻找其他玩家相应的信息基址

玩家数组基址:pPlayerBase=client.dll+0x2E4FDC

玩家X坐标:*pPlayerBase+0x1f0

玩家Y坐标:*pPlayerBase+0x1f4

玩家Z坐标:*pPlayerBase+0x1f8

玩家血量:*pPlayerBase+0xf70

玩家阵营:*pPlayerBase+0xa0 3 CT/2 T

玩家状态:*pPlayerBase+0x54 23活/0死

CT阵营人数基址

[[[[[client.dll+0x2e3cc8]+0xc]+0x20]+0x8]+0x260]

T阵营人数基址

[[[[[client.dll+0x2e3cc8]+0x8]+0x10]+0x4]+0x26c] 

获取模块地址和获取进程差不多,可以互相参考:

/************************************************************************/
/*      功能:获取模块地址
返回值: 模块地址
*/
/************************************************************************/

DWORD CprocessInfo::MyGetModuleAddress(DWORD dwPid, PTSTR strMoudleName)
{

    //初始化结构体
    HANDLE hand = 0;
    MODULEENTRY32 ModuInfo = { 0 };
    ModuInfo.dwSize = sizeof(MODULEENTRY32);
    // 创建一个系统快照, 第二个参数如果是模块或者线程的快照,则需要填写该进程的PID,全局返回则填0;
        //调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE 。
       //TH32CS_SNAPPROCESS把系统全部进程拍出来
    hand =::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, dwPid);



    if (hand == INVALID_HANDLE_VALUE)
    {
        return 0;
    }
    
                                                //Module32First是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,
                                                //我们可以利用Module32First函数来获得第一个模块的句柄。
                                                //返回信息全在PMODULEENTRY32结构体当中
                                                //和Module32Next是一个组合,Module32First觉得去哪拿,Module32Next把其他都拿出来
    Module32First(hand, &ModuInfo);

    //通过一个循环使用Module32Next,把所有模块读取出来
    do
    {
        //通过对比字符串来判断是否当前模块已经获取,szModule模块全名;
        if (!_tcscmp((PTCHAR)ModuInfo.szModule, strMoudleName))
        {
            return(DWORD) ModuInfo.hModule;
        }

    } while (::Module32Next(hand, &ModuInfo));
    
    return 0;
}

插入.h,设置自己的人物结构体

#pragma once
struct stPlayerInfo
{
    //坐标
    FLOAT x;
    FLOAT y;
    FLOAT z;
    //转轴
    FLOAT sx;
    FLOAT zy;
    //血量
    DWORD dwHp;
    //状态
    DWORD dwState;
    //阵营
    DWORD dwCT;

}; 

重新新建一个类定义人物的数据:

#include "stdafx.h"
#include "PlayerInfo.h"/************************************************************************/
/* 功能:搜索成员信息
参数:
hProcess   游戏进程句柄
dwBaseAddress 模块数据基地址
pPlayerBufferMemory 存储地址
返回值:
VOID
/************************************************************************/
VOID FindPlayer(HANDLE hProcess, DWORD dwBaseAddress, PTCHAR pPlayerBufferMemory)
{
    //获取阵营人数
    DWORD dwCtNum = 0, dwTNum = 0;
    //CT人数
    PTCHAR pNumBase = NULL;
    ReadProcessMemory(hProcess, (LPVOID)((DWORD)dwBaseAddress + 0x2e3cc8), &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0xc, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x20, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x8, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x260, &pNumBase, 4, NULL);
    //T人数
    ReadProcessMemory(hProcess, (LPVOID)((DWORD)dwBaseAddress + 0x2e3cc8), &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x8, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x10, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x4, &pNumBase, 4, NULL);
    ReadProcessMemory(hProcess, pNumBase + 0x26c, &pNumBase, 4, NULL);
    //获取人物数组地址
    PTCHAR pPlayerIfoArrBase = (PTCHAR)((DWORD)dwBaseAddress + 0x2E4FDC);
    PTCHAR pPlayerIfoBase = NULL;      //目标基地址
                                        //自身数据地址
    PTCHAR pMyIfoArrBase = (PTCHAR)((DWORD)dwBaseAddress + 0x2CC078);
    PTCHAR pMyIfoBase = NULL;      //自身基地址
    stPlayerInfo* pstPlayerInfo = (stPlayerInfo*)pPlayerBufferMemory;  //定义结构体指针指向存储数据的位置
    
                                                                       
    //获取自身信息
    ReadProcessMemory(hProcess, pMyIfoArrBase, &pMyIfoBase, 4, NULL);
    ReadProcessMemory(hProcess, pMyIfoBase + 0x2c8, &pstPlayerInfo[0].x, 4, NULL);
    ReadProcessMemory(hProcess, pMyIfoBase + 0x2cc, &pstPlayerInfo[0].y, 4, NULL);
    ReadProcessMemory(hProcess, pMyIfoBase + 0x2d0, &pstPlayerInfo[0].z, 4, NULL);
    ReadProcessMemory(hProcess, pMyIfoBase + 0x2d4, &pstPlayerInfo[0].sx, 4, NULL);
    ReadProcessMemory(hProcess, pMyIfoBase + 0x2d8, &pstPlayerInfo[0].zy, 4, NULL);

    //获取目标信息
    stPlayerInfo stNewData = { 0 };
    for (DWORD i = 0; i < dwCtNum + dwTNum; i++)//循环遍历将所有人物信息遍历出来
    {
        //同时判断是否刷新
        ReadProcessMemory(hProcess, pPlayerIfoArrBase + i * 0x10, &pPlayerIfoBase, 4, NULL); //每个角色链表数据之间间隔查0x10
        ReadProcessMemory(hProcess, pPlayerIfoBase + 0xa0, &pstPlayerInfo[i + 1].dwCT, 4, NULL); //玩家阵营:

        ReadProcessMemory(hProcess, pPlayerIfoBase + 0x1f0, &stNewData.x, 4, NULL); //玩家X坐标
        ReadProcessMemory(hProcess, pPlayerIfoBase + 0x1f4, &stNewData.y, 4, NULL);//玩家y坐标
        ReadProcessMemory(hProcess, pPlayerIfoBase + 0x1f8, &stNewData.z, 4, NULL);//玩家z坐标

        ReadProcessMemory(hProcess, pPlayerIfoBase + 0xf70, &stNewData.dwHp, 4, NULL);//玩家血量:*pPlayerBase+0xf70 
        ReadProcessMemory(hProcess, pPlayerIfoBase + 0x54, &pstPlayerInfo[i+1].dwState,4, NULL);//玩家状态:*pPlayerBase+0x54 23活/0死 
        
    }


}
原创学习随笔心得,请勿转载!
原文地址:https://www.cnblogs.com/hanhandaren/p/11097073.html