Registration Code (Part 1): w%kQ6
Registration Code (Part 2): b<#$1[*(cw~
In order to register on this forum, you must use the codes above. Combine them into one code (copy paste).

Memory Scanner Example

Programming topics that relate to the C/C++ languages.
Post Reply
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Memory Scanner Example

Post by atom0s » Wed Jan 07, 2015 2:13 am

This is an example I wrote recently for someone to demonstrate how to scan for a value within memory of a process.
  1. /**
  2.  * Simple Memory Scanner Example
  3.  * (c) 2014 atom0s [atom0s@live.com]
  4.  */
  5.  
  6. #include <Windows.h>
  7. #include <string>
  8. #include <TlHelp32.h>
  9.  
  10. /**
  11.  * @brief The target process to scan within.
  12.  */
  13. #define TARGET_NAME "winmine.exe"
  14.  
  15. /**
  16.  * @brief Obtains the process id of the given target.
  17.  *
  18.  * @return The process id if found, 0 otherwise.
  19.  */
  20. unsigned int getTargetProcessId()
  21. {
  22.     PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
  23.  
  24.     // Obtain a snapshot of the current process list..
  25.     auto handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  26.     if (handle == INVALID_HANDLE_VALUE)
  27.         return 0;
  28.  
  29.     // Obtain the first process..
  30.     if (!::Process32First(handle, &pe32))
  31.     {
  32.         ::CloseHandle(handle);
  33.         return 0;
  34.     }
  35.  
  36.     // Loop each process looking for the target..
  37.     do
  38.     {
  39.         if (!_stricmp(pe32.szExeFile, TARGET_NAME))
  40.         {
  41.             ::CloseHandle(handle);
  42.             return pe32.th32ProcessID;
  43.         }
  44.     } while (::Process32Next(handle, &pe32));
  45.  
  46.     // Cleanup..
  47.     ::CloseHandle(handle);
  48.     return 0;
  49. }
  50.  
  51. /**
  52.  * @brief Entry point of this application.
  53.  *
  54.  * @param argc  The count of arguments passed to this application.
  55.  * @param argv  The array of arguments passed to this application.
  56.  *
  57.  * @return Non-important return.
  58.  */
  59. int __cdecl main(int argc, char* argv[])
  60. {
  61.     // Obtain the target process id..
  62.     auto processId = getTargetProcessId();
  63.     if (processId == 0)
  64.         return 0;
  65.  
  66.     // Open a handle to the target..
  67.     auto handle = ::OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId);
  68.     if (handle == INVALID_HANDLE_VALUE)
  69.         return 0;
  70.  
  71.     // Obtain the current system information..
  72.     SYSTEM_INFO sysInfo = { 0 };
  73.     ::GetSystemInfo(&sysInfo);
  74.  
  75.     auto addr_min = (long)sysInfo.lpMinimumApplicationAddress;
  76.     auto addr_max = (long)sysInfo.lpMaximumApplicationAddress;
  77.  
  78.     auto found = 0;
  79.  
  80.     // Loop the pages of memory of the application..
  81.     while (addr_min < addr_max)
  82.     {
  83.         MEMORY_BASIC_INFORMATION mbi = { 0 };
  84.         if (!::VirtualQueryEx(handle, (LPCVOID)addr_min, &mbi, sizeof(mbi)))
  85.         {
  86.             printf_s("Failed to query memory.\n");
  87.             break;
  88.         }
  89.  
  90.         // Determine if we have access to the page..
  91.         if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_GUARD) == 0) && ((mbi.Protect & PAGE_NOACCESS) == 0))
  92.         {
  93.             //
  94.             // Below are flags about the current region of memory. If you want to specifically scan for only
  95.             // certain things like if the area is writable, executable, etc. you can use these flags to prevent
  96.             // reading non-desired protection types.
  97.             //
  98.  
  99.             auto isCopyOnWrite = ((mbi.Protect & PAGE_WRITECOPY) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITECOPY) != 0);
  100.             auto isExecutable = ((mbi.Protect & PAGE_EXECUTE) != 0 || (mbi.Protect & PAGE_EXECUTE_READ) != 0 || (mbi.Protect & PAGE_EXECUTE_READWRITE) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITECOPY) != 0);
  101.             auto isWritable = ((mbi.Protect & PAGE_READWRITE) != 0 || (mbi.Protect & PAGE_WRITECOPY) != 0 || (mbi.Protect & PAGE_EXECUTE_READWRITE) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITECOPY) != 0);
  102.  
  103.             // Dump the region into a memory block..
  104.             auto dump = new unsigned char[mbi.RegionSize + 1];
  105.             memset(dump, 0x00, mbi.RegionSize + 1);
  106.             if (!::ReadProcessMemory(handle, mbi.BaseAddress, dump, mbi.RegionSize, NULL))
  107.             {
  108.                 printf_s("Failed to read memory of location: %08X\n", mbi.BaseAddress);
  109.                 break;
  110.             }
  111.  
  112.             // Scan for 4 byte value of 8675309..
  113.             for (auto x = 0; x < mbi.RegionSize - 4; x += 4)
  114.             {
  115.                 if (*(DWORD*)(dump + x) == 1337)
  116.                     found++;
  117.             }
  118.  
  119.             // Cleanup the memory dump..
  120.             delete[] dump;
  121.         }
  122.  
  123.         // Step the current address by this regions size..
  124.         addr_min += mbi.RegionSize;
  125.     }
  126.  
  127.     printf_s("Found %d results!\n", found);
  128.  
  129.     // Cleanup..
  130.     ::CloseHandle(handle);
  131.     return ERROR_SUCCESS;
  132. }
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
poKebol
Posts: 3
Joined: Fri Apr 17, 2015 2:16 pm

Re: Memory Scanner Example

Post by poKebol » Fri Apr 17, 2015 2:20 pm

Very nice.

So,

Just trying to understand it:

Code: Select all

mbi.BaseAddress + x
is the actual address?

And if i want to serch a Array of Bytes like cheat engine does:

Code: Select all

 for (auto x = 0; x < mbi.RegionSize - 1; x += 1)
            {
                if ((dump + x) == "my  array")
                    found++;
            }
?

Ty for your time and code. :D
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Memory Scanner Example

Post by atom0s » Fri Apr 17, 2015 10:04 pm

Yes the address would be based from the current dumped region + x as the offset.

If you want to search for an array of bytes you can check out my topic here:
viewtopic.php?f=5&t=4

Coupled together with the above you can do what you are asking.
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest