飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 13458|回复: 50

[C/C++] 写了个Sunday算法的实现....

    [复制链接]
  • TA的每日心情
    开心
    2015-8-2 16:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2015-4-14 22:04:29 | 显示全部楼层 |阅读模式
    本帖最后由 F8LEFT 于 2015-6-11 22:03 编辑

         如题,以前就知道了Sunday这个算法,只是一直没有弄出来,所以现在有点时间了就顺便写了一下了。挺简单但是高效的一个算法,有兴趣的可以去了解一下,原理也有写明在代码中了。     

    2015.6.4 更新Hex查找,现在可以使用通配符?了,注意一下,使用通配符会降低匹配速度,选用通配符的位置值得注意一下。通常来说通配符放的越后效率越低。另外,选取的子字符串长度越长,效率越高。代码测试还不完全,可能有bug请注意。
         另外,本例代码未经优化,仅供参考。所以追求效率的同学请右上角百度一下。

    2015.6.7 更新内存搜索,用法与SundayHex函数一样,搜索自身内存数据。唔,暂时还想不到还有什么内容要更新了那么就暂时先这样吧。

    2015.6.11 内存搜索再次更新Ex版本,应该会快一点,另外修复了某些bug,此外的便是SundayF算法正式停用了,恩,估计实用价值可能不太高。


    FSunday.h
    1. #ifndef FSUNDAY_H_INCLUDED
    2. #define FSUNDAY_H_INCLUDED

    3. #include <windows.h>

    4. namespace FSunday{
    5.         int Sunday(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen);          //Sunday算法,快速查找Src中Sub的位置,下标以0为开始,失败返回-1
    6.         //消耗一定量的空间来生成位置表,来提高匹配效率
    7.         //int SundayF(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen);         //原始Sunday算法
    8.         int SundayB(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen);         //Byte
    9.         int SundayW(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen);         //Word
    10.         int SundayDW(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen);        //DWORD
    11.         int SundayHex(char* Src, unsigned long dwSrcLen, char* Sub);                              //Sub均16进制代码,以0为结束。支持通配符?, 比如 "2F3C??4D5E",长度必须为2的倍数

    12. #ifdef _WINDOWS_                                                                                                                                                //#include <windows.h>后可用
    13.         DWORD SundayMem(LPVOID lpMemAddr, unsigned int dwMemLen, char* Sub);                                //内存扫描,支持通配符,用法类似于SundayHex
    14.         DWORD SundayMemEx(LPVOID lpMemAddr, unsigned int dwMemLen, char* Sub);                                //内存扫描,加速版。不一定准确?
    15. #endif
    16. //private: 注意,永远不要手动调用下面的函数
    17.         bool __SundayHexInit__(char* Sub, unsigned long*p, char* HexSub, unsigned long dwSubLen);
    18.         int __SundayHex__(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long* p, char* HexSub, unsigned long dwSubLen);
    19.        
    20. //end
    21. };

    22. #endif // FSUNDAY_H_INCLUDED
    复制代码
    FSunday.cpp
    1. /*
    2. Sunday算法,是对字符串匹配算法的一种改进
    3. 改进的地方体现在字符串比较方法与移动方法上面
    4. 比较就不说了,就说说移动方法,有两种情况,见例子
    5. 一轮比较后,进行字符串移动
    6. 情况1:
    7. Src:1234567890
    8. Sub:  125
    9. 下一轮是用6与Sub中的字符比较,因为6不在Sub中,所以Sub的位置肯定比6大,移动如下
    10. Src:1234567890
    11. Sub:      125
    12. 恰好移动过了6,开始下一轮比较。
    13. 情况2:
    14. Src:1234567890
    15. Sub:  165
    16. 下一轮用6与Sub中的字符比较(从右端开始),因为6在Sub中,故进行右端的对齐
    17. Src:1234567890
    18. Sub:    165
    19. 对齐后,在开始下一轮比较。
    20. 这样增加了移动的效率,从而提高了匹配的速度。
    21. 本例代码的改进主要在于移动时添加了一项表来计算移动步长,从而不用每次移动时重新计算步长。
    22. */



    23. #include "FSunday.h"
    24. #include <iOStream>

    25. typedef unsigned long DWORD;
    26. typedef unsigned short WORD;
    27. typedef unsigned char BYTE;

    28. bool FHexCharValid(char c)
    29. {
    30.         if(c >= '0' && c <= '9' ||
    31.                 c >= 'A' && c <= 'F' ||
    32.                 c >= 'a' && c <= 'f' ||
    33.                 c == '?')
    34.                 return true;
    35.         else
    36.                 return false;
    37. }

    38. bool FHexDecoder(char* Dec, char* Src)
    39. {
    40.         char HighC, LowC;
    41.         DWORD dwSrcLen = strlen(Src) / 2;
    42.         int i;
    43.         for(i = 0; i < dwSrcLen; i++) {
    44.                 HighC = Src[i*2], LowC = Src[i*2+1];
    45.                 if(!FHexCharValid(LowC) || !FHexCharValid(HighC))
    46.                         return false;
    47.                 HighC -= '0';
    48.                 if(HighC > 9) HighC -= 7;
    49.                 if(HighC > 0xf) HighC -= 0x20;
    50.                 LowC -= '0';
    51.                 if(LowC > 9) LowC -= 7;
    52.                 if(LowC > 0xf) LowC -= 0x20;
    53.                 Dec[i] = (HighC<<4)|LowC;
    54.         }
    55.         return true;
    56. }

    57. int FSunday::Sunday(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen)
    58. {
    59.         if(dwSubLen == 0)
    60.                 return -1;
    61.         //if(dwSubLen <= 0xF)
    62.         //        return SundayF(Src, dwSrcLen, Sub, dwSubLen);
    63.         //if(dwSubLen <= 0xFF)
    64.         //        return SundayB(Src, dwSrcLen, Sub, dwSubLen);
    65.         if(dwSubLen <= 0xFFFF)
    66.                 return SundayW(Src, dwSrcLen, Sub, dwSubLen);
    67.         if(dwSubLen <= 0xFFFFFFFF)
    68.                 return SundayDW(Src, dwSrcLen, Sub, dwSubLen);
    69.         return -1;
    70. }

    71. /*
    72. int FSunday::SundayF(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen)
    73. {
    74.         DWORD j, k;
    75.         j = dwSubLen - 1;
    76.         bool bContinue = true;
    77.         bool bSuccess;
    78.         while (bContinue) {
    79.                 bSuccess = true;
    80.                 for(k = 0; k < dwSubLen; k++) {
    81.                         if(Src[j-k] != Sub[dwSubLen-k - 1]) {
    82.                                 bSuccess = false;
    83.                                 break;
    84.                         }
    85.                 }
    86.                 if(bSuccess)
    87.                         bContinue = false;
    88.                 else {                                          //移动j指针
    89.                         for(k = 0; k < dwSubLen; k++) {
    90.                                 if(Src[j+1] == Sub[dwSubLen-k-1]) {
    91.                                         break;
    92.                                 }
    93.                         }
    94.                         j += k+1;
    95.                 }
    96.                 if(j >= dwSrcLen)
    97.                         break;
    98.         }
    99.         if(j < dwSrcLen)
    100.                 return j-dwSubLen+1;
    101.         else
    102.                 return -1;
    103. }*/

    104. int FSunday::SundayB(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen)
    105. {
    106.         BYTE* p = new BYTE[0x100];        //table P,标志距离
    107.         DWORD i; DWORD j, k;

    108.         //    memset(p, dwSubLen, sizeof(BYTE)*0xFF);
    109.         for(i = 0; i < 0x100; i++) {
    110.                 p[i] = dwSubLen;
    111.         }

    112.         for(i = 0; i < dwSubLen; i++) {                     //扫描Sub,初始化 P 表
    113.                 p[(BYTE)Sub[i]] = dwSubLen - i - 1;             //memset
    114.         }
    115.         //开始配对字符串
    116.         //j为 Sub位置指标, k为 当前匹配位置
    117.         j = dwSubLen - 1;                                   //初始化位置为 dwSubLen - 1,匹配顺序为从右到左

    118.         bool bContinue = true;
    119.         bool bSuccess;
    120.         while(bContinue) {
    121.                 bSuccess = true;
    122.                 for(k = 0; k < dwSubLen; k++) {
    123.                         if(Src[j-k] != Sub[dwSubLen-k - 1]) {
    124.                                 bSuccess = false;
    125.                                 break;
    126.                         }
    127.                 }
    128.                 if(bSuccess)
    129.                         bContinue = false;
    130.                 else {                                          //移动j指针
    131.                         if(j < dwSrcLen - 1)
    132.                                 j += p[(BYTE)Src[j+1]] + 1;
    133.                         else j++;
    134.                 }
    135.                 if(j >= dwSrcLen)
    136.                         break;
    137.         }
    138.         delete []p;
    139.         if(j < dwSrcLen)
    140.                 return j-dwSubLen+1;
    141.         else
    142.                 return -1;
    143. }

    144. int FSunday::SundayW(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen)
    145. {
    146.         WORD* p = new WORD[0x100];        //table P,标志距离
    147.         DWORD i; DWORD j, k;

    148.         for(i = 0; i < 0x100; i++) {
    149.                 p[i] = dwSubLen;
    150.         }


    151.         for(i = 0; i < dwSubLen; i++) {                     //扫描Sub,初始化 P 表
    152.                 p[(BYTE)Sub[i]] = dwSubLen - i;
    153.         }

    154.         //开始配对字符串
    155.         //j为 Sub位置指标, k为 当前匹配位置
    156.         j = dwSubLen - 1;                                   //初始化位置为 dwSubLen - 1,匹配顺序为从右到左

    157.         bool bContinue = true;
    158.         bool bSuccess;
    159.         while(bContinue) {
    160.                 bSuccess = true;
    161.                 for(k = 0; k < dwSubLen; k++) {
    162.                         if(Src[j-k] != Sub[dwSubLen-k - 1]) {
    163.                                 bSuccess = false;
    164.                                 break;
    165.                         }
    166.                 }
    167.                 if(bSuccess)
    168.                         bContinue = false;
    169.                 else {                                          //移动j指针
    170.                         if(j < dwSrcLen-1)
    171.                                 j += p[(BYTE)Src[j+1]];
    172.                         else j++;
    173.                 }
    174.                 if(j >= dwSrcLen)
    175.                         break;
    176.         }
    177.         delete []p;
    178.         if(j < dwSrcLen)
    179.                 return j-dwSubLen+1;
    180.         else
    181.                 return -1;
    182. }

    183. int FSunday::SundayDW(char* Src, unsigned long dwSrcLen, char* Sub, unsigned long dwSubLen)
    184. {
    185.         DWORD* p = new DWORD[0x100];        //table P,标志距离
    186.         DWORD i; DWORD j, k;

    187.         for(i = 0; i < 0x100; i++) {
    188.                 p[i] = dwSubLen;
    189.         }

    190.         for(i = 0; i < dwSubLen; i++) {                     //扫描Sub,初始化 P 表
    191.                 p[(BYTE)Sub[i]] = dwSubLen - i;
    192.         }

    193.         //开始配对字符串
    194.         //j为 Sub位置指标, k为 当前匹配位置
    195.         j = dwSubLen - 1;                                   //初始化位置为 dwSubLen - 1,匹配顺序为从右到左

    196.         bool bContinue = true;
    197.         bool bSuccess;
    198.         while(bContinue) {
    199.                 bSuccess = true;
    200.                 for(k = 0; k < dwSubLen; k++) {
    201.                         if(Src[j-k] != Sub[dwSubLen-k - 1]) {
    202.                                 bSuccess = false;
    203.                                 break;
    204.                         }
    205.                 }
    206.                 if(bSuccess)
    207.                         bContinue = false;
    208.                 else {                                          //移动j指针
    209.                         if(j < dwSrcLen - 1)
    210.                                 j += p[(BYTE)Src[j+1]];
    211.                         else j++;
    212.                 }
    213.                 if(j >= dwSrcLen)
    214.                         break;
    215.         }
    216.         delete []p;
    217.         if(j < dwSrcLen)
    218.                 return j-dwSubLen+1;
    219.         else
    220.                 return -1;
    221. }

    222. int FSunday::SundayHex(char* Src, unsigned long dwSrcLen, char* Sub)
    223. {
    224.         DWORD dwSubLen = strlen(Sub);
    225.         if(dwSubLen % 2)                    //长度必须为2的倍数
    226.                 return -1;
    227.         dwSubLen /= 2;

    228.         char* HexSub = new char[dwSubLen+1];
    229.         DWORD* p = new DWORD[0x100];        //table P,标志距离
    230.         int i = -1;

    231.         if(FSunday::__SundayHexInit__(Sub, p, HexSub, dwSubLen)) {
    232.                 i = FSunday::__SundayHex__(Src, dwSrcLen, Sub, p, HexSub, dwSubLen);
    233.         }

    234.         delete []p;
    235.         delete []HexSub;
    236.         return i;
    237. }

    238. bool FSunday::__SundayHexInit__(char* Sub, DWORD*p, char* HexSub, unsigned long dwSubLen)
    239. {
    240.         if(!FHexDecoder(HexSub, Sub)) {
    241.                 return false;
    242.         }
    243.         DWORD i;

    244.         for(i = 0; i < 0x100; i++) {
    245.                 p[i] = -1;
    246.         }

    247.         int WildAddr = 0;
    248.         for(i = 0; i < dwSubLen; i++) {
    249.                 if(Sub[i*2] == '?')
    250.                         WildAddr = i;
    251.         }

    252.         for(i = WildAddr+1; i < dwSubLen; i++) {                     //扫描Sub,初始化 P 表
    253.                 p[(BYTE)HexSub[i]] = dwSubLen - i;
    254.         }

    255.         for(i = 0; i < 0x100; i++) {
    256.                 if(p[i] == -1)
    257.                         p[i] = dwSubLen - WildAddr;
    258.         }
    259.         return true;
    260. }

    261. int FSunday::__SundayHex__(char* Src, unsigned long dwSrcLen, char* Sub, DWORD* p, char* HexSub, DWORD dwSubLen)
    262. {
    263.         //开始配对字符串
    264.         //j为 Sub位置指标, k为 当前匹配位置
    265.         DWORD j, k;
    266.         j = dwSubLen - 1;                                   //初始化位置为 dwSubLen - 1,匹配顺序为从右到左

    267.         bool bContinue = true;
    268.         bool bSuccess;
    269.         while(bContinue) {
    270.                 bSuccess = true;
    271.                 for(k = 0; k < dwSubLen; k++) {
    272.                         if(Sub[(dwSubLen - k - 1)*2] != '?' && Src[j-k] != HexSub[dwSubLen-k - 1]){
    273.                                 bSuccess = false;
    274.                                 break;
    275.                         }
    276.                 }
    277.                 if(bSuccess)
    278.                         bContinue = false;
    279.                 else {                                          //移动j指针
    280.                         if(j < dwSrcLen -1)                                                        //防止j+1 >= dwSrcLen造成溢出
    281.                                 j += p[(BYTE)Src[j+1]];
    282.                         else j++;
    283.                 }
    284.                 if(j >= dwSrcLen)
    285.                         break;
    286.         }
    287.         if(j < dwSrcLen)
    288.                 return j-dwSubLen+1;
    289.         else
    290.                 return -1;
    291. }



    292. #ifdef _WINDOWS_
    293. #define PageSize 0x1000
    294.         DWORD FSunday::SundayMem(LPVOID lpMemAddr, unsigned int dwMemLen, char* Sub)
    295.         {
    296.                 DWORD dwSubLen = strlen(Sub);
    297.                 if(dwSubLen % 2)                    //长度必须为2的倍数
    298.                         return -1;
    299.                 dwSubLen /= 2;

    300.                 char* HexSub = new char[dwSubLen+1];
    301.                 DWORD* p = new DWORD[0x100];        //table P,标志距离
    302.                 int i = -1;

    303.                 if(FSunday::__SundayHexInit__(Sub, p, HexSub, dwSubLen)) {
    304.                         UINT RPage;                                                        //当前已读取的数据 * PageSize                               
    305.                         char* rPoint;
    306.                         DWORD offset = -1;

    307.                         if(RPage = (DWORD)lpMemAddr % PageSize) {
    308.                                 RPage = PageSize - RPage;
    309.                                 if(!IsBadReadPtr(lpMemAddr, 1)) {
    310.                                         rPoint = (char*)lpMemAddr;
    311.                                         offset = FSunday::__SundayHex__(rPoint, RPage, Sub, p, HexSub, dwSubLen);       
    312.                                 }
    313.                                 if(offset != -1) {
    314.                                         delete []p;
    315.                                         delete []HexSub;
    316.                                         return offset;
    317.                                 }               
    318.                         }

    319.                         for(; RPage < dwMemLen; RPage += PageSize) {
    320.                                 rPoint = (char*)((DWORD)lpMemAddr + RPage);
    321.                                 if(!IsBadReadPtr(rPoint, 1)) {
    322.                                         offset = FSunday::__SundayHex__(rPoint, PageSize, Sub, p, HexSub, dwSubLen);       
    323.                                 }
    324.                                 if(offset != -1) {
    325.                                         delete []p;
    326.                                         delete []HexSub;
    327.                                         return offset + RPage;
    328.                                 }
    329.                         }
    330.                 }
    331.                 delete []p;
    332.                 delete []HexSub;
    333.                 return -1;
    334.         }


    335.         DWORD FSunday::SundayMemEx(LPVOID lpMemAddr, unsigned int dwMemLen, char* Sub)
    336.         {
    337.                 DWORD dwSubLen = strlen(Sub);
    338.                 if(dwSubLen % 2)                    //长度必须为2的倍数
    339.                         return -1;
    340.                 dwSubLen /= 2;

    341.                 char* HexSub = new char[dwSubLen+1];
    342.                 DWORD* p = new DWORD[0x100];        //table P,标志距离
    343.                 int i = -1;

    344.                 if(FSunday::__SundayHexInit__(Sub, p, HexSub, dwSubLen)) {               
    345.                         DWORD offset = -1;

    346.                         MEMORY_BASIC_INFORMATION meminfo;
    347.                         LPVOID ptr = (LPVOID)0xFFFFFFFF;                //LoopAddr
    348.                         //①
    349.                         if(VirtualQuery(lpMemAddr, &meminfo, sizeof(MEMORY_BASIC_INFORMATION))) {
    350.                                 if(!IsBadReadPtr(lpMemAddr, 1)) {
    351.                                         ptr = (LPVOID)((DWORD)meminfo.BaseAddress + meminfo.RegionSize);
    352.                                         offset = FSunday::__SundayHex__((PCHAR)lpMemAddr, (DWORD)ptr - (DWORD)lpMemAddr, Sub, p, HexSub, dwSubLen);       
    353.                                 }
    354.                                 if(offset != -1) {
    355.                                         delete []p;
    356.                                         delete []HexSub;
    357.                                         return offset;
    358.                                 }                               
    359.                         }

    360.                         while ((DWORD)ptr - (DWORD)lpMemAddr < dwMemLen)
    361.                         {
    362.                                 if(VirtualQuery(ptr, &meminfo, sizeof(MEMORY_BASIC_INFORMATION))) {
    363.                                         if(!IsBadReadPtr(ptr, 1)) {
    364.                                                 offset = FSunday::__SundayHex__((PCHAR)meminfo.BaseAddress, meminfo.RegionSize, Sub, p, HexSub, dwSubLen);       
    365.                                         }
    366.                                         if(offset != -1) {
    367.                                                 delete []p;
    368.                                                 delete []HexSub;
    369.                                                 return offset + (DWORD)meminfo.BaseAddress - (DWORD)lpMemAddr;
    370.                                         }       
    371.                                         ptr = (LPVOID)((DWORD)meminfo.BaseAddress + meminfo.RegionSize);
    372.                                 } else {
    373.                                         break;
    374.                                 }
    375.                         }
    376.                 }
    377.                 delete []p;
    378.                 delete []HexSub;
    379.                 return -1;
    380.         }
    381. #endif // _WINDOWS_
    复制代码
    main.cpp
    1. #include <iostream>
    2. #include <string>
    3. #include <fstream>
    4. #include <time.h>

    5. #include "FSunday.h"

    6. using namespace std;
    7. //char Sub[] = "Wtf,I Fuck You!!!";
    8. char SubHex[] = "6A00E852F1FFFF8BF085F6742964A118000000817834B7000000751EFF750C56E8E6F1FFFF85C074113D80000000740A56E81EE9FFFF33C0EB028BC68B4DFC33";

    9. int memfind(const char *mem, const char *str, int sizem, int sizes);
    10. int main()
    11. {
    12.         //char Src[] = "fgjsderiodfda1546egdjkjdkfdadghh";
    13.         //char Sub[] = "fda";
    14.         /*char Src[] = {
    15.                 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0x1C, 0x65, 0x1F, 0x65, 0x1F, 0x65, 0xD1, 0x6D, 0xF1, 0xB6,
    16.                 0x5A, 0xDF, 0x16, 0xD5, 0xF1, 0xA6, 0x5F, 0x4E, 0x91, 0xDF, 0xB6, 0x51, 0xD6, 0xF5, 0x1A, 0x65,
    17.                 0xF1, 0x65, 0xBD, 0xF1, 0x65, 0x1F, 0x65, 0x16, 0xB5, 0x1F, 0xB6, 0x51, 0x65, 0x1E, 0x91, 0xDF,
    18.                 0x65, 0x89, 0x76, 0x51, 0x6F, 0x19, 0x84, 0xDF, 0x65, 0x1B, 0x6D, 0xF5, 0x1B, 0x6F, 0x8B, 0x4A,
    19.                 0xE9, 0x6F, 0x1B, 0x6D, 0xC5, 0xB1, 0x98, 0x76, 0x51, 0xD6, 0x57, 0x49, 0x8E, 0xA5, 0x61, 0xB9,
    20.                 0x81, 0x65, 0x1E, 0x41, 0xB6, 0x5F, 0x1D, 0x65, 0x1D, 0x64, 0x8D, 0x91, 0x65, 0xD1, 0x65, 0x6D
    21.         };
    22.         char Sub[] = {0x65,0x1F, 0x65};*/
    23.         ifstream ifile("F:\\新番\\xxoo.exe", ios::binary);
    24.         ifile.seekg(0, ios::end);
    25.         unsigned int szSrcLen = ifile.tellg();
    26.         ifile.seekg(0, ios::beg);
    27.         char* Src = new char[szSrcLen+1];
    28.         ifile.read(Src, szSrcLen);
    29.         ifile.close();
    30.         char Sub[] = {
    31.                         0x9C, 0xBE, 0xD5, 0xC0, 0x48, 0xC3, 0x6A, 0xC5, 0x5F, 0xC6, 0x4C, 0xC5, 0xD3, 0xC2, 0x48, 0xC0,
    32.                         0x49, 0xBE, 0x20, 0xBD, 0xFA, 0xBC, 0x95, 0xBD, 0xFA, 0xBE, 0xEC, 0xC0, 0x96, 0xC1, 0x8A, 0xBF,
    33.                         0x2C, 0xBC, 0xF7, 0xB9, 0xDC, 0xB9, 0x00, 0xBC, 0x38, 0xC0, 0x17, 0xC5, 0x1A, 0xC9, 0xB1, 0xCB,
    34.                         0x44, 0xCB, 0x82, 0xC7, 0x2C, 0xC4, 0x34, 0xC3, 0x5C, 0xC2, 0xF3, 0xC0, 0x51, 0xC0, 0xB7, 0xBF
    35.         };
    36.         char Sub2[] = "9CBED5C048C36AC55FC64CC5D3C248C049BE20BDFABC95BDFABEECC096C18ABF2CBCF7B9DCB900BC38C017C51AC9B1CB44CB82C72CC434C35CC2F3C051C0B7BF";
    37.         unsigned int dwTimeNew, dwTimeOld;
    38.         dwTimeNew = clock();
    39.         cout<<FSunday::Sunday(Src, szSrcLen, Sub, sizeof(Sub))<<endl;
    40.         dwTimeOld = clock();
    41.         cout<<"<FSunday::Sunday,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    42.         /*dwTimeNew = clock();
    43.         cout<<FSunday::SundayF(Src, szSrcLen, Sub, sizeof(Sub))<<endl;
    44.         dwTimeOld = clock();
    45.         cout<<"<FSunday::SundayF,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;*/
    46.         dwTimeNew = clock();
    47.         cout<<FSunday::SundayB(Src, szSrcLen, Sub, sizeof(Sub))<<endl;
    48.         dwTimeOld = clock();
    49.         cout<<"<FSunday::SundayB,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    50.         dwTimeNew = clock();
    51.         cout<<FSunday::SundayW(Src, szSrcLen, Sub, sizeof(Sub))<<endl;
    52.         dwTimeOld = clock();
    53.         cout<<"<FSunday::SundayW,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    54.         dwTimeNew = clock();
    55.         cout<<FSunday::SundayDW(Src, szSrcLen, Sub, sizeof(Sub))<<endl;
    56.         dwTimeOld = clock();
    57.         cout<<"<FSunday::SundayDW,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    58.         dwTimeNew = clock();
    59.         cout<<FSunday::SundayHex(Src, szSrcLen, Sub2)<<endl;
    60.         dwTimeOld = clock();
    61.         cout<<"<FSunday::SundayHex,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    62.         dwTimeNew = clock();
    63.         cout<<memfind(Src, Sub, szSrcLen, sizeof(Sub))<<endl;
    64.         dwTimeOld = clock();
    65.         cout<<"memfind,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;

    66.         dwTimeNew = clock();
    67.         cout<<(hex)<<"0x"<<FSunday::SundayMemEx((LPVOID)((DWORD)GetModuleHandle(NULL)), 0xFFFFFFFF, SubHex)<<endl;
    68.         dwTimeOld = clock();
    69.         cout<<(dec)<<"FSunday::SundayMemEx,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    70.        

    71.         dwTimeNew = clock();
    72.         cout<<(hex)<<"0x"<<FSunday::SundayMem((LPVOID)((DWORD)GetModuleHandle(NULL)), 0xFFFFFFFF, SubHex)<<endl;
    73.         dwTimeOld = clock();
    74.         cout<<(dec)<<"FSunday::SundayMem,耗时"<<dwTimeOld - dwTimeNew<<"ms"<<endl;
    75.        
    76.         delete []Src;
    77.        
    78.         cout << "Hello world!" << endl;
    79.         system("pause");
    80.         return 0;
    81. }

    82. int memfind(const char *mem, const char *str, int sizem, int sizes)
    83. {
    84.         int da,i,j;
    85.         if (sizes == 0) da = strlen(str);
    86.         else da = sizes;
    87.         for (i = 0; i < sizem; i++)
    88.         {
    89.                 for (j = 0; j < da; j ++)
    90.                 {
    91.                         if (mem[i+j] != str[j])
    92.                                 break;
    93.                 }
    94.                 if (j == da)
    95.                         return i;
    96.         }
    97.         return -1;
    98. }
    复制代码
    另外附件为vs2012工程,再次附上。

    Sunday.zip

    11.32 KB, 下载次数: 108, 下载积分: 飘云币 -2 枚

    评分

    参与人数 4威望 +48 飘云币 +44 收起 理由
    menglv + 4 能否提供完整代码?还是没有编译成功
    Dxer + 20 + 20 感谢发布原创作品!
    small-q + 20 + 20 很给力!
    smallhorse + 4 + 4 膜拜编程牛

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 1372 天

    [LV.10]以坛为家III

    发表于 2015-4-14 22:23:06 | 显示全部楼层
    F8师傅八七威武,弱弱滴问一下:这洋码子打的不错,就是不知道写的啥...............
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2021-7-17 13:00
  • 签到天数: 975 天

    [LV.10]以坛为家III

    发表于 2015-4-14 22:30:42 | 显示全部楼层
    看不懂,只有支持大神F8了,膜拜大婶
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2021-9-29 15:05
  • 签到天数: 114 天

    [LV.6]常住居民II

    发表于 2015-4-14 23:12:03 | 显示全部楼层
    本帖最后由 wx_f1Jji177 于 2015-4-14 23:26 编辑

    换换脑子,试了一下,找到首次出现的位置 QQ20150414-2@2x.png
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 20:41
  • 签到天数: 1808 天

    [LV.Master]伴坛终老

    发表于 2015-4-15 00:12:52 | 显示全部楼层
    太专业了,只能支持F8!!!
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2023-10-31 21:39
  • 签到天数: 245 天

    [LV.8]以坛为家I

    发表于 2015-4-15 00:16:22 | 显示全部楼层
    本帖最后由 heihu 于 2015-4-15 00:43 编辑

    经测试,无法查找文件内的字符串,测试文件为视频文件,大小132M,是不是不能用于文件查找?

    点评

    代码有修改,请注意  发表于 2015-4-15 12:51
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-2-26 11:14
  • 签到天数: 459 天

    [LV.9]以坛为家II

    发表于 2015-4-15 11:30:51 | 显示全部楼层
    留个脚印 等用的时候来研究 {:soso_e179:}
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2024-3-10 19:49
  • 签到天数: 473 天

    [LV.9]以坛为家II

    发表于 2015-4-15 12:48:44 | 显示全部楼层
    好像见过 不过不会。谢谢F8老师的教育
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2021-9-8 21:08
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2015-4-15 17:52:00 | 显示全部楼层
    膜拜我F8师傅..
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2023-10-31 21:39
  • 签到天数: 245 天

    [LV.8]以坛为家I

    发表于 2015-4-15 19:11:33 | 显示全部楼层
    使用F8老师的Sunday算法还是没法查找到文件字符串,使用古老的方法到是可以找到的,请F8老是指点
    1. int memfind(const char *mem, const char *str, int sizem, int sizes)
    2. {
    3. int da,i,j;
    4. if (sizes == 0) da = strlen(str);
    5. else da = sizes;
    6. for (i = 0; i < sizem; i++)
    7. {
    8. for (j = 0; j < da; j ++)
    9. {
    10. if (mem[i+j] != str[j])
    11. break;
    12. }
    13. if (j == da)
    14. return i;
    15. }
    16. return -1;
    17. }
    复制代码

    点评

    对于查找特征码,其实这个算法更加有效率。不过还可以优化一下,在asm代码里面。  发表于 2015-6-3 12:05
    测了一下,是可以对大数据文件进行操作的,请检查一下用法有没有错。还有我的代码在今天曾经修改过一次,请注意更新。 另外,关于我前面说的效率问题,还是用实际结果来表明吧: 测试文件大小124MB,Sub位置11  详情 回复 发表于 2015-4-15 20:55
    没啥好说的了,多少人为了提高算法的效率而不断的钻研。我这边因为环境问题所以测试得挺少的,所以估计有bug,跟踪一下改改就好了。 你的方法时间复杂度最坏为O(n^m),而我的最坏为O(n*m),不在同一个等级  详情 回复 发表于 2015-4-15 20:22
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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