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 


Speed issues
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Wed May 11, 2011 9:58 pm    Post subject: Speed issues Reply with quote

Hey guys...

I was adding an unknown inital value scan to my memory engine. I finished and everything went well. The way the scan works is that in the first scan, it lists down every readable address. In the next scan it looks for values that have changed. I read/write to files in order to check addresses. It works fine on any application. However, the beginning scan (the scan that lists down every readable address) is really slow when it comes to reading large applications such as games and the scan creates large files (on some occasions over 5 GB). It slows down the whole process. I don't really have a problem with the large files, I just have a problem with the speed of the scans.

I need help guys, what can I do to speed up the writing or what can I change to make the scan faster to become more effective?

Thank you

Code:

template <class T> void beginScan  ( HWND hWndDlg )
   {
      results = 0;

      bool Fast = ( SMX ( GetDlgItem (hWndDlg, IDC_CHECKBOX1), BM_GETCHECK, 0, 0) == BST_CHECKED ) ? true : false;

      pChangeScan = 0;
      changeScan  = 0;

      ofstream File ( "C:\\UIV.fs" );
      File.clear ();

      char startAddrBuf [ 256 ], endAddrBuf [ 256 ] = { 0 };

      GetWindowTextA ( GetDlgItem ( hWndDlg, IDC_EDIT2 ), (LPSTR) startAddrBuf, 256 );
      GetWindowTextA ( GetDlgItem ( hWndDlg, IDC_EDIT3 ), (LPSTR) endAddrBuf,   256 );

      LPVOID lpBeginAddr, lpEndAddr;
      DWORD  dwBeginAddr, dwEndAddr;

      stringstream ss1, ss2;

      ss1 << startAddrBuf;
      ss2 << endAddrBuf;

      ss1 >> lpBeginAddr;
      ss2 >> lpEndAddr;

      dwBeginAddr = (DWORD) lpBeginAddr;
      dwEndAddr   = (DWORD) lpEndAddr;

      for ( DWORD i = dwBeginAddr;
               i < dwEndAddr;
               i ++ )
      {
         MEMORY_BASIC_INFORMATION MBI;
         VirtualQuery ( (LPCVOID) i, &MBI, sizeof ( MEMORY_BASIC_INFORMATION ) );
         
         if ( Fast )
         {
            if ( MBI.State == MEM_COMMIT && MBI.Type == MEM_PRIVATE )
            {
               DWORD dwEnd = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize - 1 - sizeof ( T );

               for ( DWORD a = (DWORD) MBI.BaseAddress;
                        a < dwEnd;
                        a ++ )
               {

                  File << a << " " << readAddr <T> ( a ) << endl;

                  ++results;
               }
            }
         }
         else
         {
            if ( MBI.Protect == PAGE_READWRITE )
            {
               DWORD dwEnd = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize - 1 - sizeof ( T );

               for ( DWORD a = (DWORD) MBI.BaseAddress;
                        a < dwEnd;
                        a ++ )
               {

                  File << a << " " << readAddr <T> ( a ) << endl;

                  ++results;
               }
            }
         }

         i = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize;
      }

      File.close ();

      setResults ( uivDlg );
   }
Back to top
View user's profile Send private message MSN Messenger
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Thu May 12, 2011 1:13 am    Post subject: Reply with quote

I'm not sure, but why are you doing this?

Code:
for ( DWORD a = (DWORD) MBI.BaseAddress;
                        a < dwEnd;
                        a ++ )
               {


You don't have to check that. All those addresses exists.

EDIT: Creating 5 gb files takes also a long time, if you care or not about them, you've to find a better soltion

instead of: 0040000-00400001.... 00400F00
this: 0040000-00400F00
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Thu May 12, 2011 6:38 am    Post subject: Reply with quote

Yeah man I was thinking about that peice of code last night. I need to obtain every address with its value, and then check that address and its value on the next scan. If I copy, the whole region down how will I be able to have a list of the addresses with their values to know if they changed or not?

You're right I do need to change the method, but I can't think of a better way to do a UIV scan... Any ideas?
Back to top
View user's profile Send private message MSN Messenger
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Thu May 12, 2011 3:43 pm    Post subject: Reply with quote

write to disk after you're done, don't play with IO in the middle of a critical loop
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Thu May 12, 2011 9:27 pm    Post subject: Reply with quote

So how can I record my results, in an array? On some occasions the amount of information being stored into the buffer would be too big for even the array to hold.

Should I convert the output into string form, then add it into a string buffer, and after the scan write it to a disc file?

Code:

int i;

string buffer []  = { 0 };

if ( ... )
{
   buffer [ i ] = convertToString ( ... );
   ++ i;   
}


thanks for the help man
Back to top
View user's profile Send private message MSN Messenger
HomerSexual
Grandmaster Cheater Supreme
Reputation: 5

Joined: 03 Feb 2007
Posts: 1657

PostPosted: Thu May 12, 2011 9:37 pm    Post subject: Reply with quote

iPromise wrote:
So how can I record my results, in an array? On some occasions the amount of information being stored into the buffer would be too big for even the array to hold.

Should I convert the output into string form, then add it into a string buffer, and after the scan write it to a disc file?

Code:

int i;

string buffer []  = { 0 };

if ( ... )
{
   buffer [ i ] = convertToString ( ... );
   ++ i;   
}


thanks for the help man


What about writing every so many bytes. This way you could store information until it became impractical to store more, write that to file, then rewrite the buffer. This way you minimize writes.

_________________
Back to top
View user's profile Send private message
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Thu May 12, 2011 11:39 pm    Post subject: Reply with quote

Why would you convert it to a string array?
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Fri May 13, 2011 10:29 am    Post subject: Reply with quote

NoMercy; See I output my information to the file where it becomes a string. This is what the output is:

Code:

00400000 1


It lists the address, then the value followed by a space. So I think converting that to a string, then adding it to an array would be benefitial. Or I can just add two different arrays, one holding the DWORD value of the address, and the other holding the value of the address. I see the string way the fastest way I guess...

HomerSexual; Hold up, so is this what you're telling me? Write all the information in the array to the disc file, then clear the array and reuse it again to prevent having an array to huge?
Back to top
View user's profile Send private message MSN Messenger
NoMercy
Master Cheater
Reputation: 1

Joined: 09 Feb 2009
Posts: 289

PostPosted: Fri May 13, 2011 10:34 am    Post subject: Reply with quote

I do not think that to a string it becomes faster, anways you should read large chunks of memory and write that to the file isntead of writing every address a time.
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Fri May 13, 2011 10:47 am    Post subject: Reply with quote

I see, so something like this?

Code:

BYTE * Buffer;
Buffer = new BYTE [ MBI.RegionSize ];
memcpy ( (void*) Buffer, (void*) MBI.BaseAddress, MBI.RegionSize );

File << Buffer << endl;
Back to top
View user's profile Send private message MSN Messenger
HomerSexual
Grandmaster Cheater Supreme
Reputation: 5

Joined: 03 Feb 2007
Posts: 1657

PostPosted: Fri May 13, 2011 1:20 pm    Post subject: Reply with quote

iPromise wrote:
NoMercy; See I output my information to the file where it becomes a string. This is what the output is:

Code:

00400000 1


It lists the address, then the value followed by a space. So I think converting that to a string, then adding it to an array would be benefitial. Or I can just add two different arrays, one holding the DWORD value of the address, and the other holding the value of the address. I see the string way the fastest way I guess...

HomerSexual; Hold up, so is this what you're telling me? Write all the information in the array to the disc file, then clear the array and reuse it again to prevent having an array to huge?


Yes, does that sound like it would work? It would minimize writing to the disc and would prevent the array from taking too much memory.

_________________
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Sun May 15, 2011 1:44 am    Post subject: Reply with quote

@HomerSexual

It made no difference when I tested it man..

@NoMercy

I'm multithreading now, creating 15 threads to handle the UIV scan. The process is faster but in general its still slow -.-

I tried reading the whole region with memcpy, but then i'll have to write each address with its value which still takes some time..

Code:

template <class T> void beginScan  ( DWORD dwBeginAddr, DWORD dwEndAddr, string FileName )
   {
      results = 0;
      bool Fast = ( SMX ( GetDlgItem (hWndMain2, IDC_CHECKBOX1), BM_GETCHECK, 0, 0) == BST_CHECKED ) ? true : false;

      ofstream File ( FileName.c_str () );
      File.clear ();

      for ( DWORD i = dwBeginAddr;
               i < dwEndAddr;
               i ++ )
      {
         MEMORY_BASIC_INFORMATION MBI;
         VirtualQuery ( (LPCVOID) i, &MBI, sizeof ( MEMORY_BASIC_INFORMATION ) );
         
         if ( Fast )
         {
            if ( MBI.State == MEM_COMMIT && MBI.Type == MEM_PRIVATE )
            {
               DWORD dwEnd = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize - 1 - sizeof ( T );

               for ( DWORD a = (DWORD) MBI.BaseAddress;
                        a < dwEnd;
                        a ++ )
               {
                  bool check = false;

                  if ( sizeof (T) == sizeof ( BYTE ) ) {
                     File << a << " " << (unsigned int) readAddr2 <T> ( &check, a ) << endl;
                  }
                  else {
                     File << a << " " << readAddr2 <T> ( &check, a ) << endl;
                  }

                  ++results;

                  if ( check == true )
                     a = dwEnd;
               }
            }
         }
         else
         {
            if ( MBI.Protect == PAGE_READWRITE )
            {
               DWORD dwEnd = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize - 1 - sizeof ( T );

               for ( DWORD a = (DWORD) MBI.BaseAddress;
                        a < dwEnd;
                        a ++ )
               {
                  bool check = false;

                  if ( sizeof (T) == sizeof ( BYTE ) )
                  {
                     File << a << " " << (unsigned int) readAddr2 <T> ( &check, a ) << endl;
                  }
                  else
                  {
                     File << a << " " << readAddr2 <T> ( &check, a ) << endl;
                  }

                  ++results;

                  if ( check == true )
                     a = dwEnd;
               }
            }
         }

         i = (DWORD) MBI.BaseAddress + (DWORD) MBI.RegionSize;
      }

      File.close ();
      setResults ( uivDlg );
   }
Back to top
View user's profile Send private message MSN Messenger
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Sun May 15, 2011 1:58 am    Post subject: Reply with quote

15???

whyyyyy
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Sun May 15, 2011 3:45 am    Post subject: Reply with quote

Code:
bool Fast = ( SMX ( GetDlgItem (hWndMain2, IDC_CHECKBOX1), BM_GETCHECK, 0, 0) == BST_CHECKED ) ? true : false;


i corrected you like a billion times that this doesn't require the conditional assignment.. and what's with the mixup of hungarian notation and lack of it.

look at the CE source and see how it does it. you will find it does a similar technique but not with a single buffer
Back to top
View user's profile Send private message
HomerSexual
Grandmaster Cheater Supreme
Reputation: 5

Joined: 03 Feb 2007
Posts: 1657

PostPosted: Sun May 15, 2011 8:42 am    Post subject: Reply with quote

iPromise wrote:
@HomerSexual

It made no difference when I tested it man..



Then that wasn't the bottleneck. But you should still probably do it as minimizing file system calls is always good practice.

_________________
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
Goto page 1, 2  Next
Page 1 of 2

 
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