第八篇:逆向之KMP算法

来源:互联网 发布:淘宝营销软件 编辑:程序博客网 时间:2024/04/29 12:45
版本:Release
优化选项:O2
调试工具:OD
源码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_SIZE 100  char fail[MAX_SIZE];void failure(char* pat){int n=strlen(pat);int i,j;fail[0]=-1;for(j=1;j<n;j++){i=fail[j-1];while((pat[i+1]!=pat[j])&&(i>=0))i=fail[i];if(pat[i+1]==pat[j])fail[j]=i+1;elsefail[j]=-1;}}int match(char *string,char *pat){int lenp,lens,i,j;failure(pat);i=j=0;lens=strlen(string);lenp=strlen(pat);while(i<lens&&j<lenp){if(string[i]==pat[j]){i++;j++;}elseif(j==0) i++;elsej=fail[j-1]+1;}return j==lenp?i-lenp:-1;}int main(){char s[100]="abcdsdfsdfassdfwefjkjfelkf";char a[10]="dsdf";int q=match(s,a);printf("%d",q);system("pause");return 0;}match函数的反汇编00211060 >/$  53            push    ebx00211061  |.  55            push    ebp00211062  |.  8B6C24 10     mov     ebp, dword ptr [esp+10]               ;  第二个参数00211066  |.  56            push    esi00211067  |.  57            push    edi00211068  |.  8BF5          mov     esi, ebp0021106A  |.  E8 91FFFFFF   call    failure                               ;  这个函数只有一个参数且存在esi中0021106F  |.  8B4424 14     mov     eax, dword ptr [esp+14]               ;  第一个参数00211073  |.  33D2          xor     edx, edx00211075  |.  33FF          xor     edi, edi00211077  |.  8D58 01       lea     ebx, dword ptr [eax+1]0021107A  |.  8D9B 00000000 lea     ebx, dword ptr [ebx]00211080  |>  8A08          /mov     cl, byte ptr [eax]00211082  |.  40            |inc     eax00211083  |.  84C9          |test    cl, cl00211085  |.^ 75 F9         \jnz     short 0021108000211087  |.  8BCD          mov     ecx, ebp                              ;  第二个参数传到ecx00211089  |.  2BC3          sub     eax, ebx                              ;  获得字符串长度0021108B  |.  8D71 01       lea     esi, dword ptr [ecx+1]0021108E  |.  8BFF          mov     edi, edi00211090  |>  8A19          /mov     bl, byte ptr [ecx]00211092  |.  41            |inc     ecx00211093  |.  84DB          |test    bl, bl00211095  |.^ 75 F9         \jnz     short 0021109000211097  |.  2BCE          sub     ecx, esi                              ;  获得第二个字符串长度00211099  |.  85C0          test    eax, eax                              ;  设第一个参数长度len1,第二个参数len2,则这里就是判定len1>00021109B  |.  7E 29         jle     short 002110C60021109D  |.  8D49 00       lea     ecx, dword ptr [ecx]002110A0  |>  3BD1          /cmp     edx, ecx                             ;  edx随着内部循环而改变,底部的cmp中edi随着内部循环改变,所以特别关注这2个寄存器002110A2  |.  7D 24         |jge     short 002110C8002110A4  |.  8B7424 14     |mov     esi, dword ptr [esp+14]              ;  esi=第1个参数002110A8  |.  8A1C37        |mov     bl, byte ptr [edi+esi]               ;  取第1个数组下标为edi的值002110AB  |.  3A1C2A        |cmp     bl, byte ptr [edx+ebp]               ;  与第2个数组下标为edx的值比较002110AE  |.  75 03         |jnz     short 002110B3002110B0  |.  47            |inc     edi                                  ;  下标自增002110B1  |.  EB 0E         |jmp     short 002110C1002110B3  |>  85D2          |test    edx, edx002110B5  |.  75 03         |jnz     short 002110BA002110B7  |.  47            |inc     edi002110B8  |.  EB 08         |jmp     short 002110C2002110BA  |>  0FBE92 6F3321>|movsx   edx, byte ptr [edx+21336F]           ;  edx=faile[edx]002110C1  |>  42            |inc     edx                                  ;  下标自增002110C2  |>  3BF8          |cmp     edi, eax002110C4  |.^ 7C DA         \jl      short 002110A0002110C6  |>  3BD1          cmp     edx, ecx002110C8  |>  75 09         jnz     short 002110D3                        ;  这里2种返回情况其实就是len2==edx?edi-len2:-1;002110CA  |.  2BF9          sub     edi, ecx002110CC  |.  8BC7          mov     eax, edi002110CE  |.  5F            pop     edi002110CF  |.  5E            pop     esi002110D0  |.  5D            pop     ebp002110D1  |.  5B            pop     ebx002110D2  |.  C3            retn002110D3  |>  5F            pop     edi002110D4  |.  5E            pop     esi002110D5  |.  5D            pop     ebp002110D6  |.  83C8 FF       or      eax, FFFFFFFF002110D9  |.  5B            pop     ebx002110DA  \.  C3            retn失配数组获得函数failure00211000 >/$  8BC6          mov     eax, esi                              ;  esi中存储模式串地址00211002  |.  8D50 01       lea     edx, dword ptr [eax+1]00211005  |>  8A08          /mov     cl, byte ptr [eax]00211007  |.  40            |inc     eax00211008  |.  84C9          |test    cl, cl0021100A  |.^ 75 F9         \jnz     short 002110050021100C  |.  2BC2          sub     eax, edx                              ;  上面几个指令到这里获得字符串长度0021100E  |.  57            push    edi0021100F  |.  8BF8          mov     edi, eax00211011  |.  B9 01000000   mov     ecx, 100211016  |.  3BF9          cmp     edi, ecx                              ;  if (len>1)00211018  |.  C605 70332100>mov     byte ptr [fail], 0FF                  ;  fail[0]=-10021101F  |.  7E 3D         jle     short 0021105E00211021  |>  0FBE81 6F3321>/movsx   eax, byte ptr [ecx+21336F]           ;  eax=fail[ecx-1]00211028  |.  8A1431        |mov     dl, byte ptr [ecx+esi]0021102B  |.  385406 01     |cmp     byte ptr [esi+eax+1], dl             ;  if a[eax+1]!=a[ecx]0021102F  |.  74 17         |je      short 0021104800211031  |>  85C0          |/test    eax, eax00211033  |.  7C 0D         ||jl      short 0021104200211035  |.  0FBE80 703321>||movsx   eax, byte ptr [eax+fail]0021103C  |.  385406 01     ||cmp     byte ptr [esi+eax+1], dl00211040  |.^ 75 EF         |\jnz     short 00211031                      ;  while(eax>0) eax=fail[eax];if(a[eax+1]==a[ecx]) break;00211042  |>  385406 01     |cmp     byte ptr [esi+eax+1], dl00211046  |.  75 0A         |jnz     short 0021105200211048  |>  FEC0          |inc     al0021104A  |.  8881 70332100 |mov     byte ptr [ecx+fail], al              ;  fail[ecx]=eax+100211050  |.  EB 07         |jmp     short 0021105900211052  |>  C681 70332100>|mov     byte ptr [ecx+fail], 0FF             ;  fail[ecx]=-100211059  |>  41            |inc     ecx0021105A  |.  3BCF          |cmp     ecx, edi0021105C  |.^ 7C C3         \jl      short 00211021                       ;  for(ecx=1;ecx<len;ecx++)0021105E  |>  5F            pop     edi0021105F  \.  C3            retn