Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


C++ Classes/Examples of Reading Structs/Classes/Types etc

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
theidiot
Newbie cheater
Reputation: 0

Joined: 15 Dec 2015
Posts: 14

PostPosted: Wed Dec 28, 2016 3:30 am    Post subject: C++ Classes/Examples of Reading Structs/Classes/Types etc Reply with quote

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
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8517
Location: 127.0.0.1

PostPosted: Wed Dec 28, 2016 3:22 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
theidiot
Newbie cheater
Reputation: 0

Joined: 15 Dec 2015
Posts: 14

PostPosted: Mon Jan 09, 2017 7:34 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites