幻世録1キャラのデータ構造
4939 ワード
つまらない研究しました.このゲームのキャラクターデータの構造を調べてみました.まだ住所がよく分かりません.教えてください.
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];
};
以下はデータを充填するプログラムで、VSL 2013で実行できます.#include
#include
#include
#include
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;
}