幻世録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;
}