逆向之hash算法 ,逆向之选择排序 ,逆向之快速排序

来源:互联网 发布:javascript在线看 编辑:程序博客网 时间:2024/05/21 17:48

逆向之hash算法 

此算法为hash中比较简单的线性探测法,代码优化选项OD(无)
顺便说句,这些算法实现大多会拿我在学数据结构的时候自己实现的或者书上的,所以风格编码肯定不能和百度到的那些比,权当练练手,不过物尽其用吧,也不枉费当时特意把这些代码保存下来,嘿嘿
以下为C的算法代码:
[cpp] view plaincopyprint?
  1. //线性探测   
  2. #include <stdio.h>   
  3. #include <stdlib.h>   
  4. #include <time.h>   
  5. #include <string.h>   
  6.   
  7. #define MAX_SIZE 13   
  8. #define b 13   
  9.   
  10. char *ht[MAX_SIZE];  
  11.   
  12. int stringtoint(char *key)  
  13. {  
  14.     int number;  
  15.     for(number=0;*key;key++)  
  16.         number+=*key;  
  17.     return number;  
  18. }  
  19.   
  20. int f(int k)  
  21. {  
  22.     return k%b;  
  23. }  
  24.   
  25. char* search(char* key)  
  26. {  
  27.     int current,homebucket;  
  28.     homebucket=f(stringtoint(key));  
  29.     for(current=homebucket;ht[current]&&strcmp(ht[current],key);)  
  30.     {  
  31.         current=(current+1)%b;  
  32.         if(current==homebucket)  
  33.             return NULL;  
  34.     }  
  35.     if(strcmp(ht[current],key)==0)  
  36.         return ht[current];  
  37.     return NULL;  
  38. }  
  39.   
  40. void insert(char *key)  
  41. {  
  42.     int homebucket,current;  
  43.     homebucket=f(stringtoint(key));  
  44.     for(current=homebucket;ht[current];)  
  45.     {  
  46.         current=(current+1)%b;  
  47.         if(current==homebucket)  
  48.             return;  
  49.     }  
  50.     ht[current]=(char*)malloc(sizeof(*key));  
  51.     strcpy(ht[current],key);  
  52. }  
  53.   
  54. int main()  
  55. {  
  56.     int i;  
  57.     char word[MAX_SIZE];  
  58.     for(i=0;i<MAX_SIZE;i++)  
  59.     {  
  60.         ht[i]=NULL;  
  61.     }  
  62.     for(i=0;i<3;i++)  
  63.     {  
  64.         scanf("%s",word);  
  65.         insert(word);  
  66.         fflush(stdin);  
  67.     }  
  68.     printf("search:");  
  69.     scanf("%s",word);  
  70.   
  71.     printf("%s\n",search(word));  
  72.     for(i=0;i<MAX_SIZE;i++)  
  73.         printf("%s\n",ht[i]);  
  74.     system("pause");  
  75.     return 0;  
  76. }  

