Registration Code (Part 1): w%kQ6
Registration Code (Part 2): b<#$1[*(cw~
In order to register on this forum, you must use the codes above. Combine them into one code (copy paste).

Resident Evil 3 Entity Structure

Topics regarding the Resident Evil game series.
Post Reply
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Resident Evil 3 Entity Structure

Post by atom0s » Fri Jan 09, 2015 9:45 am

This is the entity structure used for Resident Evil 3 (also known as BioShock 3):

This structure is created within 010 Editor using their awesome template system. It should port to a header file with ease though if need be.
Side note: Part of this struct that is marked unknown is actually the entity list structure of the entities that are within the same zone as the entity using this structure.
  1. struct Entity
  2. {
  3.     unsigned int    RenderModel;
  4.     unsigned char   PlayerReaction;     // (Shot, pushed, fall, etc.)
  5.     unsigned char   Unknown0000;        // Something to do with action.
  6.     unsigned char   IdleAnimation;      // Hand on hip, weapon drawn, etc.
  7.     unsigned char   Unknown0001;
  8.     unsigned char   Unknown0002;        // Has something to do with how the char is drawn.
  9.     unsigned char   Collision;          // Handles if we collide with an object. (Set to -1 for no-clip.)
  10.     unsigned short  Unknown0003;
  11.     unsigned char   LastObjectInteract; // Seems to be set when you talk to things.
  12.     unsigned char   Unknown0004;
  13.     unsigned char   Unknown0005;
  14.     unsigned char   Unknown0006;
  15.     unsigned int    Unknown0007;
  16.     unsigned int    UnknownVTablePtr0000;   // Pointer to a class VTable.
  17.     unsigned int    Unknown0008;
  18.     unsigned int    Unknown0009;
  19.     unsigned int    UnknownMovement0000;    // Read/write while moving.
  20.     unsigned int    UnknownMovement0001;    // Read/write while moving.
  21.     unsigned int    UnknownMovement0002;    // Read/write while moving.
  22.     unsigned int    UnknownMovement0003;    // Read/write while moving.
  23.     unsigned int    UnknownMovement0004;    // Read/write while moving.
  24.     signed int      PlayerXCoord;
  25.     signed int      PlayerZCoord;
  26.     signed int      PlayerYCoord;
  27.     signed short    PlayerLastXCoord;       // Non-editable
  28.     signed short    PlayerLastZCoord;       // Non-editable
  29.     signed short    PlayerLastYCoord;       // Non-editable
  30.     unsigned short  Unknown0010;            // Read constantly, not sure.
  31.     unsigned int    Unknown0011;            // Read after exiting a door.
  32.     unsigned int    Unknown0012;
  33.     unsigned int    Unknown0013;
  34.     unsigned int    Unknown0014;
  35.     unsigned int    Unknown0015;
  36.     unsigned int    Unknown0016;
  37.     unsigned int    Unknown0017;
  38.     unsigned int    Unknown0018;
  39.     unsigned int    Unknown0019;
  40.     unsigned short  Roll;
  41.     unsigned short  Yaw;                    // Also known as 'Heading' or 'Rotation'.
  42.     unsigned short  Pitch;                  // Stored as an integer but not used as one.
  43.     unsigned short  Unknown0020;
  44.     unsigned int    Unknown0021;
  45.     unsigned int    Unknown0022;
  46.     unsigned int    UnknownVTablePtr0001;
  47.     unsigned char   CollisionFlags0000;     // Prevents the player from colliding vertical. (Noclip without falling.)
  48.     unsigned char   CollisionFlags0001;     // Causes the player to invert stairs. (Walk up instead of down etc.)
  49.     unsigned char   CollisionFlags0002;     // Alters how a player walks up stairs and other objects.
  50.     unsigned char   Unknown0023;            // Always -1
  51.     unsigned int    PlayerPointer0000;      // Pointer to the start of this structure.
  52.     signed int      PlayerXCoordCopy;
  53.     signed int      PlayerZCoordCopy;
  54.     signed int      PlayerYCoordCopy;
  55.     signed short    PlayerXCoordCopy1;
  56.     signed short    PlayerZCoordCopy2;
  57.     signed short    PlayerYCoordCopy3;
  58.     signed short    Unknown0024;            // Lower-end is -62 from initialization.
  59.     signed short    Unknown0025;            // Lower-end is -62 from initialization.
  60.     signed short    Unknown0026;            // Always 0x0AF0 from initialization.
  61.     signed short    Unknown0027;            // Lower-end is -62 from initialization.
  62.     signed short    Unknown0028;            // Lower-end is -62 from initialization.
  63.     unsigned int    Unknown0029;
  64.     unsigned int    Unknown0030;
  65.     unsigned short  Unknown0031;
  66.     unsigned short  CollisionBitFlag;       // Seems to change when you collide with stuff.
  67.     unsigned int    Unknown0032;            // Crashes the game when altered.
  68.     unsigned int    Unknown0033;            // Crashes the game when altered.
  69.     unsigned short  Unknown0034;
  70.     unsigned short  Unknown0035;
  71.     unsigned int    CollisionValue0000;     // Unknown value that deals with collision.
  72.     unsigned short  CollisionValue0001;     // Unknown value that deals with how fast you can turn while colliding.
  73.     unsigned short  CollisionValue0002;     // Set to 1 when you walk backward.
  74.     unsigned short  CollisionValue0003;     // Unknown value that deals with movement.
  75.     unsigned short  Unknown0036;
  76.  
  77.     union
  78.     {
  79.         struct PAnimation
  80.         {
  81.             unsigned char   PlayerAnimationId;      // The ID of the current animation.
  82.             unsigned char   PlayerAnimationFrame;   // The frame number of the current animation.
  83.             unsigned char   PlayerBreathFrame;      // Guessed, set to 9 for a laugh.
  84.             unsigned char   Unknown0000;
  85.         };
  86.         unsigned int Animation;
  87.     } PlayerAnimation;
  88.  
  89.     unsigned short  PlayerCondition;        // The players current health.
  90.     unsigned char   Unknown0037;
  91.     unsigned char   Unknown0038;
  92.     unsigned short  Unknown0039;
  93.     unsigned char   Unknown0040;            // Seems to deal with drawing your weapon.
  94.     unsigned char   PlayerConditionFlag;    // Virus, Poisoned, Fine, etc.
  95.     unsigned char   Unknown0041;
  96.     unsigned char   Unknown0042;
  97.     unsigned short  Unknown0043;
  98.     unsigned short  IdleCountdown;          // Timer until your animation is set to idle.
  99.     unsigned short  Unknown0044;
  100.     unsigned short  CollisionValue0004;     // Additional collision value when walking forward against objects.
  101.     unsigned short  CollisionValue0005;     // Additional collision value when walking down/up stairs.
  102.     unsigned short  CollisionValue0006;     // Additional collision value when walking forward against objects.
  103.     unsigned char   CollisionValue0007;     // Additional collision value when walking backward. (Perhaps animation data.)
  104.     unsigned char   CollisionValue0008;     // Additional collision value when walking backward. (Perhaps animation data.)
  105.     unsigned int    TimerValue0000;         // Some type of time that is used while moving.
  106.     unsigned int    UnknownPointer0000;     // Unknown pointer to an object.
  107.     unsigned int    UnknownPointer0001;     // Unknown pointer to an object.
  108.     unsigned int    UnknownPointer0002;     // Unknown pointer to an object.
  109.     unsigned int    UnknownPointer0003;     // Unknown pointer to an object.
  110.     unsigned int    Unknown0045;
  111.     unsigned int    Unknown0046;
  112.     unsigned int    UnknownPointer0004;     // Unknown pointer to an object.
  113.     unsigned int    UnknownPointer0005;     // Unknown pointer to an object.
  114.     unsigned int    UnknownPointer0006;     // Unknown pointer to an object.
  115.     unsigned int    Unknown0047;
  116.     unsigned int    PlayerPointer0001;      // Pointer to the start of this structure.
  117.     unsigned int    PlayerPointer0002;      // Pointer to the start of this structure.
  118.     unsigned int    Unknown0048;
  119.     unsigned int    UnknownPointer0007;     // Unknown pointer to an object.
  120.     unsigned char   Unknown0049;
  121.     unsigned char   Unknown0050;            // Seems to deal with animations when exiting menus.
  122.     unsigned short  ShadowDistance;         // The distance of the shadow from our player.
  123.     unsigned int    MovementStep;           // The movement adjusting time. Force to -1 to speed hack.
  124.     unsigned short  Unknown0051;
  125.     unsigned short  MapZOffset;             // Seems to be the offset of the map for where you can walk. (Z Coord)
  126.     unsigned char   Unknown0052;
  127.     unsigned char   InteractionCooldown;    // Timer to prevent interaction with objects.
  128.     unsigned char   Unknown0053;
  129.     unsigned char   Unknown0054;    
  130.     unsigned int    Unknown0055;
  131.     unsigned short  Unknown0056;            // Always set to 0x05DC
  132.     unsigned short  Unknown0057;            // Always set to 0xFC18
  133.     signed char     Unknown0060;            // Always set to 55
  134.     signed char     Unknown0061;            // Always set to -56
  135.     unsigned short  Unknown0062;
  136. };
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Resident Evil 3 Entity Structure

