paulohr

Memory Scanner by HadFuny in C

Apr 3rd, 2012
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.66 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. #define IS_IN_SEARCH(mb, offset) (mb->searchmask[(offset)/8] & (1<<((offset)%8)))
  5. #define REMOVE_FROM_SEARCH(mb, offset)  mb->searchmask[(offset)/8] &= ~(1<<((offset)%8));
  6.  
  7. typedef struct _MEMBLOCK
  8. {
  9.   HANDLE hProc;
  10.   unsigned char *addr;
  11.   int size;
  12.   unsigned char *buffer;
  13.  
  14.   unsigned char *searchmask;
  15.   int matches;
  16.   int data_size;
  17.  
  18.   struct _MEMBLOCK *next;
  19. } MEMBLOCK;
  20.  
  21. typedef enum
  22. {
  23.   COND_UNCONDITIONAL,
  24.   COND_EQUALS,
  25.  
  26.   COND_INCREASED,
  27.   COND_DECREASED,
  28. } SEARCH_CONDITION;
  29.  
  30. MEMBLOCK* create_memblock (HANDLE hProc, MEMORY_BASIC_INFORMATION *meminfo, int data_size)
  31. {
  32.   MEMBLOCK *mb = malloc(sizeof(MEMBLOCK));
  33.  
  34.   if (mb)
  35.   {
  36.     mb->hProc = hProc;
  37.     mb->addr = meminfo->BaseAddress;
  38.     mb->size = meminfo->RegionSize;
  39.     mb->buffer = malloc(meminfo->RegionSize);
  40.     mb->searchmask = malloc(meminfo->RegionSize/8);
  41.     memset (mb->searchmask, 0xff, meminfo->RegionSize/8);
  42.     mb->matches = meminfo->RegionSize;
  43.     mb->next = NULL;
  44.     mb->data_size = data_size;
  45.   }
  46.   return mb;
  47. }
  48.  
  49. void free_memblock (MEMBLOCK *mb)
  50. {
  51.   if (mb)
  52.   {
  53.     if (mb->buffer)
  54.     {
  55.       free(mb->buffer);
  56.     }
  57.    
  58.     if (mb->searchmask)
  59.     {
  60.       free(mb->searchmask);
  61.     }
  62.    
  63.     free (mb);
  64.   }
  65. }
  66.  
  67. void update_memblock (MEMBLOCK *mb, SEARCH_CONDITION condition, unsigned int val)
  68. {
  69.      static unsigned char tempbuf[128*1024];
  70.      unsigned int bytes_left;
  71.      unsigned int total_read;
  72.      unsigned int bytes_to_read;
  73.      unsigned int bytes_read;
  74.      
  75.   if (mb->matches > 0)
  76.   {
  77.      
  78.      bytes_left = mb->size;
  79.      total_read = 0;
  80.      mb->matches = 0;
  81.      
  82.      while (bytes_left)
  83.      {
  84.            bytes_to_read = (bytes_left > sizeof(tempbuf)) ?  sizeof(tempbuf) : bytes_left;
  85.            ReadProcessMemory (mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, (DWORD*)&bytes_read);
  86.            if (bytes_read != bytes_to_read) break;
  87.            
  88.            if (condition == COND_UNCONDITIONAL)
  89.            {
  90.                memset (mb->searchmask + (total_read/8), 0xff, bytes_read/8);
  91.                mb->matches += bytes_read;
  92.            }
  93.            else
  94.            {
  95.                unsigned int offset;
  96.                
  97.                for (offset = 0; offset < bytes_read; offset += mb->data_size)
  98.                {
  99.                    if (IS_IN_SEARCH(mb, (total_read+offset)))
  100.                    {
  101.                       BOOL is_match = FALSE;
  102.                       unsigned int temp_val;
  103.                       unsigned int prev_val = 0;
  104.                      
  105.                       switch (mb->data_size)
  106.                       {
  107.                           case 1:
  108.                                temp_val = tempbuf[offset];
  109.                                prev_val = *((unsigned char*)&mb->buffer[total_read+offset]);
  110.                                break;
  111.                           case 2:
  112.                                temp_val = *((unsigned short*)&tempbuf[offset]);
  113.                                prev_val = *((unsigned short*)&mb->buffer[total_read+offset]);
  114.                                break;
  115.                           case 4:
  116.                           default:
  117.                                temp_val = *((unsigned int*)&tempbuf[offset]);
  118.                                prev_val = *((unsigned int*)&mb->buffer[total_read+offset]);
  119.                               break;
  120.                       }
  121.                      
  122.                       switch (condition)
  123.                       {
  124.                          case COND_EQUALS:
  125.                               is_match = (temp_val == val);
  126.                               break;
  127.                          case COND_INCREASED:
  128.                               is_match = (temp_val > prev_val);
  129.                               break;
  130.                          case COND_DECREASED:
  131.                               is_match = (temp_val < prev_val);
  132.                               break;
  133.                          default:
  134.                               break;
  135.                       }
  136.                      
  137.                       if (is_match)
  138.                       {
  139.                         mb->matches++;
  140.                       }
  141.                       else
  142.                       {
  143.                         REMOVE_FROM_SEARCH(mb,(total_read+offset));
  144.                       }
  145.                      
  146.                    }
  147.                }
  148.            }
  149.            
  150.            memcpy (mb->buffer + total_read, tempbuf, bytes_read);
  151.            
  152.            bytes_left -= bytes_read;
  153.            total_read += bytes_read;
  154.      }
  155.      
  156.      mb->size = total_read;
  157.   }  
  158. }
  159.  
  160. MEMBLOCK* create_scan (unsigned int pid, int data_size)
  161. {
  162.   MEMBLOCK *mb_list = NULL;
  163.   MEMORY_BASIC_INFORMATION meminfo;
  164.   unsigned char *addr = 0;
  165.  
  166.   HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  167.  
  168.   if (hProc)
  169.   {
  170.     while (1)
  171.     {
  172.       if (VirtualQueryEx (hProc, addr, &meminfo, sizeof(meminfo))==0)
  173.       {
  174.         break;
  175.       }  
  176.  
  177. #define WRITABLE (PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
  178.      
  179.       if ((meminfo.State & MEM_COMMIT) && (meminfo.Protect & WRITABLE ))
  180.       {  
  181.          
  182.         MEMBLOCK *mb = create_memblock(hProc, &meminfo, data_size);
  183.         if (mb)
  184.         {
  185. //           update_memblock (mb);
  186.            mb->next = mb_list;
  187.            mb_list = mb;
  188.         }
  189.       }
  190.         addr = (unsigned char*)meminfo.BaseAddress + meminfo.RegionSize;
  191.     }
  192.   }
  193.  
  194.   return mb_list;
  195. }
  196.  
  197. void free_scan (MEMBLOCK *mb_list)
  198. {
  199.      CloseHandle (mb_list->hProc);
  200.      
  201.      while (mb_list)
  202.      {
  203.            MEMBLOCK *mb = mb_list;
  204.            mb_list = mb_list->next;
  205.            free_memblock (mb);
  206.      }
  207. }
  208.  
  209. void update_scan (MEMBLOCK *mb_list, SEARCH_CONDITION condition, unsigned int val)
  210. {
  211.      MEMBLOCK *mb = mb_list;
  212.      while (mb)
  213.      {
  214.            update_memblock (mb, condition, val);
  215.            mb = mb->next;
  216.      }
  217. }
  218.  
  219. void dump_scan_info (MEMBLOCK *mb_list)
  220. {
  221.      MEMBLOCK *mb = mb_list;
  222.      
  223.      while (mb)
  224.      {
  225.            int i;
  226.            printf ("0x%08x %d\r\n", mb->addr, mb->size);
  227.            
  228.            for (i = 0; i < mb->size; i++)
  229.            {
  230.                printf("%02x", mb->buffer[i]);
  231.            }
  232.            printf ("\r\n");
  233.            
  234.            mb = mb->next;
  235.      }
  236. }
  237.  
  238. void poke (HANDLE hProc, int data_size, unsigned int addr, unsigned int val)
  239. {
  240.      if (WriteProcessMemory (hProc, (void*)addr, &val, data_size, NULL) == 0)
  241.      {
  242.          printf("poke failed\r\n");
  243.      }
  244. }
  245.  
  246. unsigned int peek (HANDLE hProc, int data_size, unsigned int addr)
  247. {
  248.      unsigned int val = 0;
  249.      
  250.      if (ReadProcessMemory (hProc, (void*)addr, &val, data_size, NULL) == 0)
  251.      {
  252.          printf("poke failed\r\n");
  253.      }
  254.      
  255.      return val;
  256. }
  257.  
  258. void print_matches (MEMBLOCK *mb_list)
  259. {
  260.      unsigned int offset;
  261.      MEMBLOCK *mb = mb_list;
  262.      
  263.      while (mb)
  264.      {
  265.            for (offset = 0; offset < mb->size; offset+= mb->data_size)
  266.            {
  267.                if (IS_IN_SEARCH(mb, offset))
  268.                {
  269.                   unsigned int val = peek (mb->hProc, mb->data_size, (unsigned int)mb->addr + offset);
  270.                   printf("0x%08x: 0x%08x (%d) \r\n", mb->addr + offset, val, val);
  271.                }
  272.            }
  273.            
  274.            mb = mb->next;
  275.      }
  276. }
  277.  
  278. int get_match_count (MEMBLOCK *mb_list)
  279. {
  280.     MEMBLOCK *mb = mb_list;
  281.     int count = 0;
  282.    
  283.     while (mb)
  284.     {
  285.           count += mb->matches;
  286.           mb = mb->next;
  287.     }
  288.    
  289.     return count;
  290. }
  291.  
  292. unsigned int str2int (char *s)
  293. {
  294.    int base = 10;
  295.    
  296.    if (s[0] == '0' && s[1] == 'x')
  297.    {
  298.      base = 16;
  299.      s += 2;
  300.    }
  301.    
  302.    return strtoul (s, NULL, base);
  303. }
  304.  
  305. MEMBLOCK* ui_new_scan(void)
  306. {
  307.    MEMBLOCK *scan = NULL;
  308.    DWORD pid;
  309.    int data_size;
  310.    unsigned int start_val;
  311.    SEARCH_CONDITION start_cond;
  312.    char s[20];
  313.    
  314.    while(1)
  315.    {
  316.            printf("\r\nEnter the pid: ");
  317.            fgets (s, sizeof(s), stdin);
  318.            pid = str2int(s);
  319.            printf ("\r\nEnter the data size: ");
  320.            fgets (s, sizeof(s), stdin);
  321.            data_size = str2int(s);
  322.            printf ("\r\nEnter the start value, or 'u' for unknown:  ");
  323.            fgets (s, sizeof(s), stdin);
  324.            if (s[0] == 'u')
  325.            {
  326.               start_cond = COND_UNCONDITIONAL;
  327.               start_val = 0;
  328.            }
  329.            else
  330.            {
  331.                start_cond = COND_EQUALS;
  332.                start_val = str2int (s);
  333.            }
  334.            
  335.            scan = create_scan (pid, data_size);
  336.            if (scan) break;
  337.            printf ("\r\nInvalid scan");
  338.    }
  339.    
  340.    update_scan (scan, start_cond, start_val);
  341.    printf("\r\n%d matches found\r\n", get_match_count(scan));
  342.    
  343.    return scan;      
  344. }
  345.  
  346. void ui_poke (HANDLE hProc, int data_size)
  347. {
  348.      unsigned int addr;
  349.      unsigned int val;
  350.      char s[20];
  351.      
  352.      printf("Enter the address: ");
  353.      fgets (s, sizeof(s), stdin);
  354.      addr = str2int(s);
  355.      
  356.      printf("\r\nEnter the value: ");
  357.      fgets (s, sizeof(s), stdin);
  358.      val = str2int(s);
  359.      printf ("\r\n");
  360.      
  361.      poke (hProc, data_size, addr, val);
  362. }
  363.  
  364. void ui_run_scan(void)
  365. {
  366.      unsigned int val;
  367.      char s[20];
  368.      MEMBLOCK *scan;
  369.      
  370.      scan = ui_new_scan();
  371.      
  372.      while(1)
  373.      {
  374.         printf("\r\nEnter the next value or");
  375.         printf("\r\n[i] increased");
  376.         printf("\r\n[d] decreased");
  377.         printf("\r\n[m] print matches");
  378.         printf("\r\n[p] poke address");
  379.         printf("\r\n[n] new scan");
  380.         printf("\r\n[q] quit\r\n");
  381.        
  382.         fgets (s, sizeof(s), stdin);
  383.         printf("\r\n" );
  384.        
  385.         switch(s[0])
  386.         {
  387.           case 'i':
  388.                update_scan (scan, COND_INCREASED, 0);
  389.                printf(" %d matches found\r\n", get_match_count(scan));
  390.                break;
  391.           case 'd':
  392.                update_scan (scan, COND_DECREASED, 0);
  393.                printf(" %d matches found\r\n", get_match_count(scan));
  394.                break;
  395.           case 'm':
  396.                print_matches(scan);
  397.                break;
  398.           case 'p':
  399.                ui_poke (scan->hProc, scan->data_size);
  400.                break;
  401.           case 'n':
  402.                free_scan(scan);
  403.                scan = ui_new_scan();
  404.                break;
  405.           case 'q':
  406.                free_scan(scan);
  407.                return;
  408.           default:
  409.                val = str2int(s);
  410.                update_scan(scan, COND_EQUALS, val);
  411.                printf(" %d matches found\r\n", get_match_count(scan));
  412.                break;
  413.         }
  414.      }
  415. }
  416.  
  417. int main (int argc, char *argv[])
  418. {
  419.      ui_run_scan();
  420.      return 0;
  421. }
Advertisement
Add Comment
Please, Sign In to add comment