[cpp] view plaincopyprint?
  1. 惯例,OD跟踪,往下翻,有个jmp main指令,很明显就是它啦,F7跟进去,显示如下代码  
  2. 01381170 >/$  83EC 18       sub     esp, 18                                 ;  首先分配临时存储空间  
  3. 01381173  |.  A1 00303801   mov     eax, dword ptr [__security_cookie]  
  4. 01381178  |.  33C4          xor     eax, esp  
  5. 0138117A  |.  894424 14     mov     dword ptr [esp+14], eax  
  6. 0138117E  |.  33C0          xor     eax, eax  
  7. 01381180  |.  53            push    ebx  
  8. 01381181  |.  8B1D A8203801 mov     ebx, dword ptr [<&MSVCR90.fflush>]      ;  MSVCR90.fflush  
  9. 01381187  |.  55            push    ebp  
  10. 01381188  |.  8B2D AC203801 mov     ebp, dword ptr [<&MSVCR90.__iob_func>]  ;  MSVCR90.__p__iob  
  11. 0138118E  |.  56            push    esi  
  12. 0138118F  |.  8B35 B0203801 mov     esi, dword ptr [<&MSVCR90.scanf>]       ;  MSVCR90.scanf  
  13. 01381195  |.  A3 6C333801   mov     dword ptr [ht], eax                     ;  初始化全局变量的指针数组  
  14. .....................  
  15. ......................  
  16. 013811DE  |.  57            push    edi  
  17. 013811DF  |.  90            nop  
  18. 013811E0  |>  8D4424 14     /lea     eax, dword ptr [esp+14]                ;  eax指向分配存储空间中最后一个变量  
  19. 013811E4  |.  50            |push    eax  
  20. 013811E5  |.  68 04213801   |push    01382104                               ;  ASCII "%s"  
  21. 013811EA  |.  FFD6          |call    esi                                    ;  scanf("%s",esp+14)  
  22. 013811EC  |.  8D7C24 1C     |lea     edi, dword ptr [esp+1C]                ;  其实这个esp+1c就是上面那个esp+14,详细可以查查C的调用约定  
  23. 013811F0  |.  E8 FBFEFFFF   |call    insert                                 ;  额。。这个我们先不管,先把主函数整体给反汇编出来  
  24. 013811F5  |.  FFD5          |call    ebp                                    ;  fflush  
  25. 013811F7  |.  50            |push    eax  
  26. 013811F8  |.  FFD3          |call    ebx  
  27. 013811FA  |.  83C4 0C       |add     esp, 0C                                ;  堆栈平衡跑这来了,服了  
  28. 013811FD  |.  836C24 10 01  |sub     dword ptr [esp+10], 1                  ;  其实就是上面那个mov dword ptr [esp+c],3,看到没  
  29. 01381202  |.^ 75 DC         \jnz     short 013811E0                         ;  if [esp+10]==1 break;  
  30. 01381204  |.  8B1D A0203801 mov     ebx, dword ptr [<&MSVCR90.printf>]      ;  MSVCR90.printf  
  31. 0138120A  |.  68 08213801   push    01382108                                ; /format = "search:"  
  32. 0138120F  |.  FFD3          call    ebx                                     ; \printf  
  33. 01381211  |.  8BCF          mov     ecx, edi  
  34. 01381213  |.  51            push    ecx  
  35. 01381214  |.  68 04213801   push    01382104                                ;  ASCII "%s"  
  36. 01381219  |.  FFD6          call    esi                                     ;  scanf调用  
  37. 0138121B  |.  E8 E0FDFFFF   call    search  
  38. 01381220  |.  50            push    eax                                     ;  从这里可以看出eax的返回值是个字符串指针  
  39. 01381221  |.  68 10213801   push    01382110                                ;  ASCII "%s",LF  
  40. 01381226  |.  FFD3          call    ebx  
  41. 01381228  |.  83C4 14       add     esp, 14                                 ;  还是平衡堆栈  
  42. 0138122B  |.  BE 6C333801   mov     esi, offset ht                          ;  ht是个全局变量  
  43. 01381230  |.  5F            pop     edi  
  44. 01381231  |>  8B16          /mov     edx, dword ptr [esi]  
  45. 01381233  |.  52            |push    edx  
  46. 01381234  |.  68 10213801   |push    01382110                               ;  ASCII "%s",LF  
  47. 01381239  |.  FFD3          |call    ebx  
  48. 0138123B  |.  83C6 04       |add     esi, 4                                 ;  由此可见全局变量是每个元素4字节的数组  
  49. 0138123E  |.  83C4 08       |add     esp, 8  
  50. 01381241  |.  81FE A0333801 |cmp     esi, offset _adjust_fdiv  
  51. 01381247  |.^ 7C E8         \jl      short 01381231  
  52. 01381249  |.  68 14213801   push    01382114                                ; /command = "pause"  
  53. 0138124E  |.  FF15 A4203801 call    dword ptr [<&MSVCR90.system>]           ; \system  
  54. 01381254  |.  8B4C24 24     mov     ecx, dword ptr [esp+24]  
  55. 01381258  |.  83C4 04       add     esp, 4  
  56. 0138125B  |.  5E            pop     esi  
  57. 0138125C  |.  5D            pop     ebp  
  58. 0138125D  |.  5B            pop     ebx  
  59. 0138125E  |.  33CC          xor     ecx, esp  
  60. 01381260  |.  33C0          xor     eax, eax  
  61. 01381262  |.  E8 04000000   call    __security_check_cookie  
  62. 01381267  |.  83C4 18       add     esp, 18  
  63. 0138126A  \.  C3            retn  
  64.   
  65. 下面是insert函数,简单的将字符串每个字节相加,得到的数再取余数,然后看能不能插入hash表,不过有个地方代码很古怪,作用肯定是求余啦,只是。。。  
  66. 012810F0 >/$  8A07          mov     al, byte ptr [edi]                      ;  这里edi就是指向输入的字符啦  
  67. 012810F2  |.  33C9          xor     ecx, ecx  
  68. 012810F4  |.  8BD7          mov     edx, edi                                ;  随时关注edi的动向哦~~~  
  69. 012810F6  |.  84C0          test    al, al  
  70. 012810F8  |.  74 12         je      short 0128110C  
  71. 012810FA  |.  8D9B 00000000 lea     ebx, dword ptr [ebx]                    ;  前面用到的寄存器在这都有效。。。  
  72. 01281100  |>  0FBEC0        /movsx   eax, al                                ;  movsx:此乃带符号扩展  
  73. 01281103  |.  42            |inc     edx  
  74. 01281104  |.  03C8          |add     ecx, eax  
  75. 01281106  |.  8A02          |mov     al, byte ptr [edx]  
  76. 01281108  |.  84C0          |test    al, al  
  77. 0128110A  |.^ 75 F4         \jnz     short 01281100                         ;  仔细分析这一段代码就是把每个字符的Ascii数值相加放入ecx  
  78. 0128110C  |>  B8 4FECC44E   mov     eax, 4EC4EC4F                           ;  除法,取模运算的优化,定点表示法(即4EC4EC4F为除数的倒数小数位的1倍或2的n次方倍的16进制表示)  
  79. 01281111  |.  F7E9          imul    ecx                                ;指令执行后eax为商的小数部分,edx为商的整数部分(可能是2的n次方倍)  
  80. 01281113  |.  C1FA 02       sar     edx, 2                                  ;  带符号右移4位,由此可以看出商为真正的商的4倍  
  81. 01281116  |.  8BC2          mov     eax, edx                                
  82. 01281118  |.  C1E8 1F       shr     eax, 1F                                ;取符号位(适应负数情况)  
  83. 0128111B  |.  03C2          add     eax, edx                               ;加上符号位  
  84. 0128111D  |.  6BC0 0D       imul    eax, eax, 0D                            ;  三操作数乘法指令,以前还真没见过 eax=eax*0D 如是  
  85. 01281120  |.  2BC8          sub     ecx, eax                                     ;  执行后ecx即为余数,(x%y=x-(x/y)*y)   ,还不明白可以去看百度文库的代码逆向文章其中有除法,取模的优化详解~~  
  86. 01281122  |.  833C8D 6C3328>cmp     dword ptr [ecx*4+ht], 0  
  87. 0128112A  |.  56            push    esi  
  88. 0128112B  |.  8BF1          mov     esi, ecx  
  89. 0128112D  |.  74 1C         je      short 0128114B                          ;  如果为NULL  
  90. 0128112F  |.  90            nop  
  91. 01281130  |>  8D46 01       /lea     eax, dword ptr [esi+1]                 ;  ht数组的下一个下标  
  92. 01281133  |.  99            |cdq  
  93. 01281134  |.  BE 0D000000   |mov     esi, 0D  
  94. 01281139  |.  F7FE          |idiv    esi  
  95. 0128113B  |.  8BF2          |mov     esi, edx  
  96. 0128113D  |.  3BF1          |cmp     esi, ecx  
  97. 0128113F  |.  74 2A         |je      short 0128116B                         ;  插入失败  
  98. 01281141  |.  833CB5 6C3328>|cmp     dword ptr [esi*4+ht], 0  
  99. 01281149  |.^ 75 E5         \jnz     short 01281130                         ;  嗯,这里还是没有空位,继续找吧  
  100. 0128114B  |>  6A 01         push    1                                       ; /size = 1  
  101. 0128114D  |.  FF15 B4202801 call    dword ptr [<&MSVCR90.malloc>]           ; \malloc  
  102. 01281153  |.  83C4 04       add     esp, 4  
  103. 01281156  |.  8904B5 6C3328>mov     dword ptr [esi*4+ht], eax  
  104. 0128115D  |.  8BCF          mov     ecx, edi  
  105. 0128115F  |.  8BD0          mov     edx, eax  
  106. 01281161  |>  8A01          /mov     al, byte ptr [ecx]                     ;  简单地将字符拷贝到新分配的内存中  
  107. 01281163  |.  8802          |mov     byte ptr [edx], al  
  108. 01281165  |.  41            |inc     ecx  
  109. 01281166  |.  42            |inc     edx  
  110. 01281167  |.  84C0          |test    al, al  
  111. 01281169  |.^ 75 F6         \jnz     short 01281161  
  112. 0128116B  |>  5E            pop     esi  
  113. 0128116C  \.  C3            retn  
  114.   
  115. 这是search函数  
  116. 00241000  /$  8A07          mov     al, byte ptr [edi]               ;  此处的edi就是那个存字符的缓冲区也是要搜索的  
  117. 00241002  |.  33C9          xor     ecx, ecx  
  118. 00241004  |.  8BD7          mov     edx, edi  
  119. 00241006  |.  84C0          test    al, al  
  120. 00241008  |.  74 12         je      short 0024101C                   ;  如果字符串结尾  
  121. 0024100A  |.  8D9B 00000000 lea     ebx, dword ptr [ebx]             ;  此处是printf函数地址,可以在主函数找到。。顺便感叹下这寄存器窜的  
  122. 00241010  |>  0FBEC0        /movsx   eax, al                         ;  下面这个循环稍微看下就知道是字符串数值相加啦  
  123. 00241013  |.  42            |inc     edx  
  124. 00241014  |.  03C8          |add     ecx, eax  
  125. 00241016  |.  8A02          |mov     al, byte ptr [edx]  
  126. 00241018  |.  84C0          |test    al, al  
  127. 0024101A  |.^ 75 F4         \jnz     short 00241010  
  128. 0024101C  |>  B8 4FECC44E   mov     eax, 4EC4EC4F                    ;依然是个取余操作,详情参考前面注释  
  129. 00241021  |.  F7E9          imul    ecx  
  130. 00241023  |.  C1FA 02       sar     edx, 2  
  131. 00241026  |.  8BC2          mov     eax, edx  
  132. 00241028  |.  C1E8 1F       shr     eax, 1F  
  133. 0024102B  |.  03C2          add     eax, edx  
  134. 0024102D  |.  6BC0 0D       imul    eax, eax, 0D  
  135. 00241030  |.  2BC8          sub     ecx, eax                         ;  这里得到了余数  
  136. 00241032  |.  53            push    ebx  
  137. 00241033  |.  56            push    esi  
  138. 00241034  |.  8BF1          mov     esi, ecx  
  139. 00241036  |.  8D04B5 000000>lea     eax, dword ptr [esi*4]  
  140. 0024103D  |.  83B8 6C332400>cmp     dword ptr [eax+24336C], 0        ;  看全局数组某个位置是否为空  
  141. 00241044  |.  8BD6          mov     edx, esi  
  142. 00241046  |.  74 58         je      short 002410A0                   ;  下面循环貌似有点复杂,先看发现空位后的操作  
  143. 00241048  |.  EB 06         jmp     short 00241050  
  144. 0024104A  |   8D9B 00000000 lea     ebx, dword ptr [ebx]  
  145. 00241050  |>  8B80 6C332400 /mov     eax, dword ptr [eax+24336C]     ;  搜索到的字符串地址  
  146. 00241056  |.  8BCF          |mov     ecx, edi                        ;  字符串寄存器又换成ecx了  
  147. 00241058  |>  8A18          |/mov     bl, byte ptr [eax]  
  148. 0024105A  |.  3A19          ||cmp     bl, byte ptr [ecx]  
  149. 0024105C  |.  75 1A         ||jnz     short 00241078  
  150. 0024105E  |.  84DB          ||test    bl, bl  
  151. 00241060  |.  74 12         ||je      short 00241074                 ;  发现相等并等于0字符后跳出并检查是否为所求字符串  
  152. 00241062  |.  8A58 01       ||mov     bl, byte ptr [eax+1]  
  153. 00241065  |.  3A59 01       ||cmp     bl, byte ptr [ecx+1]  
  154. 00241068  |.  75 0E         ||jnz     short 00241078  
  155. 0024106A  |.  83C0 02       ||add     eax, 2  
  156. 0024106D  |.  83C1 02       ||add     ecx, 2  
  157. 00241070  |.  84DB          ||test    bl, bl  
  158. 00241072  |.^ 75 E4         |\jnz     short 00241058  
  159. 00241074  |>  33C0          |xor     eax, eax  
  160. 00241076  |.  EB 05         |jmp     short 0024107D  
  161. 00241078  |>  1BC0          |sbb     eax, eax  
  162. 0024107A  |.  83D8 FF       |sbb     eax, -1  
  163. 0024107D  |>  85C0          |test    eax, eax  
  164. 0024107F  |.  74 1F         |je      short 002410A0  
  165. 00241081  |.  8D42 01       |lea     eax, dword ptr [edx+1]          ;  下标后移一个位置后取余  
  166. 00241084  |.  99            |cdq  
  167. 00241085  |.  B9 0D000000   |mov     ecx, 0D  
  168. 0024108A  |.  F7F9          |idiv    ecx  
  169. 0024108C  |.  3BD6          |cmp     edx, esi  
  170. 0024108E  |.  74 49         |je      short 002410D9                  ;  意思就是取余后仍然等于原来那个位置,那么查找失败返回0  
  171. 00241090  |.  8D0495 000000>|lea     eax, dword ptr [edx*4]  
  172. 00241097  |.  83B8 6C332400>|cmp     dword ptr [eax+24336C], 0  
  173. 0024109E  |.^ 75 B0         \jnz     short 00241050                  ;  发现下一个非空位,继续搜索  
  174. 002410A0  |>  8B3495 6C3324>mov     esi, dword ptr [edx*4+24336C]  
  175. 002410A7  |.  8BCF          mov     ecx, edi                         ;  之后ecx指向搜索的字符串  
  176. 002410A9  |.  8BC6          mov     eax, esi  
  177. 002410AB  |.  EB 03         jmp     short 002410B0                   ;  跳转之后的基本都是strcmp函数的代码,看来这个库函数是汇编实现还是内联的。。效率确实没得说  
  178. 002410AD  |   8D49 00       lea     ecx, dword ptr [ecx]  
  179. 002410B0  |>  8A10          /mov     dl, byte ptr [eax]  
  180. 002410B2  |.  3A11          |cmp     dl, byte ptr [ecx]  
  181. 002410B4  |.  75 28         |jnz     short 002410DE  
  182. 002410B6  |.  84D2          |test    dl, dl  
  183. 002410B8  |.  74 12         |je      short 002410CC  
  184. 002410BA  |.  8A50 01       |mov     dl, byte ptr [eax+1]  
  185. 002410BD  |.  3A51 01       |cmp     dl, byte ptr [ecx+1]  
  186. 002410C0  |.  75 1C         |jnz     short 002410DE  
  187. 002410C2  |.  83C0 02       |add     eax, 2  
  188. 002410C5  |.  83C1 02       |add     ecx, 2  
  189. 002410C8  |.  84D2          |test    dl, dl  
  190. 002410CA  |.^ 75 E4         \jnz     short 002410B0  
  191. 002410CC  |>  33C0          xor     eax, eax                         ;  看着这么多指令,其实就是返回找到的那个元素的地址  
  192. 002410CE  |.  F7D8          neg     eax  
  193. 002410D0  |.  1BC0          sbb     eax, eax  
  194. 002410D2  |.  F7D0          not     eax  
  195. 002410D4  |.  23C6          and     eax, esi  
  196. 002410D6  |.  5E            pop     esi  
  197. 002410D7  |.  5B            pop     ebx  
  198. 002410D8  |.  C3            retn  
  199. 002410D9  |>  5E            pop     esi  
  200. 002410DA  |.  33C0          xor     eax, eax  
  201. 002410DC  |.  5B            pop     ebx  
  202. 002410DD  |.  C3            retn  
  203. 002410DE  |>  1BC0          sbb     eax, eax                         ;  返回0  
  204. 002410E0  |.  83D8 FF       sbb     eax, -1  
  205. 002410E3  |.  F7D8          neg     eax  
  206. 002410E5  |.  1BC0          sbb     eax, eax                         ;  这里算出eax==FFFFFFFF  
  207. 002410E7  |.  F7D0          not     eax  
  208. 002410E9  |.  23C6          and     eax, esi  
  209. 002410EB  |.  5E            pop     esi  
  210. 002410EC  |.  5B            pop     ebx  
  211. 002410ED  \.  C3            retn  


总结:
发现编译器还是满厉害的,2个小函数直接被优化掉放入调用函数的代码里了,这还只是无优化版本,库也估计也有很多是反汇编实现而且是内联的
有一点比较麻烦的就是C函数的调用约定导致堆栈平衡有点混乱,说不定就突然冒出个add esp,xx不明所以,还导致变量的使用由于堆栈原因比较难看,尤其是寄存器还跨函数使用。。。还得到前面找这个寄存器存的是什么数据,还好windows调用约定是函数自己平衡堆栈,规律性来说应该是要强些的

后来试了下优化选项为o2,结果发现和无优化选项的代码一模一样,表示有点失望。。
PS:学着别人自己做的逆向笔记。。。质量不怎么样,发现自己真不会写笔记,光看自己的解说就。。。不过还是都传上来好了



----------------------------------------------------------------------

逆向之选择排序 

这次是直接在维基复制来的代码,就单分析排序的函数

[cpp] view plaincopyprint?
  1. // selection sort function module in C   
  2. void selectionSort(int data[], int count)  
  3. {  
  4.         int i, j, min, temp;  
  5.         for (i = 0; i < count - 1; i++) {  
  6.                 /* find the minimum */  
  7.                 min = i;  
  8.                 for (j = i+1; j < count; j++)  
  9.                     if (data[j] < data[min])  
  10.                         min = j;  
  11.                 /* swap data[i] and data[min] */  
  12.                 if(min != i) {  
  13.                     temp = data[i];  
  14.                     data[i] = data[min];  
  15.                     data[min] = temp;  
  16.                 }  
  17.         }  
  18. }  
  19.   
  20. 下面是本函数的汇编版本,无优化哦~~个人感觉这里的循环比较难还原...也不知道是因为受源码是2个for的影响还是......  
  21. 总之如果用IDA反编译下的话就会变成判断比较复杂的do while + for的双循环......还是得多加练习啊  
  22. 011E1000 >/$  83EC 08       sub     esp, 8                           ;  之前esp+8是要排序数据,而edx=esp+8  
  23. 011E1003  |.  53            push    ebx  
  24. 011E1004  |.  55            push    ebp  
  25. 011E1005  |.  56            push    esi  
  26. 011E1006  |.  57            push    edi  
  27. 011E1007  |.  33DB          xor     ebx, ebx  
  28. 011E1009  |.  8DA424 000000>lea     esp, dword ptr [esp]  
  29. 011E1010  |>  8D43 01       /lea     eax, dword ptr [ebx+1]          ;  eax从1开始增长  
  30. 011E1013  |.  83F8 06       |cmp     eax, 6  
  31. 011E1016  |.  8BFB          |mov     edi, ebx  
  32. 011E1018  |.  894424 10     |mov     dword ptr [esp+10], eax         ;  esp+10就是分配的临时变量空间  
  33. 011E101C  |.  7D 43         |jge     short 011E1061  
  34. 011E101E  |.  8D349D 000000>|lea     esi, dword ptr [ebx*4]  
  35. 011E1025  |.  897424 14     |mov     dword ptr [esp+14], esi         ;  记住了,esp+14存的是要排序数组的偏移  
  36. 011E1029  |.  8DA424 000000>|lea     esp, dword ptr [esp]  
  37. 011E1030  |>  8D0C85 000000>|/lea     ecx, dword ptr [eax*4]         ;  根据各个跳转和前面那些准备工作的情况,猜测这里应该是进入了循环内部  
  38. 011E1037  |.  8B2C11        ||mov     ebp, dword ptr [ecx+edx]  
  39. 011E103A  |.  3B2C16        ||cmp     ebp, dword ptr [esi+edx]       ;  当前数据和后一个数据比较,小于的话继续比较下一个  
  40. 011E103D  |.  7D 04         ||jge     short 011E1043  
  41. 011E103F  |.  8BF8          ||mov     edi, eax                       ;  找到的数的下标  
  42. 011E1041  |.  8BF1          ||mov     esi, ecx                       ;  找到的数的偏移  
  43. 011E1043  |>  40            ||inc     eax  
  44. 011E1044  |.  83F8 06       ||cmp     eax, 6  
  45. 011E1047  |.^ 7C E7         |\jl      short 011E1030  
  46. 011E1049  |.  3BFB          |cmp     edi, ebx  
  47. 011E104B  |.  74 10         |je      short 011E105D                  ;  找到的数等于当前数  
  48. 011E104D  |.  8B4424 14     |mov     eax, dword ptr [esp+14]         ;  当前偏移存储到eax  
  49. 011E1051  |.  8B34BA        |mov     esi, dword ptr [edx+edi*4]      ;  找到的数存到esi  
  50. 011E1054  |.  8B0C10        |mov     ecx, dword ptr [eax+edx]        ;  下面3指令将2数交换位置  
  51. 011E1057  |.  893410        |mov     dword ptr [eax+edx], esi  
  52. 011E105A  |.  890CBA        |mov     dword ptr [edx+edi*4], ecx  
  53. 011E105D  |>  8B4424 10     |mov     eax, dword ptr [esp+10]  
  54. 011E1061  |>  8BD8          |mov     ebx, eax  
  55. 011E1063  |.  83FB 05       |cmp     ebx, 5  
  56. 011E1066  |.^ 7C A8         \jl      short 011E1010  
  57. 011E1068  |.  5F            pop     edi  
  58. 011E1069  |.  5E            pop     esi  
  59. 011E106A  |.  5D            pop     ebp  
  60. 011E106B  |.  5B            pop     ebx  
  61. 011E106C  |.  83C4 08       add     esp, 8  
  62. 011E106F  \.  C3            retn  

----------------------------------------------------------------------------

逆向之快速排序 

下面是这次逆向分析的C源代码,优化选项是O2,不过严重怀疑O2和无优化是不是没区别对于这种小程序来说。。。

[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <time.h>   
  4. #define MAX 100   
  5. #define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))  
  6.   
  7. void QuickSort(int p[],int start,int end)  
  8. {  
  9.     int i,key,temp,j;  
  10.     if(start<end)  
  11.     {  
  12.         i=start;  
  13.         j=end+1;//bigest index +1 because --j  
  14.         key=p[start];//key element is the first   
  15.         for(;;)  
  16.         {  
  17.             while(i<j&&p[--j]>key) {}//find  element that less than the piovt of the   
  18.             while(i<j&&p[++i]<key) {}//find  element that greater than the piovt of the   
  19.             //above Circulation order should strictly Abide by  
  20.             if(i<j)  
  21.                 SWAP(p[i],p[j],temp);//swap  
  22.             else  
  23.                 break;  
  24.         }  
  25.         SWAP(p[i],p[start],temp);//swap piovt and i(this moment i==j)  
  26.         QuickSort(p,start,i-1);  
  27.         QuickSort(p,i+1,end);  
  28.     }  
  29. }  
  30.    
  31. int main()  
  32. {  
  33.     int i;  
  34.     int a[10];//={5,8,15,2,13,7,0,1,25,9};  
  35.     srand((unsigned)(time(0)));  
  36.     for(i=0;i<10;i++)  
  37.         a[i]=rand()%10;  
  38.     QuickSort(a,0,9);  
  39.     for(i=0;i<10;i++)  
  40.         printf("%3d",a[i]);  
  41.     system("pause");  
  42.     return 0;  
  43. }  
  44.   
  45.   
  46. 这里主函数就贴了,直接贴排序函数,这个函数也不知道怎么讲。。个人感觉比较难  
  47. 而且源码的第2个递归调用直接优化掉了,如果要反出源码应该会比较难  
  48. 00251000 >/$  8B4424 0C     mov     eax, dword ptr [esp+C]           ;  eax存储第3个参数  
  49. 00251004  |.  53            push    ebx  
  50. 00251005  |.  8B5C24 0C     mov     ebx, dword ptr [esp+C]           ;  ebx存储第2个参数  
  51. 00251009  |.  3BD8          cmp     ebx, eax  
  52. 0025100B  |.  7D 67         jge     short 00251074  
  53. 0025100D  |.  55            push    ebp  
  54. 0025100E  |.  56            push    esi  
  55. 0025100F  |.  57            push    edi  
  56. 00251010  |.  8B7C24 14     mov     edi, dword ptr [esp+14]          ;  edi存储要排序数据地址  
  57. 00251014  |>  8B0C9F        /mov     ecx, dword ptr [edi+ebx*4]      ;  在下面整个循环里,esi是自增下标i,eax是自减下标j  
  58. 00251017  |.  8BF3          |mov     esi, ebx  
  59. 00251019  |.  40            |inc     eax  
  60. 0025101A  |.  8D9B 00000000 |lea     ebx, dword ptr [ebx]  
  61. 00251020  |>  3BF0          |/cmp     esi, eax                       ;  下面这2个小循环是一个类型,仔细看下就行,在不远处有个jmp其实就是个大循环  
  62. 00251022  |.  7D 28         ||jge     short 0025104C  
  63. 00251024  |.  48            ||dec     eax  
  64. 00251025  |.  390C87        ||cmp     dword ptr [edi+eax*4], ecx  
  65. 00251028  |.^ 7F F6         ||jg      short 00251020  
  66. 0025102A  |.  8D9B 00000000 ||lea     ebx, dword ptr [ebx]  
  67. 00251030  |>  3BF0          ||/cmp     esi, eax  
  68. 00251032  |.  7D 18         |||jge     short 0025104C  
  69. 00251034  |.  46            |||inc     esi  
  70. 00251035  |.  390CB7        |||cmp     dword ptr [edi+esi*4], ecx  
  71. 00251038  |.^ 7C F6         ||\jl      short 00251030  
  72. 0025103A  |.  3BF0          ||cmp     esi, eax  
  73. 0025103C  |.  7D 0E         ||jge     short 0025104C  
  74. 0025103E  |.  8B2C87        ||mov     ebp, dword ptr [edi+eax*4]     ;  SWAP(a[b],a[c])  
  75. 00251041  |.  8B14B7        ||mov     edx, dword ptr [edi+esi*4]  
  76. 00251044  |.  892CB7        ||mov     dword ptr [edi+esi*4], ebp  
  77. 00251047  |.  891487        ||mov     dword ptr [edi+eax*4], edx  
  78. 0025104A  |.^ EB D4         |\jmp     short 00251020  
  79. 0025104C  |>  8B0C9F        |mov     ecx, dword ptr [edi+ebx*4]      ;  SWAP(a[b],a[c])  
  80. 0025104F  |.  8B04B7        |mov     eax, dword ptr [edi+esi*4]  
  81. 00251052  |.  8D56 FF       |lea     edx, dword ptr [esi-1]  
  82. 00251055  |.  52            |push    edx  
  83. 00251056  |.  53            |push    ebx  
  84. 00251057  |.  890CB7        |mov     dword ptr [edi+esi*4], ecx  
  85. 0025105A  |.  57            |push    edi  
  86. 0025105B  |.  89049F        |mov     dword ptr [edi+ebx*4], eax  
  87. 0025105E  |.  E8 9DFFFFFF   |call    QuickSort  
  88. 00251063  |.  8B4424 28     |mov     eax, dword ptr [esp+28]         ;  eax=第3个参数  
  89. 00251067  |.  8D5E 01       |lea     ebx, dword ptr [esi+1]          ;  ebx=i+1  
  90. 0025106A  |.  83C4 0C       |add     esp, 0C  
  91. 0025106D  |.  3BD8          |cmp     ebx, eax  
  92. 0025106F  |.^ 7C A3         \jl      short 00251014  
  93. 00251071  |.  5F            pop     edi  
  94. 00251072  |.  5E            pop     esi  
  95. 00251073  |.  5D            pop     ebp  
  96. 00251074  |>  5B            pop     ebx  
  97. 00251075  \.  C3            retn  


自己看着都。。。。不是写文章的料啊诶。。



原创粉丝点击