 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
theidiot Newbie cheater
Reputation: 0
Joined: 15 Dec 2015 Posts: 14
|
Posted: Wed Dec 28, 2016 3:30 am Post subject: C++ Classes/Examples of Reading Structs/Classes/Types etc |
|
|
There anything out there that you think might prove useful in reading memory for types/lists/vectors/structs or whatever.. anything to make the code more manageable, able and efficient? I'm working on an entities list and am a bit of a novice but I've progressed. I still am not sure how I'd identify the list. Each entity has the same amount of data in it's block including userid, coordinates, direction, what seems to be codes for sprites though I'm not sure etc.
It's been interesting so far. I've got to say the free C++ Builder Starter promotion has got me doing things. |
|
| Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Wed Dec 28, 2016 3:22 pm Post subject: |
|
|
Things like lists/vectors are based on the implementation they are done in. In Microsoft C++ for example, the types for things like std::list or std::vector change between each iteration of the runtime, so you will need to pinpoint what is being used and wrap based on that.
Just implement the type in a similar manner that it would be if you wrote the code. Debug and dissect the data to determine how its implemented in memory then translate that back to how you feel it would be written in C++. From that you can cast the data to a pointer of your own implementation and walk the data as needed.
Things also change if you are injected or not. Reading data externally will have more limitations on how easily you can walk the data and what kind of extra code/checks you will need.
For example, this is an implementation I made to walk Grim Dawns object list externally. This was a double-linked list where the last object would wrap back around and link to the first in the list:
| Code: |
int __cdecl main(int, char*[])
{
auto memory = new Memory;
if (memory->Attach("Grim Dawn.exe"))
{
memory->AddPattern("Game.dll", "gameengine", "A1????????568BB080000000FF15????????508BCEE8????????5EC3", 1, 0);
memory->AddPattern("Engine.dll", "objectmanager", "08894604C746080000000050FF15????????C745FCFFFFFFFF8935????????A1????????85C075??FF7604????????????833D????????0075??68", 0x20, 0);
memory->CollectPatterns();
auto getPlayerPointer = [&memory]() -> unsigned
{
// Obtain the needed game objects..
auto gameEngine = memory->Read<int>(memory->GetPattern("gameengine"));
auto objectManager = memory->Read<int>(memory->GetPattern("objectmanager"));
if (gameEngine == 0 || objectManager == 0)
return 0;
// Obtain the player index..
auto index_ptr1 = memory->Read<int>(gameEngine);
auto index_ptr2 = memory->Read<int>(index_ptr1 + 0x16B0);
auto index_ptr3 = memory->Read<int>(index_ptr2 + 0x10);
auto playerIndex = memory->Read<int>(index_ptr3 + 0x08);
// Obtain the object manager mask..
auto mask_ptr1 = memory->Read<int>(objectManager);
auto objectMask = memory->Read<int>((mask_ptr1 + 0x20) + 0x18);
// Calculate the player object index..
auto part1 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x08);
part1 = part1 ^ 0x811C9DC5;
part1 = part1 * 0x01000193;
auto part2 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x09);
part2 = part2 ^ part1;
part2 = part2 * 0x01000193;
auto part3 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x0A);
part3 = part3 ^ part2;
part3 = part3 * 0x01000193;
auto part4 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x0B);
part4 = part4 ^ part3;
part4 = part4 * 0x01000193;
part4 = part4 & objectMask;
auto object_ptr1 = memory->Read<int>((mask_ptr1 + 0x20) + 0x0C);
auto object_ptr2 = memory->Read<int>(object_ptr1 + part4 * 8);
auto first_object = object_ptr2;
while (true)
{
auto current_index = memory->Read<int>(object_ptr2 + 0x08);
if (current_index == playerIndex)
{
return memory->Read<int>(object_ptr2 + 0x0C);
}
else
{
object_ptr2 = memory->Read<int>(object_ptr2);
if (object_ptr2 == 0 || object_ptr2 == first_object)
return 0;
}
}
return 0;
};
auto player = getPlayerPointer();
printf_s("Current Pointer: %08X\r\n", player);
if (player)
{
printf_s("Current position: %f - %f - %f\r\n",
memory->Read<float>(player + 0xA0),
memory->Read<float>(player + 0xA4),
memory->Read<float>(player + 0xA8)
);
}
}
delete memory;
return 0;
}
|
Another implementation would be, for example the online game Final Fantasy XI. The entities in that game are stored in a static array like this:
| Code: | | Entity_t* Entities[4096]; |
With this, you could read this array like this:
| Code: | for (auto x =0; x < 4096; x++)
{
// Each pointer is 4 bytes (32bit) so we walk the table of pointers
// using 4 as the alignment and x as the offset.
auto entity = (Entity_t*)(entitiesptr + (x * 4));
if (entity == nullptr)
continue;
// Do something with the entities here..
} |
_________________
- Retired. |
|
| Back to top |
|
 |
theidiot Newbie cheater
Reputation: 0
Joined: 15 Dec 2015 Posts: 14
|
Posted: Mon Jan 09, 2017 7:34 pm Post subject: |
|
|
| I appreciate the reply. The first list you spoke about is very similar to what i am dealing with and i worked it out inna similar way to what you seem to have done, i wonder if there are any adjecent addresses to the pointers that will tell me the size of each indexed portion. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|