非常精妙,如果是你自己写的话,真的该称你一声大神,我自己都自愧不如了。今晚仔细看了一下,这个算法内部很牛逼。真怀疑我是不是应该继续再搞挂了。
- int __cdecl Find(int Begin, int Limit, int pdata, int length)
- Begin:节区的起始地址,Limit节区去除一个length后的大小
- pdata:需要搜索的内容(应该只可以为字符串),length:字符串的长度。
- {
- unsigned int offset;
- int readchar;
- int rest;
- signed int nowStart;
- int restspacesize;
- int DataRVA;
- int Buffoffset;
- int result;
- if ( !Begin || !pdata ) // 如果基址和缓冲区为空
- goto Exit;
- memset32(buffer, length, 256); // #define memset32(dst,val,count) \
- // __asm mov edi,dword ptr[dst] \
- // __asm mov eax,dword ptr[val] \
- // __asm mov ecx,dword ptr[count] \
- // __asm rep stosd
- //由于每个字节码的最大数为0xFF,所以下方的index绝不会越界
- offset = 0;
- if ( length )
- {
- do
- {
- readchar = *(offset + pdata); // 获取offset所指向的缓冲区的字符
- rest = length - offset++ - 1; // 取完字符后每次递增偏移量,并且求出缓冲区剩余长度
- buffer[readchar] = rest; // 将剩余长度放入字符下表的缓冲区
- } // 此时缓冲区内只剩下以字符为下标的剩余长度列表
- while ( offset < length ); // 其实也就是求个取反排序
- }
- nowStart = 1; // 本次搜索的起始RVA
- restspacesize = Limit - length; // firstrest等于这次搜索后的剩余搜索空间大小
- if ( (Limit - length) >= 1 ) // 如果所选区段的长度大于搜索内容的长度,则搜索。
- {
- while ( 1 ) // 开始搜索
- {
- DataRVA = nowStart - 1;
- Buffoffset = nowStart - 1 - nowStart; // Buffoffset = -1
- if ( Buffoffset + 1 < length )
- {
- do
- {
- if ( *(DataRVA + Begin) != *(Buffoffset + pdata + 1) )
- break;
- ++DataRVA; // 如果不对称,则搜索的指针下移一个字节
- Buffoffset = DataRVA - nowStart; // 下一个RVA减去起始RVA,得到对应的数组元素下表
- }
- while ( DataRVA - nowStart + 1 < length );// 如果本次的RVA未达length末尾,则继续搜索
- restspacesize = Limit - length; // 到这里已搜索完毕一次字符串空间,再次缩短剩余搜索空间大小
- }
- if ( DataRVA - nowStart + 1 == length ) // 如果RVA已经到达length长度则返回结果
- break;
- nowStart += buffer[*(nowStart + Begin + length - 1)] + 1;// 这里根据上面的剩余字节数取长度为模的补数为下一次上搜索的起始地址,哈哈,此处不好说,不可说。
- if ( nowStart > restspacesize ) // 如果下一次搜索位置大于剩余可搜索空间的话,返回了。结果为-1
- goto Exit;
- }
- result = nowStart - 1;
- }
- else
- {
- Exit: result = -2;
- }
- return result;
- }
[ 此帖被sprees在2013-12-02 01:18重新编辑 ]