|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Sun Apr 12, 2015 10:29 am Post subject: C++ implementation of aobscan in own programs? |
|
|
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 |
|
|
vng21092 Grandmaster Cheater Reputation: 15
Joined: 05 Apr 2013 Posts: 644
|
|
Back to top |
|
|
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Sun Apr 12, 2015 12:01 pm Post subject: |
|
|
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 |
|
|
vng21092 Grandmaster Cheater Reputation: 15
Joined: 05 Apr 2013 Posts: 644
|
Posted: Sun Apr 12, 2015 12:58 pm Post subject: |
|
|
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 .
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 |
|
|
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Sun Apr 12, 2015 1:52 pm Post subject: |
|
|
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 |
|
|
Zanzer I post too much Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Sun Apr 12, 2015 2:03 pm Post subject: |
|
|
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.
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 |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Sun Apr 12, 2015 2:44 pm Post subject: |
|
|
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 |
|
|
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Sun Apr 12, 2015 2:55 pm Post subject: |
|
|
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 |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Sun Apr 12, 2015 3:22 pm Post subject: |
|
|
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 |
|
|
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Sun Apr 12, 2015 4:05 pm Post subject: |
|
|
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 |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Sun Apr 12, 2015 10:36 pm Post subject: |
|
|
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 |
|
|
nonags How do I cheat? Reputation: 0
Joined: 12 Apr 2015 Posts: 8
|
Posted: Mon Apr 13, 2015 3:05 am Post subject: |
|
|
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 |
|
|
Zanzer I post too much Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Apr 13, 2015 6:34 pm Post subject: |
|
|
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 |
|
|
|
|
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
|
|