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 


64 bit External AOB Scanner not getting everything in range

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

Joined: 16 Dec 2023
Posts: 3

PostPosted: Sat Dec 16, 2023 11:35 am    Post subject: 64 bit External AOB Scanner not getting everything in range Reply with quote

I tested a scan with Cheat Engine and this. The AOB I scanned with this returned 0 results in the range, while Cheat Engine returned 2. What did I do wrong here?

My range is basically where I believe the "heap" of the program is in memory. The range isn't the problem, I don't think.

Code:

bool MemoryCompare(const BYTE* bData, const BYTE* bMask, const char* szMask) {
   for (; *szMask; ++szMask, ++bData, ++bMask) {
      if (*szMask == 'x' && *bData != *bMask) {
         return false;
      }
   }
   return (*szMask == NULL);
}

DWORD64 FindPattern(DWORD64 dwAddress, DWORD64 dwLen, BYTE* bMask, const char* szMask, DWORD64 realaddress)
{
   for (int i = 0; i < (DWORD64)dwLen; i++)
      if (MemoryCompare((BYTE*)(dwAddress + (DWORD64)i), bMask, szMask))
         return (DWORD64)(realaddress + i);
   return 0;
}
struct Result {
   DWORD64 result;
   explicit Result(DWORD64 result) : result(result) {}
};
mutex mtx;
void ScanMemoryChunk(DWORD64 startAddress, DWORD64 endAddress, const char* content, const char* mask, std::vector<Result>& results)
{
   DWORD64 PageSize = 0x20000;
   if ((endAddress - startAddress) < PageSize) {
      PageSize = (endAddress - startAddress);
   }
   BYTE storage[0x20000];

   for (DWORD64 lpAddr = startAddress; lpAddr < endAddress; lpAddr += PageSize)
   {
      if (lpAddr > endAddress) {
         lpAddr = endAddress;
      }
      ReadProcessMemory(ProcessHandle, (LPCVOID)lpAddr, &storage, PageSize, NULL);

      DWORD64 addr = FindPattern((DWORD64)storage, PageSize, (PBYTE)content, mask, lpAddr);

      if (addr != 0)
      {
         std::lock_guard<std::mutex> lock(mtx);
         results.emplace_back(Result(addr));
      }
   }
}
vector<DWORD64> Scan(const char* content, const char* mask2 = "", int numThreads = 24)
{
   ResetHeapEnd();      
   const char* mask = mask2;
   if (!strcmp(mask2, "")) {
      string lol123 = "";
      for (int i = 0; i < strlen(content); i++) {
         lol123 += "x";
      }
      return Scan(content, lol123.c_str(), numThreads);
   }
   const DWORD64 startAddress = HeapBase;
   const DWORD64 endAddress = HeapEnd;
   const DWORD64 chunkSize = (endAddress - startAddress)/numThreads;

   vector<Result> results;
   vector<thread> threads;

   DWORD64 totalChunks = (endAddress - startAddress) / chunkSize;
   DWORD64 chunksPerThread = totalChunks / numThreads;

   numThreads = min(numThreads, totalChunks);

   for (int i = 0; i < numThreads; ++i)
   {
      DWORD64 threadStartAddress = startAddress + (i * chunksPerThread * chunkSize);
      DWORD64 threadEndAddress = threadStartAddress + (chunksPerThread * chunkSize);

      if (i == numThreads - 1)
      {
         threadEndAddress = endAddress;
      }

      threads.emplace_back(ScanMemoryChunk, threadStartAddress, threadEndAddress, content, mask, std::ref(results));
   }

   for (auto& thread : threads)
   {
      thread.join();
   }

   vector<DWORD64> hacks;
   for (const auto& result : results) {
      hacks.push_back(result.result);
   }

   return hacks;
}
[/code]
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25813
Location: The netherlands

PostPosted: Sat Dec 16, 2023 11:49 am    Post subject: Reply with quote

for not finding the result not sure, but I can tell you that MemoryCompare will cause issues as when you reach the end of the buffer it will end up comparing further than the allocated memory

don't bother with threads for now. Just do a single thread till you have a hang of your code

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
lightersmash
How do I cheat?
Reputation: 0

Joined: 16 Dec 2023
Posts: 3

PostPosted: Sat Dec 16, 2023 12:17 pm    Post subject: Reply with quote

I did some testing (turning it into a single thread scanner, and then just making it run the ScanMemoryChunk function on everything and it still is having the issue, so that means the problem in that, but I can't find the issue there. Help?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4709

PostPosted: Sat Dec 16, 2023 12:35 pm    Post subject: This post has 1 review(s) Reply with quote

I don't know what you think the heap is or how you think games allocate memory, but you're missing a lot. Sometimes values are spread out across multiple non-contiguous memory regions. The only way you can actually get all the results is if you scan through all the relevant memory. Find where the "relevant" memory is using VirtualQueryEx.

In `FindPattern`, make `i` a DWORD64 and not an int. There's a lot of useless casing going on. Also comparing a signed value against an unsigned value is weird for a number of reasons.

`DWORD64 PageSize = 0x20000;` One page of memory is 0x1000 (4096) bytes. It would be better if you renamed this to "ChunkSize" or something. The way it is now is like defining a variable named "second" to be 2 minutes or something; it's confusing.

lightersmash wrote:
Code:
for (DWORD64 lpAddr = startAddress; lpAddr < endAddress; lpAddr += PageSize)
{
   if (lpAddr > endAddress) {
      lpAddr = endAddress;
   }
   ReadProcessMemory(ProcessHandle, (LPCVOID)lpAddr, &storage, PageSize, NULL);
    ...
This is wrong. That `if` statement is useless- it'll never get executed since it's covered by the `for` loop condition.
RPM then reads past the end of valid memory. Hopefully Windows catches this and returns an error, but you'll never know since you're not doing any error handling.

If your code isn't working, the first thing you should do is check if there are errors. Compiler flags like `-Wall -Wextra -Wpedantic` are good, but the compiler isn't going to magically insert code that checks if an API call succeeded or not.

I didn't look at the rest of it.
See "Cheat Engine/memscan.pas" in CE's source for all the mess you have to go through to do this well.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
lightersmash
How do I cheat?
Reputation: 0

Joined: 16 Dec 2023
Posts: 3

PostPosted: Sat Dec 16, 2023 1:08 pm    Post subject: Reply with quote

Thanks for the help. It works now.
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 Gamehacking 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