Post by atom0s » Fri Jan 09, 2015 9:46 am

Here is an example of reading the entity list of the game:
  1. /**
  2.  * Resident Evil 3 - Entity List Reader
  3.  * (c) 2014 atom0s [atom0s@live.com]
  4.  */
  5.  
  6. #include <Windows.h>
  7. #include <iostream>
  8. #include <TlHelp32.h>
  9.  
  10. /**
  11.  * @brief Game Executable Names
  12.  */
  13. const char g_GameNames[4][255] =
  14. {
  15.     { "Bio3_PC.exe" },              // JP MediaKite / SourceNext
  16.     { "Bio3_PC_Mercenaries.exe" },  // JP MediaKite Mercenaries
  17.     { "BIOHAZARD(R) 3 PC.exe" },    // SourceNext Original Name
  18.     { "ResidentEvil3.exe" }         // NA (Unknown specific version.)
  19. };
  20.  
  21. /**
  22.  * @brief Obtains the process id of Residen Evil 3.
  23.  * @returN The process id if found, 0 otherwise.
  24.  */
  25. DWORD getResidentEvilProcessId(void)
  26. {
  27.     PROCESSENTRY32 pe32{ sizeof(PROCESSENTRY32) };
  28.  
  29.     auto handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  30.     if (handle == INVALID_HANDLE_VALUE)
  31.         return 0;
  32.  
  33.     if (!::Process32First(handle, &pe32))
  34.     {
  35.         ::CloseHandle(handle);
  36.         return 0;
  37.     }
  38.  
  39.     do
  40.     {
  41.         for (auto x = 0; x < _countof(g_GameNames); x++)
  42.         {
  43.             if (_strnicmp(pe32.szExeFile, g_GameNames[x], strlen(g_GameNames[x])) == 0)
  44.             {
  45.                 ::CloseHandle(handle);
  46.                 return pe32.th32ProcessID;
  47.             }
  48.         }
  49.     } while (::Process32Next(handle, &pe32));
  50.  
  51.     ::CloseHandle(handle);
  52.     return 0;
  53. }
  54.  
  55. /**
  56.  * @brief Obtains the process base address of Residen Evil 3.
  57.  *
  58.  * @Param dwProcId  The process id to obtain the base address of.
  59.  * @returN The process base address if found, 0 otherwise.
  60.  */
  61. DWORD getResidentEvilProcessBase(DWORD dwProcId)
  62. {
  63.     MODULEENTRY32 me32{ sizeof(MODULEENTRY32) };
  64.  
  65.     auto handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcId);
  66.     if (handle == INVALID_HANDLE_VALUE)
  67.         return 0;
  68.  
  69.     if (!::Module32First(handle, &me32))
  70.     {
  71.         ::CloseHandle(handle);
  72.         return 0;
  73.     }
  74.  
  75.     ::CloseHandle(handle);
  76.     return (DWORD)me32.modBaseAddr;
  77. }
  78.  
  79. /**
  80.  * @brief Obtains the process base size of Residen Evil 3.
  81.  *
  82.  * @Param dwProcId  The process id to obtain the base address of.
  83.  * @returN The process base size if found, 0 otherwise.
  84.  */
  85. DWORD getResidentEvilProcessSize(DWORD dwProcId)
  86. {
  87.     MODULEENTRY32 me32{ sizeof(MODULEENTRY32) };
  88.  
  89.     auto handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcId);
  90.     if (handle == INVALID_HANDLE_VALUE)
  91.         return 0;
  92.  
  93.     if (!::Module32First(handle, &me32))
  94.     {
  95.         ::CloseHandle(handle);
  96.         return 0;
  97.     }
  98.  
  99.     ::CloseHandle(handle);
  100.     return me32.modBaseSize;
  101. }
  102.  
  103. /**
  104.  * @brief Compares the given memory data against the given pattern using the desired mask.
  105.  *
  106.  * @Param lpData            Pointer to the actual memory to be compared again.
  107.  * @Param lpPattern         Pointer to the pattern to scan the memory for.
  108.  * @Param pszMask           String containing the mask for the pattern being compared against.
  109.  *
  110.  * @returN True when the pattern is found, false otherwise.
  111.  */
  112. static bool __stdcall MaskCompare(const unsigned char* lpData, const unsigned char* lpPattern, const char* pszMask)
  113. {
  114.     for (; *pszMask; ++pszMask, ++lpData, ++lpPattern)
  115.         if (*pszMask == 'x' && *lpData != *lpPattern)
  116.             return false;
  117.     return (*pszMask) == NULL;
  118. }
  119.  
  120. /**
  121.  * @brief Locates the given pattern inside the given data.
  122.  *
  123.  * @Param lpData            The data to scan for our pattern within.
  124.  * @Param nDataSize         The size of the data block to scan within.
  125.  * @Param lpPattern         The pattern to compare the memory against.
  126.  * @Param pszMask           String containing the mask for the pattern being compared against.
  127.  *
  128.  * @returN Location of where the pattern was found, 0 otherwise.
  129.  */
  130. static DWORD __stdcall FindPattern(const unsigned char* lpData, unsigned int nDataSize, const unsigned char* lpPattern, const char* pszMask)
  131. {
  132.     for (unsigned int x = 0; x < nDataSize; x++)
  133.         if (MaskCompare(lpData + x, lpPattern, pszMask))
  134.             return (DWORD)(lpData + x);
  135.     return 0;
  136. }
  137.  
  138. /**
  139.  * @brief The main application entry point.
  140.  *
  141.  * @Param argc  The number of arguments passed to this program.
  142.  * @Param argv  The arguments passed to this program.
  143.  *
  144.  * @returN Error code on succss of application.
  145.  */
  146. int __cdecl main(int argc, char* argv[])
  147. {
  148.     std::cout << "===============================================" << std::endl;
  149.     std::cout << "Resident Evil 3 Entity List" << std::endl;
  150.     std::cout << "by atom0s (c) 2014 [atom0s@live.com]" << std::endl;
  151.     std::cout << "===============================================" << std::endl << std::endl;
  152.  
  153.     // Get the process id..
  154.     auto procId = getResidentEvilProcessId();
  155.     if (procId == 0)
  156.         return -1;
  157.     std::cout << "[*] Found game process!" << std::endl;
  158.  
  159.     // Get the process base address..
  160.     auto procBase = getResidentEvilProcessBase(procId);
  161.     if (procBase == 0)
  162.         return -1;
  163.     std::cout << "[*] Found game process base!" << std::endl;
  164.  
  165.     // Get the process base size..
  166.     auto procSize = getResidentEvilProcessSize(procId);
  167.     if (procSize == 0)
  168.         return -1;
  169.     std::cout << "[*] Obtained process base size!" << std::endl;
  170.  
  171.     // Open the process for reading..
  172.     auto handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, procId);
  173.     if (handle == INVALID_HANDLE_VALUE)
  174.         return -1;
  175.     std::cout << "[*] Obtained process handle for memory reading!" << std::endl;
  176.  
  177.     // Dump the process memory..
  178.     auto procDump = new unsigned char[procSize + 1];
  179.     ::ReadProcessMemory(handle, (LPCVOID)procBase, procDump, procSize, NULL);
  180.  
  181.     // Find the entity pointers..
  182.     auto entityPtr1 = FindPattern(procDump, procSize, (BYTE*)"\x51\x53\x55\x56\x57\xBE\xFF\xFF\xFF\xFF\xE8\xFF\xFF\xFF\xFF\xF7", "xxxxxx????x????x");
  183.     auto entityPtr2 = FindPattern(procDump, procSize, (BYTE*)"\x8B\x86\x0C\x27\x00\x00\x8D\xAE\x64\x26\x00\x00\x8B\xDD\x3B\xD8", "xxxxxxxxxxxxxxxx");
  184.     if (entityPtr1 == NULL || entityPtr2 == NULL)
  185.     {
  186.         ::CloseHandle(handle);
  187.         return -1;
  188.     }
  189.  
  190.     // Readjust the offsets..
  191.     entityPtr1 -= (DWORD)procDump;
  192.     entityPtr2 -= (DWORD)procDump;
  193.     std::cout << "[*] Found signatures for entity offsets!" << std::endl;
  194.  
  195.     // Read the entity pointer offsets..
  196.     auto entityOff1 = 0; // entityPtr + 2;
  197.     auto entityOff2 = 0; // entityPtr + 8;
  198.     ::ReadProcessMemory(handle, (LPCVOID)(procBase + entityPtr1 + 6), &entityPtr1, 4, NULL);
  199.     ::ReadProcessMemory(handle, (LPCVOID)(procBase + entityPtr2 + 2), &entityOff1, 4, NULL);
  200.     ::ReadProcessMemory(handle, (LPCVOID)(procBase + entityPtr2 + 8), &entityOff2, 4, NULL);
  201.  
  202.     // Ensure we found valid offsets..
  203.     if (entityPtr1 == NULL || entityOff1 == NULL || entityOff2 == NULL)
  204.     {
  205.         ::CloseHandle(handle);
  206.         return -1;
  207.     }
  208.  
  209.     std::cout << "[*] Read offsets for entity table boundries!" << std::endl;
  210.     std::cout << "[*] Reading current entity list.." << std::endl << std::endl;
  211.  
  212.     // Read the ending entry in the entity list..
  213.     auto entityEnd = 0;
  214.     ::ReadProcessMemory(handle, (LPCVOID)(entityPtr1 + entityOff1), &entityEnd, 4, NULL);
  215.     printf_s("End of entity list entry is: 0x%08X\n", entityEnd);
  216.  
  217.     // Loop until we want to escape..
  218.     while (true)
  219.     {
  220.         // Allow escape to leave the loop and close the app..
  221.         if ((::GetAsyncKeyState(VK_ESCAPE) & 1) && ::GetAsyncKeyState(VK_SHIFT))
  222.             break;
  223.  
  224.         // Read the current entry in the entity list..
  225.         auto entity = 0;
  226.         ::ReadProcessMemory(handle, (LPCVOID)(entityPtr1 + entityOff2), &entity, 4, NULL);
  227.         printf_s("Found entity: 0x%08X\n", entity);
  228.  
  229.         // Are we at the end of the list..
  230.         if (entity == entityEnd)
  231.             break;
  232.  
  233.         entityOff2 += 4;
  234.     }
  235.  
  236.     // Cleanup..
  237.     ::CloseHandle(handle);
  238.     return ERROR_SUCCESS;
  239. }
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest