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++] Help.
Goto page 1, 2, 3  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: Fri Dec 25, 2009 1:58 pm    Post subject: [C++] Help. Reply with quote

2 Questions.

My first question is can I find the base address of the process i'm injected to by using VirtualQuery() with MEMORY_BASIC_INFORMATION?

Like so:

Code:

MEMORY_BASIC_INFORMATION MBI;
VirtualQuery(0, &MBI, sizeof(MBI));

return MBI.BaseAddress;


My second question is on my previous thread, I asked a faster method to scan through addresses, see what I usually do is:

Code:

DWORD Start = 0x00400000;
DWORD Stop = 0x04FFFFFF;            

do
{
bool Read = ReadByte(Start, Value);

 if (Read == true)
 {                     
 SendMessageX(ListBox1, LB_ADDSTRING, 0, (LPARAM) ConvertAddress((LPVOID) Start).c_str());                     
 }
                  

++Start;

} while (Start <= Stop);




Dark Byte and other members suggested I use VirtualQuery() to scan faster, but I dont see how it could scan faster by using it.

If you really do need VirtualQuery() to scan through the regions, etc, to find the allocated addresses, can you give an example code and show me how to do it?


P.S. I am finished my Memory Engine, but its slow in scanning, so i'm trying to find a faster method to scan through the addresses. To anyone that helps, get a free copy of it, its semi - private so theres a less chance of it getting detected, I just tested it on the game: GunBound and it works but again, slow.

Thanks

Some pictures for proof:

Back to top
View user's profile Send private message MSN Messenger
lurc
Grandmaster Cheater Supreme
Reputation: 2

Joined: 13 Nov 2006
Posts: 1900

PostPosted: Fri Dec 25, 2009 4:59 pm    Post subject: Reply with quote

Well you said your injected right? Why not use ImageNtHeader then and just retrieve the base/size of the .CODE section (or whatever header you want to scan) so that you aren't scanning memory that isn't even in the region?

Another thing, as a precaution, is that you should check for the bit-wise masks: PAGE_NOACCESS and PAGE_GUARD through VirtualQuery of the .CODE section or whatever section you're scanning because if these flags are marked, then you the system will raise access violations exceptions.

P.S. doesn't really look like an "engine". Just looks like a program that just searches byte signatures.

_________________
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 Dec 25, 2009 5:25 pm    Post subject: Reply with quote

@lurc I protect all my addresses I encounter with PAGE_EXECUTE_READWRITE so theirs no need for VirtualQuery(). ImageNtHeader, i'm considering to use.

Also, it is a engine, it doesn't only scan for byte signatures, it scans for more. You'll get first dip when you get a copy.
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 475

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

PostPosted: Fri Dec 25, 2009 5:58 pm    Post subject: Reply with quote

Code:

 SendMessageX(ListBox1, LB_ADDSTRING, 0, (LPARAM) ConvertAddress((LPVOID) Start).c_str());

waits till the message has been written to the listbox and then returns, you could probably improve that by going multithreaded and using postmessage (of course, keep track of the allocated strings)

also, make sure the routine "ReadByte" does not contain one single windows API call, if it does, it'll be slow

if you HAVE to call windows api's then limit them to the least possible times called. So if you are going to read a 4MB region, only call the api's once and then check the 4MB buffer

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
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: Fri Dec 25, 2009 6:12 pm    Post subject: Reply with quote

holy cow, please don't write all your code into 1 giant cluster
Back to top
View user's profile Send private message
Anden100
Grandmaster Cheater
Reputation: 0

Joined: 20 Apr 2007
Posts: 668

PostPosted: Sat Dec 26, 2009 10:55 am    Post subject: Reply with quote

Dark Byte wrote:
Code:

 SendMessageX(ListBox1, LB_ADDSTRING, 0, (LPARAM) ConvertAddress((LPVOID) Start).c_str());

waits till the message has been written to the listbox and then returns, you could probably improve that by going multithreaded and using postmessage (of course, keep track of the allocated strings)

also, make sure the routine "ReadByte" does not contain one single windows API call, if it does, it'll be slow

if you HAVE to call windows api's then limit them to the least possible times called. So if you are going to read a 4MB region, only call the api's once and then check the 4MB buffer


Is it possible to do multiple LB_ADDSTRING's in just one PostMessage call, to display all addresses in one call to PostMessage?
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Sat Dec 26, 2009 1:43 pm    Post subject: Reply with quote

@Anden100 I dont think so.
@slovach Lol..
@Dark Byte Thanks.

What i'm doing now to scan faster is making multiple threads that reads a certain amount of addresses, until they fnally reach to the target stop region.
Back to top
View user's profile Send private message MSN Messenger
Flyte
Peanuts!!!!
Reputation: 6

Joined: 19 Apr 2006
Posts: 1887
Location: Canada

PostPosted: Sat Dec 26, 2009 2:54 pm    Post subject: Reply with quote

iPromise wrote:
What i'm doing now to scan faster is making multiple threads that reads a certain amount of addresses, until they fnally reach to the target stop region.


Read: http://iso-9899.info/wiki/Why_not_threads
Back to top
View user's profile Send private message
Anden100
Grandmaster Cheater
Reputation: 0

Joined: 20 Apr 2007
Posts: 668

PostPosted: Sat Dec 26, 2009 3:20 pm    Post subject: Reply with quote

Multiple Threads... thats what i never got to...
And, making a memory scanner is not that big, i did it without too much trouble, and even with a basic (bad looking) GUI, never got to release the source though...
Back to top
View user's profile Send private message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Sat Dec 26, 2009 4:09 pm    Post subject: Reply with quote

@Flyte Then what can I use that wont be so time consuming?

EDIT: Scanning fast is a bitch, multithreading wont do much either..
Back to top
View user's profile Send private message MSN Messenger
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Sun Dec 27, 2009 12:17 am    Post subject: Reply with quote

This is what i'm doing now.

Code:

   SYSTEM_INFO si;
               MEMORY_BASIC_INFORMATION mbi;

               GetSystemInfo(&si);

               DWORD MinimumSystemAddress = (DWORD) si.lpMinimumApplicationAddress;

               do
               {
                  mbi.RegionSize = 0;
                  SIZE_T ret = VirtualQuery((LPCVOID) MinimumSystemAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));

                  if (ret == sizeof(MEMORY_BASIC_INFORMATION))
                  {
                     if (mbi.Type == MEM_PRIVATE)
                     {
                        if (mbi.State = MEM_COMMIT)
                        {
                           if (mbi.RegionSize > 0)
                           {
                              bool Read = ReadByte(MinimumSystemAddress, atoi(GetValue));

                              if (Read == true)
                              {
                                 SendMessageX(ListBox1, LB_ADDSTRING, 0, (LPARAM) ConvertAddress((LPVOID) MinimumSystemAddress).c_str());
                              }
                           }
                        }
                     }
                  }

                  ++MinimumSystemAddress;

               } while (MinimumSystemAddress <= (DWORD) 0x7FFFFFFF);

               GetResults();
Back to top
View user's profile Send private message MSN Messenger
lurc
Grandmaster Cheater Supreme
Reputation: 2

Joined: 13 Nov 2006
Posts: 1900

PostPosted: Sun Dec 27, 2009 1:10 am    Post subject: Reply with quote

1. You're initializing a new variable every single time it loops (which is a lot of times.)

Solution: Place variable definitions outside of loop.

SIZE_T ret;
bool Read;

do { ... } while ( ... );

2. Your calling VirtualQuery on EVERY-SINGLE-ADDRESS. I mean that's good for catching exceptions and all, but usually an entire page is going to be protected the same way.

3. Your sending a message every single time you read a correct byte, Why not just store all the address's as they are (DWORD) and just convert them all to strings and add them to the list box AFTER your done searching?

4. Like i said before, your searching far passed the region of game memory. Find out the end of the region your searching instead, then you won't need to worry about wasting time searching a place where you have no interest in.

Edit:
Forgot to add this

Code:
if (mbi.State = MEM_COMMIT)

Your assigning the state MEM_COMMIT, when you should be comparing.
Switch that = to ==

_________________
Back to top
View user's profile Send private message
hcavolsdsadgadsg
I'm a spammer
Reputation: 26

Joined: 11 Jun 2007
Posts: 5801

PostPosted: Sun Dec 27, 2009 3:03 am    Post subject: Reply with quote

lurc wrote:
1. You're initializing a new variable every single time it loops (which is a lot of times.)

Solution: Place variable definitions outside of loop.

SIZE_T ret;
bool Read;

do { ... } while ( ... );


no, you don't need to worry about this.
this is not what is happening in actuality.
Back to top
View user's profile Send private message
Slugsnack
Grandmaster Cheater Supreme
Reputation: 71

Joined: 24 Jan 2007
Posts: 1857

PostPosted: Sun Dec 27, 2009 6:35 am    Post subject: Reply with quote

Base, EP, etc.

Code:
#include <windows.h>
#include <stdio.h>
#include <conio.h>

int main()
{
  IMAGE_DOS_HEADER* pIDH = (IMAGE_DOS_HEADER*)GetModuleHandle( NULL );
  IMAGE_NT_HEADERS* pINH = (IMAGE_NT_HEADERS*)((BYTE*)pIDH + (pIDH -> e_lfanew));
  IMAGE_OPTIONAL_HEADER IOH = pINH -> OptionalHeader;

  printf( "Magic number is : %u\n", pIDH -> e_magic );
  printf( "Address of entry point is : %#x", IOH.AddressOfEntryPoint );

  while( !_kbhit() )
    Sleep(100);

  return 0;
}


And you are using VirtualQuery completely wrong. You're not supposed to use VirtualProtect to make all memory readable either that's retarded.

Here is the code for my 'first scan' function in one of my first C projects. Yes, don't expect the code to be particularly good.

Code:
void FirstScan( unsigned int nValue, HWND hwndList )
{
  MEMORY_BASIC_INFORMATION mbi = {0};
  DWORD dwEndAddr;
  int iIndex;
  LVITEM lvi = {0};

  lvi.mask = LVIF_TEXT;
  lvi.iItem = 1;
  lvi.iSubItem = 0;
  TCHAR szAddress[9] = {0};
  TCHAR szValue[11] = {0};

  swprintf_s( szValue, _countof( szValue ), _T("%d"), nValue );

  while ( VirtualQuery( ( VOID * )( ( int )mbi.BaseAddress + mbi.RegionSize ), &mbi, sizeof( MEMORY_BASIC_INFORMATION ) ) )
  {
    if( mbi.Protect == PAGE_READWRITE )
    {
      dwEndAddr = ( DWORD )mbi.BaseAddress + mbi.RegionSize - 1 - ( !nScanType ? 0 : nScanType * 2 );

      for( DWORD i = ( DWORD )mbi.BaseAddress; i <= dwEndAddr; i++ )
      {
        __try
        {
          if( ( !nScanType && *( BYTE * )i == ( BYTE )nValue )
              || ( nScanType == 1 && *( WORD * )i == ( WORD )nValue )
              || ( nScanType == 2 && *( DWORD* )i == ( DWORD )nValue ) )
          {
            swprintf_s( szAddress, _countof( szAddress ), _T("%08X"), i );
            iIndex = ListView_InsertItem( hwndList, &lvi );
            ListView_SetItemText( hwndList, iIndex, 0, szAddress );
            ListView_SetItemText( hwndList, iIndex, 1, szValue );
            lvi.iItem++;
          }
        }
        __except( true )
        {
          i = dwEndAddr;
        }
      }
    }
  }
}
Back to top
View user's profile Send private message
Anden100
Grandmaster Cheater
Reputation: 0

Joined: 20 Apr 2007
Posts: 668

PostPosted: Sun Dec 27, 2009 7:29 am    Post subject: Reply with quote

This is what i did in my MemoryScanner (removed some functions -.-), saves all results to a file, which can then be read later to print it in a different loop

Code:
#define SAVE_COUNT 100 //could be any number, how often values will be saved to a file

struct addr{
   int address;
   int value;
};

HANDLE hProcess;

BOOL scan(int value){
   std::fstream save(ADDRFILE, std::ios::binary | std::ios::out | std::ios::app);
   int pos = 0;
   addr address[50];
   MEMORY_BASIC_INFORMATION mbi;
   SYSTEM_INFO si;
   char bufstr[MAX_PATH];
   GetSystemInfo(&si);
   int min = (int)si.lpMinimumApplicationAddress;
   int max = (int)si.lpMaximumApplicationAddress;
   size_t s;
   if(hProcess == INVALID_HANDLE_VALUE){
      MessageBox(NULL, "Please choose a process!", "Notice", NULL);
      return FALSE;
   }
   for(int i = min; i < max;){
      s = VirtualQueryEx(hProcess, (LPVOID)i, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
      if(s == sizeof(MEMORY_BASIC_INFORMATION) && mbi.Type == MEM_PRIVATE && mbi.State == MEM_COMMIT && mbi.RegionSize > 0){
         size_t reg = mbi.RegionSize;
         void *buffer = malloc(reg);
         ReadProcessMemory(hProcess, (LPVOID)mbi.BaseAddress, buffer, reg, NULL);
         for(unsigned int j = 0; j < reg; j++){
            int *val = (int*)((DWORD)buffer + j);
            if(*val == value){
               if(pos <= SAVE_COUNT+1){
                  save.write(reinterpret_cast<char*>(&address), sizeof(addr)*pos);
                  pos = 0;
               }
               address[pos].address = (int)mbi.BaseAddress+j;
               address[pos].value = value;
               pos++;
               resultcount++;
            }
         }
      }
      if(s == 0){
         DWORD err = GetLastError();
         if(err == 6)
            sprintf_s(bufstr, sizeof(bufstr), "Please select a process");
         else
            sprintf_s(bufstr, sizeof(bufstr), "VirtualQueryEx failed with error code: %d", err);
         MessageBox(NULL, bufstr, "Error!", 0);
         return FALSE;
      }
      DWORD prog = (DWORD)mbi.BaseAddress + (DWORD)mbi.RegionSize;
      i = prog;
   }
   save.write(reinterpret_cast<char*>(&address), sizeof(addr)*pos);
   save.close();
   return TRUE;
}


This little piece of code is quite fast Razz, (of curse, DB's Memory Scan is faster, but this works properly Razz

and Slugsnack, tyvm for the DOS header thing Razz, very useful for my Disassembler project (omg a lot of coding it takes...)
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, 3  Next
Page 1 of 3

 
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