VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 7211|回复: 20

[原创] 快速查找内存算法

[复制链接]
发表于 2013-12-22 18:02:25 | 显示全部楼层 |阅读模式
本帖最后由 bxc1995 于 2013-12-22 18:06 编辑

最近写了个快速查找内存的东西,发出来交流下,顺便求优化。

  1. #define ASM __declspec (naked)

  2. typedef struct _CMP_BYTE
  3. {
  4.     bool          IsValid;      //1字节
  5.     BYTE        Data;        //1字节
  6. } CMP_BYTE, *PCMP_BYTE;

  7. ASM UINT WINAPI FindMemory(PBYTE destAddr,UINT destSize,PCMP_BYTE pCB,UINT cbCount,BOOL Absolute)
  8. {
  9.     __asm
  10.     {
  11.         push ebp
  12.         mov ebp,esp
  13.         push ebx
  14.         push esi
  15.         push edi
  16.         cmp destAddr,0                   //判断参数是否为NULL
  17.         je BackErr
  18.         cmp destSize,0
  19.         je BackErr
  20.         cmp pCB,0
  21.         je BackErr
  22.         cmp cbCount,0
  23.         je BackErr
  24.         mov eax,cbCount
  25.         cmp eax,destSize
  26.         ja BackErr
  27.         push eax                        //i
  28.         mov edi,destAddr
  29. dLoop:
  30.         mov esi,pCB
  31.         xor eax,eax
  32.         mov [ebp-0x10],eax
  33. sLoop:
  34.         mov ax,word ptr [esi]           //取CMP_BYTE
  35.         test al,al                      //判断IsValid
  36.         je sNext
  37.         mov ebx,[ebp-0x10]
  38.         cmp ah,byte ptr [edi+ebx]
  39.         jne dNext

  40. sNext:
  41.         inc dword ptr [ebp-0x10]        //自加计数
  42.         add esi,0x02                    //自加结构指针
  43.         mov eax,dword ptr [ebp-0x10]
  44.         cmp eax,cbCount                 //比较cbCount和计数
  45.         jb sLoop                        //计数 < cbCount 跳转
  46.         mov eax,Absolute
  47.         test eax,eax
  48.         mov eax,edi
  49.         jne Return                       
  50.         sub eax,destAddr
  51.         jmp Return
  52. dNext:
  53.         inc edi                         //srcAddr++
  54.         mov eax,destSize                 
  55.         sub eax,cbCount                 //eax = srcSize - cbCount
  56.         add eax,destAddr
  57.         cmp edi,eax                     //比较
  58.         jbe dLoop   

  59. BackErr:
  60.         xor eax,eax
  61.         dec eax
  62. Return:
  63.         pop ecx
  64.         pop edi
  65.         pop esi
  66.         pop ebx
  67.         mov esp,ebp
  68.         pop ebp
  69.         retn 0x14
  70.     }
  71. }
复制代码
CMP_BYTE结构是用于模糊搜索内存用的。比如查找55 ?? 8B 00 22 ?? 33
像"??"这种未知的字节在CMP_BYTE结构里IsValid就是FALSE。

参数说明:
PBYTE destAddr         欲查找的内存基址
UINT destSize             内存大小
PCMP_BYTE pCB        CMP_BYTE结构指针
UINT cbCount            CMP_BYTE结构数量
BOOL Absolute           是否返回绝对地址

点评

非常感谢  发表于 2015-1-8 19:40
不错,不过这个用C/C++来写也差不到哪里去……  发表于 2013-12-22 20:36

本帖被以下淘专辑推荐:

发表于 2013-12-23 19:26:35 | 显示全部楼层
绝对没有sunday算法快……

点评

sunday不及KMP稳定吧...虽然我是HASH党...  发表于 2015-4-21 16:52
你那个又不支持通配符匹配  发表于 2015-4-21 13:18
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-23 20:34:29 | 显示全部楼层
JuncoJet 发表于 2013-12-23 19:26
绝对没有sunday算法快……

恩,这个每次只针对1Byte比较,对于连续的内存的确有点慢,下回有空在写个
回复 支持 反对

使用道具 举报

发表于 2015-4-21 11:55:11 | 显示全部楼层
怎么没有一个vb实例看看呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-21 14:37:30 | 显示全部楼层
本帖最后由 bxc1995 于 2015-4-21 14:44 编辑
menglv 发表于 2015-4-21 11:55
怎么没有一个vb实例看看呢?


用C++写成dll,VB调用就可以了。
destAddr和destSize就不用说明了吧。
pCB是CMP_BYTE结构的数组。cbCount是数组的个数。Absolute用来是否返回绝对值用的。

比如要从0x00401000开始,检索0x2000长度的区域中是否包含55 ?? 8B 00 22 ?? 33的数据:
  1. CMP_BYTE cb[7] =
  2. {
  3.   {TRUE, 0x55},
  4.   {FALSE, 0},
  5.   {TRUE, 0x8B},
  6.   {TRUE, 0x00},
  7.   {TRUE, 0x22},
  8.   {FALSE, 0},
  9.   {TRUE, 0x33}
  10. };

  11. FindMemory(0x00401000, 0x2000, cb, 7, FALSE);
复制代码
因为bool类型在VB里是2字节,所以要用byte代替。
回复 支持 反对

使用道具 举报

发表于 2015-4-21 22:28:12 来自手机 | 显示全部楼层
不会c语言,能否帮我编译一个,我来扣代码。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-22 01:23:31 | 显示全部楼层
本帖最后由 bxc1995 于 2015-4-22 01:28 编辑
menglv 发表于 2015-4-21 22:28
不会c语言,能否帮我编译一个,我来扣代码。




函数声明:

  1. Public Type CMP_BYTE
  2.   blValid as Byte
  3.   btData as Byte
  4. End Type

  5. Public Declare Function FindMemory Lib "findmem32" (ByVal destAddr As Long, ByVal destSize As Long, ByRef lpCB As CMP_BYTE, ByVal cbCount as long, ByVal Absolute as long) As Long
  6. '或者
  7. Public Declare Function FindMemory Lib "findmem32" (ByRef destAddr As Any, ByVal destSize As Long, ByRef lpCB As CMP_BYTE, ByVal cbCount as long, ByVal Absolute as long) As Long
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

点评

好像知道怎么调用了,待会试试  发表于 2015-4-22 13:40
直接给一个调用的测试例子吧,看看速度如何,我的汇编已经写出来了。  发表于 2015-4-22 13:38
回复 支持 反对

使用道具 举报

发表于 2015-4-22 20:22:26 | 显示全部楼层
本帖最后由 menglv 于 2015-4-22 20:42 编辑

好像vb还是调用不起来,谁能用vb调用一下看看,我想比较一下速度。
vc的程序调用的例子也可以,我要编译好的程序,谢谢,c语言真不懂。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-22 21:53:03 | 显示全部楼层
menglv 发表于 2015-4-22 20:22
好像vb还是调用不起来,谁能用vb调用一下看看,我想比较一下速度。
vc的程序调用的例子也可以,我要编译好 ...

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2015-4-23 09:30:59 | 显示全部楼层
本帖最后由 menglv 于 2015-4-23 09:34 编辑


好像算法有问题,只能找到偶数位的情况,而且三位也找不到。
查找6578会找不到!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-7-5 12:38

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表