丁侦球 发表于 2024-3-3 09:25:01

C++实现的完整aobscan特征码搜索,采用Sunday算法,速度极快。

C++实现的完整aobscan特征码搜索,采用Sunday算法,速度极快。

完整的aobscan实现,我在搜索部分使用了一个高速搜索算法。

#include <windows.h>
#include <Psapi.h>
#include <stdio.h>
#include <time.h>

/*这是一个很低效的算法*/
unsigned char *memstr(char * dst , int dst_len, char *src , int src_len )
{
    int i;
    char *cp = src;
    if (src_len < dst_len)
    {
      return NULL;
    }
    for (i = 0; i <= src_len - dst_len; i++)
    {
      if (memcmp(cp , dst , dst_len) == 0)
      {
            return (unsigned char *)cp;
      }
      cp++;
    }
    return   NULL;
}

/*sunday算法*/
#define MAX_CHAR_SIZE 257
long *setCharStep(const unsigned char *subStr, long subStrLen)
{
    long i;
    static long charStep;
    for (i = 0; i < MAX_CHAR_SIZE; i++)
      charStep = subStrLen + 1;
    for (i = 0; i < subStrLen; i++)
    {
      charStep[(unsigned char)subStr] = subStrLen - i;
    }
    return charStep;
}
/*
   算法核心思想,从左向右匹配,遇到不匹配的看大串中匹配范围之外的右侧第一个字符在小串中的最右位置
   根据事先计算好的移动步长移动大串指针,直到匹配
*/
long sundaySearch(const unsigned char *mainStr, const unsigned char *subStr, long *charStep, long mainStrLen, int subStrLen)
{
    long main_i = 0;
    long sub_j = 0;
    while (main_i < mainStrLen)
    {
      //保存大串每次开始匹配的起始位置,便于移动指针
      long tem = main_i;
      while (sub_j < subStrLen)
      {
            if (mainStr == subStr)
            {
                main_i++;
                sub_j++;
                continue;
            }
            else
            {
                //如果匹配范围外已经找不到右侧第一个字符,则匹配失败
                if (tem + subStrLen > mainStrLen)
                  return -1;
                //否则 移动步长 重新匹配
                unsigned char firstRightChar = mainStr;
                main_i += charStep[(unsigned char)firstRightChar];
                sub_j = 0;
                break; //退出本次失败匹配 重新一轮匹配
            }
      }
      if (sub_j == subStrLen)
            return main_i - subStrLen;
    }
    return -1;
}



unsigned char getHex(unsigned char hex)
{
    if (hex >= '0' && hex <= '9') return hex - '0';
    if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10;
    if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10;
    return 0;
}
int GetHexValue(char *src)
{
    int i, j, flag;
    static char temp;
    for (i = 0, j = 0; src != 0; i++)
    {
      if ((src <= 'F' && src >= 'A') || (src <= 'f' && src >= 'a') || (src <= '9' && src >= '0'))
      {
            if (src != ' ')
            {
                temp = src;
            }
      }
    }
    temp = 0;
    src = 0;
    for (i = 0, j = 0, flag = 1; temp != 0; i++)
    {

      char ch = getHex(temp);
      if (ch != -1)
      {
            if (flag == 1) src = ch << 4;
            else src += ch;
            flag *= -1;
      }
    }
    src = 0;
    return j;
}
DWORD ReadPage(HANDLE m_hProcess, DWORD dwBaseAddr, char* Value)
{
    //读取1页内存
    BYTE arBytes;
    if (!::ReadProcessMemory(m_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL))
    {
      //此页不可读
      return (DWORD) - 1;
    }
    else
    {
      //
      //unsigned char key[] = {0x80, 0x7f, 0x49, 0x00};
      unsigned char Value2;
      strcpy((char*)Value2, Value);
      int len = GetHexValue((char*)Value2);
      //getchar();
      //注释这两行是低效的算法
      //char key[] = {0x80, 0x7f, 0x49, 0x00};
      //int len = 4;
      //if (memstr(key, len, (char*)arBytes, 4096) != 0) return memstr(key, len, (char*)arBytes, 4096) - (unsigned char*)arBytes;
      //else return -1;

      //开始sunday算法
      long *charStep = setCharStep(Value2, len);
      return sundaySearch(arBytes, Value2, charStep, 4096, len);
    }
    return (DWORD) - 1;    //不会执行到此处
}

**** Hidden Message *****
页: [1]
查看完整版本: C++实现的完整aobscan特征码搜索,采用Sunday算法,速度极快。