无聊研究了一下幻世录1这款游戏的角色数据结构,还有很多地址不清楚什么意思,希望有人可以告诉我!!!
struct Hero
{
int attributeLL[4]; // 力量 反应 精神 体质(变化下限)
int image[2]; // 人物头像 ?
int attributeUL[4]; // 力量 反应 精神 体质(变化上限)
// 力量 反应 精神 体质
// (颜色变化限制,此值比attributeUL小时显示红色,比attributeUL大但不超过50时显示黄色,否则白色)
int attributeMax[4];
int index; // 角色序号(改后会死亡)
int experience[2]; // 现在的/需要的经验
int a3[3];
int level; // 等级
int a4[5];
int strength[9]; // 防御力 敏捷度 ? 攻击力 ? ? ? 魔击力 ?上限
int state[5]; // 生命力现在/总共 魔法现在/总共 气力(一个格0)
int equip[6]; // 装备
int resistance[5]; // 抗土水风火心
int a5[5];
int step; // 步数
int a6[2];
int goods[8]; // 物品
int a7[60];
};
下面是填充数据的程序,在VS2013可以运行。
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <vector>
using namespace std;
struct Hero
{
int attributeLL[4]; // 力量 反应 精神 体质(变化下限)
int image[2]; // 人物头像 ?
int attributeUL[4]; // 力量 反应 精神 体质(变化上限)
// 力量 反应 精神 体质
// (颜色变化限制,此值比attributeUL小时显示红色,比attributeUL大但不超过50时显示黄色,否则白色)
int attributeMax[4];
int index; // 角色序号(改后会死亡)
int experience[2]; // 现在的/需要的经验
int a3[3];
int level; // 等级
int a4[5];
int strength[9]; // 防御力 敏捷度 ? 攻击力 ? ? ? 魔击力 ?上限
int state[5]; // 生命力现在/总共 魔法现在/总共 气力(一个格0)
int equip[6]; // 装备
int resistance[5]; // 抗土水风火心
int a5[5];
int step; // 步数
int a6[2];
int goods[8]; // 物品
int a7[60];
};
DWORD findBeginAddress(HANDLE m_hProcess)
{
BYTE* pTarget = new BYTE[sizeof(int)];
sscanf_s("4213", "%d", pTarget);
MEMORY_BASIC_INFORMATION mbi;
DWORD outAddress = 0;
DWORD dwMaxAddress = (DWORD)0x7ffeffff;
DWORD dwMinAddress = (DWORD)0x10000;
PBYTE pAddress = (PBYTE)dwMinAddress;
DWORD dwSearchSize = dwMaxAddress - dwMinAddress;
BYTE *lpBuf = new BYTE[1];
DWORD dwBufSize = 1;
DWORD dwSearchDataSize = sizeof(int);
int counts = 0;
while (TRUE)
{
if ((DWORD)pAddress > dwMaxAddress)
{
break;
}
if (sizeof(mbi) != VirtualQueryEx(m_hProcess, pAddress, &mbi, sizeof(mbi)))
{
break;
}
if (MEM_COMMIT != mbi.State || 0 == mbi.Protect
|| (PAGE_GUARD & mbi.Protect) != 0
|| (PAGE_NOACCESS & mbi.Protect) != 0)
{
pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
continue;
}
if (mbi.RegionSize > dwBufSize)
{
delete[] lpBuf;
dwBufSize = mbi.RegionSize;
lpBuf = new BYTE[dwBufSize];
}
if (FALSE == ReadProcessMemory(m_hProcess, mbi.BaseAddress,
lpBuf, (DWORD)mbi.RegionSize, NULL))
{
pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
continue;
}
SIZE_T nMax = mbi.RegionSize - dwSearchDataSize;
for (SIZE_T i = 0; i <= nMax; i++)
{
if (0 == memcmp(pTarget, &lpBuf[i], dwSearchDataSize - 1)
&& 0x3D8 == (0xFFF & ((DWORD)mbi.BaseAddress + i)) )
{
outAddress = (DWORD)mbi.BaseAddress + i;
counts++;
i += dwSearchDataSize - 1;
}
}
if (1 == counts)
break;
pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
}
delete[] pTarget;
pTarget = NULL;
delete[] lpBuf;
lpBuf = NULL;
return outAddress - 0x10;
}
int main()
{
DWORD regionSize = (DWORD)sizeof(Hero) * 4;
BYTE* lpBuf = new BYTE[regionSize];
DWORD m_dwProcessID = 0; // 需要自己在任务管理器中查询
HANDLE m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_dwProcessID);
do
{
if (0 == m_hProcess)
break;
PVOID headAddress = (PVOID)findBeginAddress(m_hProcess);
if (0 == headAddress)
break;
if (lpBuf != NULL && FALSE == ReadProcessMemory(m_hProcess, headAddress,
lpBuf, regionSize, NULL))
{
break;
}
BYTE* buf = lpBuf;
Hero* pHero1 = (Hero*)buf;
buf += sizeof(Hero);
Hero* pHero2 = (Hero*)buf;
buf += sizeof(Hero);
Hero* pHero3 = (Hero*)buf;
buf += sizeof(Hero);
Hero* pHero4 = (Hero*)buf;
for (int i = 0; i < sizeof(Hero) / sizeof(int) * 4; i++)
{
if (i % (sizeof(Hero) / sizeof(int)) == 0)
cout << endl;
cout << *((int*)pHero1 + i) << " ";
}
} while (0);
CloseHandle(m_hProcess);
m_hProcess = NULL;
delete[] lpBuf;
lpBuf = NULL;
return 0;
}