看流星社区

 找回密码
 注册账号
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
查看: 293|回复: 1

[C/C++源码] Sunday算法实现内存快速搜索特征码(支持带问号)

[复制链接]

该用户从未签到

发表于 2020-3-22 18:49:45 | 显示全部楼层 |阅读模式

Sunday算法实现内存快速搜索特征码(支持带问号)

  1. #include<Windows.h>
  2. #include<iostream>
  3. #include<vector>
  4. #include<time.h>

  5. using namespace std;

  6. #define BLOCKMAXSIZE 409600//每次读取内存的最大大小
  7. BYTE* MemoryData;//每次将读取的内存读入这里
  8. short Next[260];

  9. //特征码转字节集
  10. WORD GetTzmArray(char* Tzm, WORD* TzmArray)
  11. {
  12.         int len = 0;
  13.         WORD TzmLength = strlen(Tzm) / 3 + 1;

  14.         for (int i = 0; i < strlen(Tzm); )//将十六进制特征码转为十进制
  15.         {
  16.                 char num[2];
  17.                 num[0] = Tzm[i++];
  18.                 num[1] = Tzm[i++];
  19.                 i++;
  20.                 if (num[0] != '?' && num[1] != '?')
  21.                 {
  22.                         int sum = 0;
  23.                         WORD a[2];
  24.                         for (int i = 0; i < 2; i++)
  25.                         {
  26.                                 if (num[i] >= '0' && num[i] <= '9')
  27.                                 {
  28.                                         a[i] = num[i] - '0';
  29.                                 }
  30.                                 else if (num[i] >= 'a' && num[i] <= 'z')
  31.                                 {
  32.                                         a[i] = num[i] - 87;
  33.                                 }
  34.                                 else if (num[i] >= 'A' && num[i] <= 'Z')
  35.                                 {
  36.                                         a[i] = num[i] - 55;
  37.                                 }

  38.                         }
  39.                         sum = a[0] * 16 + a[1];
  40.                         TzmArray[len++] = sum;
  41.                 }
  42.                 else
  43.                 {
  44.                         TzmArray[len++] = 256;
  45.                 }
  46.         }
  47.         return TzmLength;
  48. }

  49. //获取Next数组
  50. void GetNext(short* next, WORD* Tzm, WORD TzmLength)
  51. {
  52.         //特征码(字节集)的每个字节的范围在0-255(0-FF)之间,256用来表示问号,到260是为了防止越界
  53.         for (int i = 0; i < 260; i++)
  54.                 next[i] = -1;
  55.         for (int i = 0; i < TzmLength; i++)
  56.                 next[Tzm[i]] = i;
  57. }

  58. //搜索一块内存
  59. void SearchMemoryBlock(HANDLE hProcess, WORD* Tzm, WORD TzmLength, unsigned __int64 StartAddress, unsigned long size, vector<unsigned __int64>& ResultArray)
  60. {
  61.         if (!ReadProcessMemory(hProcess, (LPCVOID)StartAddress, MemoryData, size, NULL))
  62.         {
  63.                 return;
  64.         }

  65.         for (int i = 0, j, k; i < size;)
  66.         {
  67.                 j = i; k = 0;

  68.                 for (; k < TzmLength && j < size && (Tzm[k] == MemoryData[j] || Tzm[k] == 256); k++, j++);

  69.                 if (k == TzmLength)
  70.                 {
  71.                         ResultArray.push_back(StartAddress + i);
  72.                 }

  73.                 if ((i + TzmLength) >= size)
  74.                 {
  75.                         return;
  76.                 }

  77.                 int num = Next[MemoryData[i + TzmLength]];
  78.                 if (num == -1)
  79.                         i += (TzmLength - Next[256]);//如果特征码有问号,就从问号处开始匹配,如果没有就i+=-1
  80.                 else
  81.                         i += (TzmLength - num);
  82.         }
  83. }

  84. //搜索整个程序
  85. int SearchMemory(HANDLE hProcess, char* Tzm, unsigned __int64 StartAddress, unsigned __int64 EndAddress, int InitSize, vector<unsigned __int64>& ResultArray)
  86. {
  87.         int i = 0;
  88.         unsigned long BlockSize;
  89.         MEMORY_BASIC_INFORMATION mbi;

  90.         WORD TzmLength = strlen(Tzm) / 3 + 1;
  91.         WORD* TzmArray = new WORD[TzmLength];

  92.         GetTzmArray(Tzm, TzmArray);
  93.         GetNext(Next, TzmArray, TzmLength);

  94.         //初始化结果数组
  95.         ResultArray.clear();
  96.         ResultArray.reserve(InitSize);

  97.         while (VirtualQueryEx(hProcess, (LPCVOID)StartAddress, &mbi, sizeof(mbi)) != 0)
  98.         {
  99.                 //获取可读可写和可读可写可执行的内存块
  100.                 if (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE)
  101.                 {
  102.                         i = 0;
  103.                         BlockSize = mbi.RegionSize;
  104.                         //搜索这块内存
  105.                         while (BlockSize >= BLOCKMAXSIZE)
  106.                         {
  107.                                 SearchMemoryBlock(hProcess, TzmArray, TzmLength, StartAddress + (BLOCKMAXSIZE * i), BLOCKMAXSIZE, ResultArray);
  108.                                 BlockSize -= BLOCKMAXSIZE; i++;
  109.                         }
  110.                         SearchMemoryBlock(hProcess, TzmArray, TzmLength, StartAddress + (BLOCKMAXSIZE * i), BlockSize, ResultArray);

  111.                 }
  112.                 StartAddress += mbi.RegionSize;

  113.                 if (EndAddress != 0 && StartAddress > EndAddress)
  114.                 {
  115.                         return ResultArray.size();
  116.                 }
  117.         }
  118.         free(TzmArray);
  119.         return ResultArray.size();
  120. }

  121. int main()
  122. {
  123.         //初始化MemoryData大小
  124.         MemoryData = new BYTE[BLOCKMAXSIZE];

  125.         DWORD pid=0;
  126.         vector<unsigned __int64> ResultArray;
  127.        
  128.         cout << "请输入进程ID:" << endl;
  129.         cin >> pid;

  130.         //通过进程ID获取进程句柄
  131.         HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);

  132.         int start = clock();
  133.         SearchMemory(hProcess, (char*)"FF 3F FF ?? FF F2", 0x410000, 0xFFFFFFFF, 30, ResultArray);
  134.         int end = clock();

  135.         cout << "用时:" << end-start << "毫秒"<<endl;
  136.         cout << "搜索到" << ResultArray.size() << "个结果" << endl;

  137.         for (vector<unsigned __int64>::iterator it = ResultArray.begin(); it != ResultArray.end(); it++)
  138.         {
  139.                 printf("%x\n", *it);
  140.         }

  141.         return 0;
  142. }
复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2020-6-1 07:14

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表