Guest User

Untitled

a guest
Sep 9th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.71 KB | None | 0 0
  1. /**
  2. * Simple Memory Scanner Example
  3. * (c) 2014 atom0s [atom0s@live.com]
  4. */
  5.  
  6. #include <Windows.h>
  7. #include <wchar.h>
  8. #include <iostream>
  9. #include <string>
  10. #include <TlHelp32.h>
  11. #include <vector>
  12. using namespace std;
  13.  
  14. /**
  15. * @brief The target process to scan within.
  16. */
  17. const wchar_t *TARGET_NAME = L"ac_client.exe";
  18. const unsigned int ARRAY_SIZE = 8000;
  19.  
  20. /**
  21. * @brief Obtains the process id of the given target.
  22. *
  23. * @return The process id if found, 0 otherwise.
  24. */
  25.  
  26. void flushArrayToFile(FILE * file, uint32_t arr[]) {
  27.     fwrite(arr, sizeof(uint32_t), sizeof(arr) / 4, file);
  28. }
  29.  
  30. const int getFileSize(FILE * file) {
  31.     fseek(file, 0, SEEK_END);
  32.     return ftell(file);
  33. }
  34.  
  35. unsigned int getTargetProcessId()
  36. {
  37.     PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
  38.  
  39.     // Obtain a snapshot of the current process list..
  40.     auto handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  41.     if (handle == INVALID_HANDLE_VALUE)
  42.         return 0;
  43.  
  44.     // Obtain the first process..
  45.     if (!::Process32First(handle, &pe32))
  46.     {
  47.         ::CloseHandle(handle);
  48.         return 0;
  49.     }
  50.  
  51.     // Loop each process looking for the target..
  52.     do
  53.     {
  54.         if (!wcscmp(pe32.szExeFile, TARGET_NAME))
  55.         {
  56.             ::CloseHandle(handle);
  57.             return pe32.th32ProcessID;
  58.         }
  59.     } while (::Process32Next(handle, &pe32));
  60.  
  61.     // Cleanup..
  62.     ::CloseHandle(handle);
  63.     return 0;
  64. }
  65.  
  66. void showMbiInfo(MEMORY_BASIC_INFORMATION mbi) {
  67.     cout << hex << "Base Address: " << mbi.BaseAddress << endl;
  68.     cout << "Region Size: " << mbi.RegionSize << endl;
  69. }
  70.  
  71. /**
  72. * @brief Entry point of this application.
  73. *
  74. * @param argc  The count of arguments passed to this application.
  75. * @param argv  The array of arguments passed to this application.
  76. *
  77. * @return Non-important return.
  78. */
  79. int __cdecl main(int argc, char* argv[])
  80. {
  81.     // Obtain the target process id..
  82.     auto processId = getTargetProcessId();
  83.     cout << processId << endl;
  84.  
  85.     if (processId == 0)
  86.         return 0;
  87.  
  88.     // Open a handle to the target..
  89.     auto handle = ::OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId);
  90.     if (handle == INVALID_HANDLE_VALUE)
  91.         return 0;
  92.  
  93.     // Obtain the current system information..
  94.     SYSTEM_INFO sysInfo = { 0 };
  95.     ::GetSystemInfo(&sysInfo);
  96.  
  97.     auto addr_min = (unsigned long)sysInfo.lpMinimumApplicationAddress;
  98.     auto addr_max = (unsigned long)sysInfo.lpMaximumApplicationAddress;
  99.  
  100.     cout << addr_min << " to " << addr_max << endl;
  101.  
  102.     cout << "Enter 4 byte value to search: " << endl;
  103.     int value;
  104.     cin >> value;
  105.  
  106.     uint32_t addresses[ARRAY_SIZE];
  107.     int curIndex = 0;
  108.     int foundCurrent = 0;
  109.     int foundTotal = 0;
  110.     FILE * file = fopen("addr.bin", "wb");
  111.     // initial scan ("new scan")
  112.     while (addr_min < addr_max)
  113.     {
  114.         MEMORY_BASIC_INFORMATION mbi = { 0 };
  115.         if (!::VirtualQueryEx(handle, (LPCVOID)addr_min, &mbi, sizeof(mbi)))
  116.         {
  117.             printf_s("Failed to query memory.\n");
  118.             break;
  119.         }
  120.  
  121.         // Determine if we have access to the page..
  122.         if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_GUARD) == 0) && ((mbi.Protect & PAGE_NOACCESS) == 0))
  123.         {
  124.             //
  125.             // Below are flags about the current region of memory. If you want to specifically scan for only
  126.             // certain things like if the area is writable, executable, etc. you can use these flags to prevent
  127.             // reading non-desired protection types.
  128.             //
  129.  
  130.             auto isCopyOnWrite = ((mbi.Protect & PAGE_WRITECOPY) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITECOPY) != 0);
  131.             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);
  132.             auto isWritable = ((mbi.Protect & PAGE_READWRITE) != 0 || (mbi.Protect & PAGE_WRITECOPY) != 0 || (mbi.Protect & PAGE_EXECUTE_READWRITE) != 0 || (mbi.Protect & PAGE_EXECUTE_WRITECOPY) != 0);
  133.  
  134.             // Dump the region into a memory block..
  135.             auto dump = new unsigned char[mbi.RegionSize + 1];
  136.             memset(dump, 0x00, mbi.RegionSize + 1); // initialize the whole array to 0
  137.             if (!::ReadProcessMemory(handle, mbi.BaseAddress, dump, mbi.RegionSize, NULL))
  138.             {
  139.                 printf_s("Failed to read memory of location: %08X\n", mbi.BaseAddress);
  140.                 break;
  141.             }
  142.  
  143.             // Scan for 4 byte value
  144.             for (int x = 0; x < mbi.RegionSize - 4; x += 4)
  145.             {
  146.                 if (*(uint32_t*)(dump + x) == value) {
  147.                     foundTotal++;
  148.                     foundCurrent++;
  149.                     curIndex++;
  150.  
  151.                     if (curIndex >= ARRAY_SIZE) {
  152.                         fwrite(addresses, sizeof(uint32_t), ARRAY_SIZE, file);
  153.                         foundCurrent -= ARRAY_SIZE;
  154.                         curIndex = 0;
  155.                     }
  156.                     addresses[curIndex] = (uint32_t)mbi.BaseAddress + x;
  157.                     cout << hex << addresses[curIndex] << endl;
  158.                 }
  159.             }
  160.             // Cleanup the memory dump..
  161.             delete[] dump;
  162.         }
  163.  
  164.         // Step the current address by this regions size..
  165.         addr_min += mbi.RegionSize;
  166.     }
  167.     // dump what's left into the file and close
  168.     fwrite(addresses, sizeof(uint32_t), foundCurrent, file);
  169.     fclose(file);
  170.     printf_s("Found %d results!\n", foundTotal);
  171.  
  172.     // below is testing to see if what we pull out of the file matches makes sense
  173.     file = fopen("addr.bin", "rb");
  174.     uint32_t buffer[50000];
  175.     fread(buffer, sizeof(uint32_t), getFileSize(file) / 4, file);
  176.     for (int i = 0; i < foundTotal; i++) {
  177.         cout << "Read from file: " << buffer[i] << endl;
  178.     }
  179.  
  180.     // below is just comments for how I would do a "next" scan but for now it's not there
  181.     // but there's no point since pulling from files isn't working
  182.  
  183.     // in the next loop, do fread for ARRAY_SIZE number of elements,
  184.     // or for the number of elements left in the file
  185.     // (if found > ARRAY_SIZE, found -= ARRAY_SIZE?)
  186.     // else use rest of found, then reset found to 0
  187.     // then ReadProcessMemory the whole array
  188.    
  189.     std::system("pause");
  190.     // Cleanup..
  191.     ::CloseHandle(handle);
  192.     return ERROR_SUCCESS;
  193. }
Add Comment
Please, Sign In to add comment