ToB企服应用市场:ToB评测及商务社交产业平台

标题: (二)内存扫描器(面向对象版) [打印本页]

作者: 小秦哥    时间: 2023-4-4 14:00
标题: (二)内存扫描器(面向对象版)
在此之前,我们实现了内存扫描器(面向过程版)。为了使用的简洁性及可重用性,我们将其模块化,改写为C++类的形式,将用户用不到的成员私有化,对外隐藏,只为其提供类似于首次扫描、再次扫描、内存读写等的接口。
修改后的内存扫描器源码如下:
点击查看代码
  1. #pragma once
  2. #include<Windows.h>
  3. #include<iostream>
  4. #include<vector>
  5. using namespace std;
  6. #define IS_IN_SEARCH(mb,offset) (mb->searchmask[(offset)/8] & (1<<((offset)%8)))
  7. #define REMOVE_FROM_SEARCH(mb,offset) mb->searchmask[(offset)/8]&=~(1<<((offset)%8));
  8. typedef struct _MEMBLOCK
  9. {
  10.         HANDLE hProcess;
  11.         PVOID addr;
  12.         int size;
  13.         char* buffer;
  14.         char* searchmask;//标志每一字节的数据是否在搜索列表中
  15.         int matches;         //匹配的数据个数
  16.         int data_size;   //数据大小(单位字节)
  17.         struct _MEMBLOCK* next;
  18. }MEMBLOCK;
  19. typedef struct _AddrValue
  20. {
  21.         PVOID addr;
  22.         int val;
  23. }AddrValue;
  24. typedef enum
  25. {
  26.         COND_UNCONDITIONAL, //every bytes
  27.         COND_EQUALS,                //bytes particular value
  28.         COND_INCREASE,                //bytes value increased
  29.         COND_DECREASE,                //bytes value decreased
  30. }SEARCH_CONDITION;
  31. class Scanner
  32. {
  33.        
  34. public:
  35.         ~Scanner()
  36.         {
  37.                 if (scan)  free_scan();
  38.         }
  39.         /*扫描*/
  40.         bool first_scan(int pid, int data_size, int start_val, SEARCH_CONDITION start_cond = COND_EQUALS);
  41.         void next_scan(int val, SEARCH_CONDITION condition = COND_EQUALS);
  42.         /*内存读写*/
  43.         void poke(PVOID addr, int val);
  44.         int peek(PVOID addr);
  45.        
  46.         /*统计内存数据*/
  47.         vector<AddrValue> get_data();//获取满足条件的内存地址及数值
  48.         void print_matches(); //打印内存数据 (UI的不需要)
  49.         int get_match_count();//获取满足条件的数据数量
  50. private:
  51.         /*单个内存块*/
  52.         MEMBLOCK* create_memblock(HANDLE hProcess, MEMORY_BASIC_INFORMATION* meminfo, int data_size);
  53.         void update_memblock(MEMBLOCK* mb, SEARCH_CONDITION condition, int val);
  54.         void free_memblock(MEMBLOCK* mb);
  55.         /*所有内存块*/
  56.         MEMBLOCK* create_scan(int pid, int data_size);
  57.         void update_scan(SEARCH_CONDITION condition, int val);
  58.         void dump_scan_info();
  59.         void free_scan();
  60. private:
  61.         MEMBLOCK* scan = NULL;//扫描器
  62.         int data_size;                  //数据大小
  63.         HANDLE hProcess;          //当前进程句柄
  64. };
  65. #include"scanner.h"
  66. MEMBLOCK* Scanner::create_memblock(HANDLE hProcess, MEMORY_BASIC_INFORMATION* meminfo, int data_size)
  67. {
  68.         MEMBLOCK* mb = (MEMBLOCK*)malloc(sizeof(MEMBLOCK));
  69.         if (mb)
  70.         {
  71.                 mb->hProcess = hProcess;
  72.                 mb->addr = meminfo->BaseAddress;
  73.                 mb->size = meminfo->RegionSize;
  74.                 mb->buffer = (char*)malloc(meminfo->RegionSize);
  75.                 //初始化搜索掩码为0xff,表示每一个字节都在搜索列表中
  76.                 mb->searchmask = (char*)malloc(meminfo->RegionSize / 8);
  77.                 memset(mb->searchmask, 0xff, meminfo->RegionSize / 8);
  78.                 mb->matches = meminfo->RegionSize;
  79.                 mb->data_size = data_size;
  80.                 mb->next = NULL;
  81.         }
  82.         return mb;
  83. }
  84. void Scanner::update_memblock(MEMBLOCK* mb, SEARCH_CONDITION condition, int val)
  85. {
  86.         static unsigned char tempbuf[128 * 1024];//0x20000
  87.         unsigned int bytes_left;//当前未处理的字节数
  88.         unsigned int total_read;//已经处理的字节数
  89.         unsigned int bytes_to_read;
  90.         SIZE_T bytes_read;
  91.         if (mb->matches > 0)
  92.         {
  93.                 bytes_left = mb->size;
  94.                 total_read = 0;
  95.                 mb->matches = 0;
  96.                 while (bytes_left)
  97.                 {
  98.                         bytes_to_read = (bytes_left > sizeof(tempbuf)) ? sizeof(tempbuf) : bytes_left;
  99.                         ReadProcessMemory(mb->hProcess, (LPCVOID)((SIZE_T)mb->addr + total_read), tempbuf, bytes_to_read, &bytes_read);
  100.                         //如果读失败了,则结束
  101.                         if (bytes_to_read != bytes_read) break;
  102.                         //条件搜索处
  103.                         if (condition == COND_UNCONDITIONAL)//无条件,则所有数据都匹配
  104.                         {
  105.                                 memset(mb->searchmask + total_read / 8, 0xff, bytes_read / 8);
  106.                                 mb->matches += bytes_read;
  107.                         }
  108.                         else//遍历临时buffer
  109.                         {
  110.                                 for (int offset = 0; offset < bytes_read; offset += mb->data_size)
  111.                                 {
  112.                                         if (IS_IN_SEARCH(mb, (total_read + offset)))
  113.                                         {
  114.                                                 BOOL is_match = FALSE;
  115.                                                 int temp_val;
  116.                                                 int prev_val;
  117.                                                 switch (mb->data_size)//获取临时数值的大小
  118.                                                 {
  119.                                                 case 1:
  120.                                                         temp_val = tempbuf[offset];
  121.                                                         prev_val = *((char*)&mb->buffer[total_read + offset]);
  122.                                                         break;
  123.                                                 case 2:
  124.                                                         temp_val = *((short*)&tempbuf[offset]);
  125.                                                         prev_val = *((short*)&mb->buffer[total_read + offset]);
  126.                                                         break;
  127.                                                 case 4:
  128.                                                 default:
  129.                                                         temp_val = *((int*)&tempbuf[offset]);
  130.                                                         prev_val = *((short*)&mb->buffer[total_read + offset]);
  131.                                                         break;
  132.                                                 }
  133.                                                 switch (condition)//根据不同搜索条件处理
  134.                                                 {
  135.                                                 case COND_EQUALS:
  136.                                                         is_match = (temp_val == val);
  137.                                                         break;
  138.                                                 case COND_INCREASE:
  139.                                                         is_match = (temp_val > prev_val);
  140.                                                         break;
  141.                                                 case COND_DECREASE:
  142.                                                         is_match = (temp_val < prev_val);
  143.                                                         break;
  144.                                                 default:
  145.                                                         break;
  146.                                                 }
  147.                                                 if (is_match)
  148.                                                 {
  149.                                                         mb->matches++;
  150.                                                 }
  151.                                                 else
  152.                                                 {
  153.                                                         REMOVE_FROM_SEARCH(mb, (total_read + offset));
  154.                                                 }
  155.                                         }
  156.                                 }
  157.                         }
  158.                         memcpy(mb->buffer + total_read, tempbuf, bytes_read);
  159.                         bytes_left -= bytes_read;
  160.                         total_read += bytes_read;
  161.                 }
  162.                 mb->size = total_read;
  163.         }
  164. }
  165. void Scanner::free_memblock(MEMBLOCK* mb)
  166. {
  167.         if (mb)
  168.         {
  169.                 if (mb->buffer)
  170.                 {
  171.                         free(mb->buffer);
  172.                 }
  173.                 if (mb->searchmask)
  174.                 {
  175.                         free(mb->searchmask);
  176.                 }
  177.                 free(mb);
  178.         }
  179. }
  180. MEMBLOCK* Scanner::create_scan(int pid, int data_size)
  181. {
  182.         MEMBLOCK* mb_list = NULL;
  183.         MEMORY_BASIC_INFORMATION meminfo;
  184.         PVOID addr = 0;
  185.         hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  186.         if (hProcess)
  187.         {
  188.                 while (1)
  189.                 {
  190.                         //查询失败,返回
  191.                         if (!VirtualQueryEx(hProcess, addr, &meminfo, sizeof(meminfo)))
  192.                         {
  193.                                 break;
  194.                         }
  195. #define WRITABLE (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)
  196.                         if ((meminfo.State & MEM_COMMIT) && (meminfo.Protect & WRITABLE))
  197.                         {
  198.                                 MEMBLOCK* mb = create_memblock(hProcess, &meminfo, data_size);
  199.                                 //头插法将扫描的内存块存入内存块列表中
  200.                                 if (mb)
  201.                                 {
  202.                                         //update_memblock(mb);
  203.                                         mb->next = mb_list;
  204.                                         mb_list = mb;
  205.                                 }
  206.                         }
  207.                         addr = (LPVOID)((SIZE_T)meminfo.BaseAddress + meminfo.RegionSize);
  208.                 }
  209.         }
  210.         return mb_list;
  211. }
  212. void Scanner::update_scan(SEARCH_CONDITION condition, int val)
  213. {
  214.         MEMBLOCK* mb = scan;
  215.         while (mb)
  216.         {
  217.                 update_memblock(mb, condition, val);
  218.                 mb = mb->next;
  219.         }
  220. }
  221. void Scanner::dump_scan_info()
  222. {
  223.         MEMBLOCK* mb = scan;
  224.         while (mb)
  225.         {
  226.                 //打印内存块
  227.                 printf("0x%08x 0x%08x\r\n", mb->addr, mb->size);
  228.                 mb = mb->next;
  229.                 //打印内存块中数据
  230.                 for (int i = 0; i < mb->size; i++)
  231.                 {
  232.                         printf("%02x ", mb->buffer[i]);
  233.                         if (i % 16 == 0) printf("\r\n");
  234.                 }
  235.                 printf("\r\n");
  236.         }
  237. }
  238. void Scanner::free_scan()
  239. {
  240.         CloseHandle(scan->hProcess);
  241.         while (scan)
  242.         {
  243.                 MEMBLOCK* mb = scan;
  244.                 scan = scan->next;
  245.                 free_memblock(mb);
  246.         }
  247. }
  248. int Scanner::peek(PVOID addr)
  249. {
  250.         int val = 0;
  251.         if (!ReadProcessMemory(hProcess, addr, &val, data_size, NULL))
  252.         {
  253.                 printf("peek failed\r\n");
  254.         }
  255.         return val;
  256. }
  257. void Scanner::poke(PVOID addr, int val)//写内存
  258. {
  259.         if (!WriteProcessMemory(hProcess, addr, &val, data_size, NULL))
  260.         {
  261.                 printf("poke failed\r\n");
  262.         }
  263. }
  264. void Scanner::print_matches()
  265. {
  266.         vector<AddrValue> data = get_data();
  267.         for (int i = 0; i < data.size(); i++)
  268.         {
  269.                 printf("0x%08x : %d\r\n", data[i].addr, data[i].val);
  270.         }
  271. }
  272. vector<AddrValue> Scanner::get_data()
  273. {
  274.         vector<AddrValue> data;
  275.         MEMBLOCK* mb = scan;
  276.         while (mb)
  277.         {
  278.                 for (int offset = 0; offset < mb->size; offset += mb->data_size)
  279.                 {
  280.                         if (IS_IN_SEARCH(mb, offset))
  281.                         {
  282.                                 int val = peek((PVOID)((SIZE_T)mb->addr + offset));
  283.                                 AddrValue temp;
  284.                                 temp.addr = (PVOID)((SIZE_T)mb->addr + offset);
  285.                                 temp.val = val;
  286.                                 data.push_back(temp);
  287.                         }
  288.                 }
  289.                 mb = mb->next;
  290.         }
  291.         return data;
  292. }
  293. int Scanner::get_match_count()
  294. {
  295.         MEMBLOCK* mb = scan;
  296.         int count = 0;
  297.         while (mb)
  298.         {
  299.                 count += mb->matches;
  300.                 mb = mb->next;
  301.         }
  302.         return count;
  303. }
  304. bool Scanner::first_scan(int pid, int _data_size, int start_val, SEARCH_CONDITION start_cond)
  305. {
  306.         data_size = _data_size;
  307.         if (scan)
  308.         {
  309.                 free_scan();
  310.         }
  311.         scan = create_scan(pid, data_size);
  312.        
  313.         if (scan)
  314.         {
  315.                 update_scan(start_cond, start_val);
  316.                 return true;
  317.         }
  318.                
  319.         else
  320.                 return false;
  321. }
  322. void Scanner::next_scan(int val, SEARCH_CONDITION condition)
  323. {
  324.         update_scan(condition, val);
  325. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4