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++ implementation of aobscan in own programs?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Discussions
View previous topic :: View next topic  
Author Message
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Sun Apr 12, 2015 10:29 am    Post subject: C++ implementation of aobscan in own programs? Reply with quote

Hi there,

I am new here and did some successfully pointer search. I can open the process and read the values. However each new patch of a game will have new pointers. After a short search I found that many developer have a special rescan algorithm. For example the TocaEdit team (or is it only one) do use a function called futurescan which seems to search for a key in the memory as orientation.
A google search for futurescan and the only found code snippet for the game "sleeping dogs":

Code:
//hook all camera
char camkey[] = { 0x8B , 0x01 , 0x8B , 0x50 , 0x3C , 0xFF , 0xD2 , 0x8B , 0xC8 , 0x85 , 0xC9 , 0x0F , 0x84 , 0xE8 , 0x00 , 0x00 , 0x00 , 0x0F , 0xB7 , 0x41 , 0x28 , 0x8B , 0xD0 , 0xC1 , 0xEA , 0x0E , 0xF6 , 0xC2 , 0x01 , 0x74 , 0x0B , 0x8B , 0x41 , 0x3C , 0x8B , 0x80 , 0x58 , 0x01 , 0x00 , 0x00 , 0xEB , 0x4E};
   
HookAddress = FutureScan(camkey, sizeof(camkey));
   if(HookAddress){
      HookAddress = GetLong(HookAddress-sizeof(camkey)-4);
   }


So my question is: Is this a common method or is there something similar from the cheatengine developer in this forum?
How does this work and why it can be so fast?

regards,
nonags


Last edited by nonags on Sun Apr 12, 2015 1:52 pm; edited 1 time in total
Back to top
View user's profile Send private message
vng21092
Grandmaster Cheater
Reputation: 15

Joined: 05 Apr 2013
Posts: 644

PostPosted: Sun Apr 12, 2015 11:19 am    Post subject: Reply with quote

http://forum.cheatengine.org/viewtopic.php?t=561407, read read read Wink
Back to top
View user's profile Send private message
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Sun Apr 12, 2015 12:01 pm    Post subject: Reply with quote

First thanks for the direction, very helpfully because there is much stuff and I do not know special CE functions like this aobscan.
Ok, as far I did read (please correct me) this is a tutorial to change a CE script to a aobscan script. This script will make CE able to find the pointers again and with the patern also in new games (if this part did not change).
Aobscan is not directly explained

Then my next question would be, howto get this into C++ and use in my own programs? Is there a API or library to use a CE script in a Tool or do I have to dig the CE code and copy aobscan out of it?
Back to top
View user's profile Send private message
vng21092
Grandmaster Cheater
Reputation: 15

Joined: 05 Apr 2013
Posts: 644

PostPosted: Sun Apr 12, 2015 12:58 pm    Post subject: Reply with quote

well, it doesn't really find pointers per se. AOB scan finds the instruction that writes to the value in question. So, a specific instruction will write to health while others will modify other things, like ammo or w.e. Point is, if you have the instruction that writes to your value, whats the point in looking for pointers? You can modify said instruction to do your bidding. Pointers aren't consistent as you've stated, but AOB scans have a pretty high chance of sticking around through patches. As far as the C++ stuff goes, I've got no clue Sad .

I really suck at explaining things so uhh, lets have a visualization. You have a friend named... Billy, Billy has a wallet holding your money. Billy is that instruction, HE handles your wallet. When you look for a pointer, its almost as if you're looking for the wallet, now it's hard finding the wallet because you have no clue where the fuck Billy put it. BUT, you know Billy always has the wallet, so you can tell Billy to do the work for you, and you won't have to care where the wallet is... cause you have Billy. Hope you get that?
Back to top
View user's profile Send private message
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Sun Apr 12, 2015 1:52 pm    Post subject: Reply with quote

So it seems to be a more complex scan than only searching a pattern in the memory. I though so because of the camkey in above example.
However I need this in a C++ solution so I change the topic a little bit to be more concret.
I have to find and read this aobscan to get more into it.
If I start a program I can hook this and search after startup. However there is no game started and the above futurescan will trigger often to find the values (shown in logfiles). Lets say I start the game an I am in the menu, there is no live count or health count. After I choose start there maybe, but I do not trigger again the aobscan.
How often I must start the aobscan?
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sun Apr 12, 2015 2:03 pm    Post subject: Reply with quote

Another reason why hacking into the game code to find an address is better.
You don't have to worry about all of the preconditions like waiting for the person to load up their character.
The game won't execute the code until it's supposed to and once it does, you now have the address.

Sorry, I don't have any sample code for doing this without CE. Smile

In your case, I would not set the address scan on a timer or even on load.
Setup every one of your scripts to execute an initialization routine.
When the user attempts to enable something, that is when you run the initialization to find the address.
If it finds the address, cache it. Otherwise, the initialization routine will run again next time they enable a script.
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: Sun Apr 12, 2015 2:44 pm    Post subject: Reply with quote

There are various ways you can accomplish AoB scanning in C/C++

The original common method of doing it is like this:
Code:
bool Compare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
    for (; *szMask; ++szMask, ++pData, ++bMask)
        if (*szMask == 'x' && *pData != *bMask)   return 0;
    return (*szMask) == NULL;
}
DWORD Pattern(DWORD dwAddress, DWORD dwLen, BYTE *bMask, char * szMask)
{
    for (DWORD i = 0; i < dwLen; i++)
        if (Compare((BYTE*)(dwAddress + i), bMask, szMask))  return (DWORD)(dwAddress + i);
    return 0;
}


Here is my method I wrote and use personally for my projects:
Code:
/**
 * @brief Scans a given chunk of data for the given pattern and mask.
 *
 * @param data          The data to scan within for the given pattern.
 * @param baseAddress   The base address of where the scan data is from.
 * @param lpPattern     The pattern to scan for.
 * @param pszMask       The mask to compare against for wildcards.
 * @param offset        The offset to add to the pointer.
 * @param resultUsage   The result offset to use when locating signatures that match multiple functions.
 *
 * @return Pointer of the pattern found, 0 otherwise.
 */
static intptr_t FindPattern(std::vector<unsigned char> data, intptr_t baseAddress, const unsigned char* lpPattern, const char* pszMask, intptr_t offset, intptr_t resultUsage)
{
    // Build vectored pattern..
    std::vector<std::pair<unsigned char, bool>> pattern;
    for (size_t x = 0, y = strlen(pszMask); x < y; x++)
        pattern.push_back(std::make_pair(lpPattern[x], pszMask[x] == 'x'));
 
    auto scanStart = data.begin();
    auto resultCnt = 0;
 
    while (true)
    {
        // Search for the pattern..
        auto ret = std::search(scanStart, data.end(), pattern.begin(), pattern.end(),
            [&](unsigned char curr, std::pair<unsigned char, bool> currPattern)
        {
            return (!currPattern.second) || curr == currPattern.first;
        });
 
        // Did we find a match..
        if (ret != data.end())
        {
            // If we hit the usage count, return the result..
            if (resultCnt == resultUsage || resultUsage == 0)
                return (std::distance(data.begin(), ret) + baseAddress) + offset;
 
            // Increment the found count and scan again..
            ++resultCnt;
            scanStart = ++ret;
        }
        else
            break;
    }
 
    return 0;
}


This requires some newer C++11 features so you will need a more modern compiler. You can couple this with std::async and std::futures to create an async pattern scanner that is extremely fast if you need to scan for large amounts of patterns at once as well.

Adjust accordingly to your needs based on if you are injected or external etc.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Sun Apr 12, 2015 2:55 pm    Post subject: Reply with quote

Thank you for the stuff. std::search seems for me very slow. Do you think they only search the lower memory addresses to find ingame values? I have no glue how long it may take but the futurescan is around 1 second to find the base offset.

Quote:
When the user attempts to enable something, that is when you run the initialization to find the address.

You talk about ingame actions or actions done in a cheat tool?
In my case it is only a monitor of some values, the user do nothing and do not manipulate something.
Same in above sample. TocaEdit use version.dll for injection proxy. How they find the right trigger for the futurescan?
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: Sun Apr 12, 2015 3:22 pm    Post subject: Reply with quote

The more modern FindPattern I showed above works flawlessly for me. In one of my projects I search for about 30-40 patterns at once using it. The entire clump of scans all finish in under 1 second using std::async/std::future.

On smaller scale scans like 1-5 patterns only, the std::search method may perform slower than the first FindPattern (or other iterations of it). It is more beneficial when scanning for a large sum of objects rather then just a few.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Sun Apr 12, 2015 4:05 pm    Post subject: Reply with quote

Ok, to collect all the informations:
1. scan with CE for value in memory, i.e. health
2. let CE search for which code in memory writes to this address
3. take a bigger memory pattern of the code around the writing code
4. check if this pattern is unique in runing game, else make bigger pattern
5. make sure this code pattern exist from original game and the one with a game patch

In the monitor tool you may open the process or make a hook injection to directly access the memory.
Then you search the whole memory for the found pattern. Perhaps you only search the first 10 Megabyte of the virtual 4GB memory.

is this correct?
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: Sun Apr 12, 2015 10:36 pm    Post subject: Reply with quote

Yes, pretty much correct. Always a good thing to ensure your pattern exists between two different files if that is what you are aiming for, which is the point of using AoB's.

As for memory searching, you can determine what exactly you should be scanning within based on where the pattern is located.

For example, if your pattern resides inside of the main executables code itself, you only need to scan within that executable's memory. If your pattern resides inside of a module, such as like 'Game.dll' then you only need to search inside of that modules memory. However in some cases the pattern you search for may be allocated at runtime causing the memory to be dynamic so you may need to scan each region of the memory the game currently has allocated to locate what you need.

All depends on the game though.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
nonags
How do I cheat?
Reputation: 0

Joined: 12 Apr 2015
Posts: 8

PostPosted: Mon Apr 13, 2015 3:05 am    Post subject: Reply with quote

Hi, i am with you.
Here is a question about the pattern. I must think about dynamic runtime game code which exists after the level is started. (I come back to the scan trigger later) As far I see here it is called multilevel pointer, if you go the non aobscan (patchsave) method.

Ok, now I search with cheat engine for the value and the writing code. I have this area and the code is always the same EXEPT the dynamic values where the value is written to. Then I need a pattern with holes. Code yes, dynamic memory addresses no. So the pattern looks like 30 01 45 01 84 04 78, first value is code, next is step to next pattern byte, next is code etc.

Is there a pattern search algorithm in CE to generate such a pattern (I have looked for but did not find so far anything that sounds like this)? Or is this my part?
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 126

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Mon Apr 13, 2015 6:34 pm    Post subject: Reply with quote

You can change the Value Type to Array of byte and search for: 30 01 45 01 84 04 78
If this AOB is an instruction, make sure you change the Writable checkbox to scan all memory.

You can create an AA script in CE to that address using:
Code:
aobscan(myaob,game.exe,30 01 45 01 84 04 78)
registersymbol(myaob)


It might be helpful if you post the instructions at those bytes, if they are in fact instructions.

I just want to make sure we're on the same page about what you're trying to do.
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 Discussions 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