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 


Search for text in process memory

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

Joined: 28 Mar 2011
Posts: 3

PostPosted: Mon Mar 28, 2011 10:04 pm    Post subject: Search for text in process memory Reply with quote

I need to find the adress of a unique string in the process, via cheat engine it's really easy but I need it in C++ form.

So this is where I stand at:

Code:

   int main()
   {
      DWORD procID;
      wchar_t *p = NULL;
      wchar_t test[] = L"Punkte";

      HWND foo = FindWindow(NULL, "Solitär");

      GetWindowThreadProcessId(foo, &procID);

      DWORD dwStart = 0;
      SIZE_T lpRead;
      SYSTEM_INFO si;
      HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
      GetSystemInfo(&si);

      MEMORY_BASIC_INFORMATION mbi;
      unsigned char* addr = (unsigned char*)si.lpMinimumApplicationAddress;

      while(1)
      {
            if(VirtualQueryEx(hProc, (void*)addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
            {
                break;
            }

         printf("Memory at %02x, size %d\n",   mbi.BaseAddress, mbi.RegionSize);

         addr = (unsigned char*)mbi.BaseAddress + mbi.RegionSize;
      }

      system("PAUSE");

      return 0;
   }


It just prints all the memory blocks of the game solitaire, I have a german version so keywords are in german, I wanted to find the locations of the text score in this process, but really have no clue how I search for the string within the memory blocks.

It doesn't work to simply read all those blocks with ProcessMemory as wchar_t arrays and then to look for the keyword sequence, infact none of the read meamory blocks with ReadProcessMemory even makes any sense.

Any indeas how to solve this?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Tue Mar 29, 2011 7:25 am    Post subject: Reply with quote

Some things to note:

You should not use PROCESS_ALL_ACCESS due to compatibility issues, instead specify the flags you need specifically.

VirtualQuery does not read memory, it simply gives you information regarding the pages.

You are mixing encoding types, which is generally bad practice. Either stick to one or the other, or use TCHAR with the appropriate function wrappers / macros.


As for your overall issue, you will need to use ReadProcessMemory to make dumps from the process and search within the dumps for your string.

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

Joined: 28 Mar 2011
Posts: 3

PostPosted: Tue Mar 29, 2011 8:01 am    Post subject: Reply with quote

I don't care about technicallities (correct flags) for now, but thx for pointing some of those things out.

I'm aware of how to read memory from the process, but how do I search in such a memory block for Unicode strings?

e.g. lets say I read one of those blocs like this:

Quote:

SIZE_T lpRead;
BYTE* mb = NULL;

mb = (BYTE*)malloc(mbi.RegionSize);

ReadProcessMemory( hProc, mbi.BaseAddress, mb, mbi.RegionSize, &lpRead);


But how do I convert Unicode to a BYTE pattern now and how do I search for it?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Tue Mar 29, 2011 11:23 am    Post subject: Reply with quote

Here is an extremely hacked together example I just wrote, I wouldn't recommend using it just like this though, add error checking, handle protection flags better, and so on:

Code:

#include <Windows.h>
#include <tchar.h>
#include <iostream>

int main( int argc, TCHAR* argv[] )
{
   // String to locate..
   TCHAR tszString[] = _T( "Anonymous" );

   HWND hWnd = FindWindow( NULL, _T( "Minesweeper" ) );
   if( hWnd == NULL ) return 0;

   DWORD dwProcId = 0;
   GetWindowThreadProcessId( hWnd, &dwProcId );
   if( dwProcId == 0 ) return 0;

   HANDLE hHandle = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, dwProcId );
   if( hHandle == INVALID_HANDLE_VALUE ) return 0;

   SYSTEM_INFO si = { 0 };
   GetSystemInfo( &si );

   MEMORY_BASIC_INFORMATION mbi = { 0 };

   LPVOID lpStartAddr = si.lpMinimumApplicationAddress;
   while( VirtualQueryEx( hHandle, lpStartAddr, &mbi, sizeof( MEMORY_BASIC_INFORMATION ) ) )
   {
      _tprintf( _T( "Region: 0x%08X - Size: %d\r\n" ), mbi.BaseAddress, mbi.RegionSize );

      if( ( mbi.Protect & PAGE_EXECUTE_READ ) || ( mbi.Protect & PAGE_EXECUTE_READWRITE ) ||
         ( mbi.Protect & PAGE_READONLY ) || ( mbi.Protect & PAGE_READWRITE ) )
      {
         TCHAR* btDump = new TCHAR[ mbi.RegionSize + 1 ];
         ReadProcessMemory( hHandle, mbi.BaseAddress, btDump, mbi.RegionSize, NULL );

         for( DWORD x = 0; x < mbi.RegionSize; x++ )
            if( wmemcmp( &btDump[ x ], tszString, _tcslen( tszString ) ) == 0 )
            {
               _tprintf( _T( " --> Found string at: 0x%08X\r\n" ), reinterpret_cast< LPVOID >( reinterpret_cast< DWORD_PTR >( mbi.BaseAddress ) + ( x * sizeof( TCHAR ) ) ) );
            }

         delete btDump;
      }

      lpStartAddr = reinterpret_cast< LPVOID >( reinterpret_cast< DWORD_PTR >( mbi.BaseAddress ) + mbi.RegionSize );
   }

   CloseHandle( hHandle );

   return 0;
}


Change wmemcmp to memcmp if you don't want to use unicode as well.

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

Joined: 28 Mar 2011
Posts: 3

PostPosted: Tue Mar 29, 2011 12:57 pm    Post subject: Reply with quote

Thx a lot, came up with a slow solution of my own, this is much faster Smile
It works perfectly for ascii strings with memcmp, but it doesn't compile with wmemcmp, it has some problems with conversion routines it seems:

Code:

error C2664: 'wmemcmp' : cannot convert parameter 1 from 'TCHAR *' to 'const wchar_t *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


Could recode it to work with unicode, but maybe you know a simpler solution, like recasting in a correct manner?

Thx a lot for your time, you helped me out a lot!

EDIT:

So this is the unicode version, in case someone looks this up in the future:

Code:

      for( DWORD x = 0; x < mbi.RegionSize; x++ )
      {
         const wchar_t *p1 = reinterpret_cast< const wchar_t * >(&btDump[ x ]);
         const wchar_t *p2 = reinterpret_cast< const wchar_t * >(tszString);

         if( wmemcmp( p1, p2, wcslen( tszString ) ) == 0 )
         {
            wprintf( L" --> Found string at: 0x%08X\r\n", reinterpret_cast< LPVOID >( reinterpret_cast< DWORD_PTR >( mbi.BaseAddress ) + ( x * sizeof( wchar_t) ) ) );
         }
      }
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Tue Mar 29, 2011 3:13 pm    Post subject: Reply with quote

Just set the character set to Unicode and it will compile fine.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
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